import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil, map, shareReplay } from 'rxjs/operators';
import * as i0 from "@angular/core";
import * as i1 from "../services/testing-instrumentation.service";
import * as i2 from "@angular/common";
import * as i3 from "@memberjunction/ng-ui-components";
const _forTrack0 = ($index, $item) => $item.days;
const _forTrack1 = ($index, $item) => $item.testName;
const _forTrack2 = ($index, $item) => $item.label;
const _forTrack3 = ($index, $item) => $item.version;
function TestingAnalyticsComponent_Conditional_0_ng_container_0_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementContainer(0);
} }
function TestingAnalyticsComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵtemplate(0, TestingAnalyticsComponent_Conditional_0_ng_container_0_Template, 1, 0, "ng-container", 1);
} if (rf & 2) {
    i0.ɵɵnextContext();
    const content_r1 = i0.ɵɵreference(3);
    i0.ɵɵproperty("ngTemplateOutlet", content_r1);
} }
function TestingAnalyticsComponent_Conditional_1_For_4_Template(rf, ctx) { if (rf & 1) {
    const _r3 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "mj-filter-chip", 6);
    i0.ɵɵlistener("Clicked", function TestingAnalyticsComponent_Conditional_1_For_4_Template_mj_filter_chip_Clicked_0_listener() { const range_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r4 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r4.OnTimeRangeSelect(range_r4.days)); });
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const range_r4 = ctx.$implicit;
    const ctx_r4 = i0.ɵɵnextContext(2);
    i0.ɵɵproperty("Label", range_r4.label)("Active", ctx_r4.SelectedDays === range_r4.days);
} }
function TestingAnalyticsComponent_Conditional_1_ng_container_7_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementContainer(0);
} }
function TestingAnalyticsComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
    const _r2 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "mj-page-layout")(1, "mj-page-header", 2)(2, "div", 3);
    i0.ɵɵrepeaterCreate(3, TestingAnalyticsComponent_Conditional_1_For_4_Template, 1, 2, "mj-filter-chip", 4, _forTrack0);
    i0.ɵɵelementStart(5, "mj-refresh-button", 5);
    i0.ɵɵlistener("Clicked", function TestingAnalyticsComponent_Conditional_1_Template_mj_refresh_button_Clicked_5_listener() { i0.ɵɵrestoreView(_r2); const ctx_r4 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r4.Refresh()); });
    i0.ɵɵelementEnd()()();
    i0.ɵɵelementStart(6, "mj-page-body");
    i0.ɵɵtemplate(7, TestingAnalyticsComponent_Conditional_1_ng_container_7_Template, 1, 0, "ng-container", 1);
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const ctx_r4 = i0.ɵɵnextContext();
    const content_r1 = i0.ɵɵreference(3);
    i0.ɵɵadvance(3);
    i0.ɵɵrepeater(ctx_r4.TimeRanges);
    i0.ɵɵadvance(4);
    i0.ɵɵproperty("ngTemplateOutlet", content_r1);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_9_Conditional_0_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "mj-empty-state", 30);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_9_Conditional_1_For_2_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 32)(1, "span", 34);
    i0.ɵɵtext(2);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(3, "div", 35);
    i0.ɵɵelement(4, "div", 36);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(5, "span", 37);
    i0.ɵɵtext(6);
    i0.ɵɵpipe(7, "number");
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const t_r6 = ctx.$implicit;
    const ctx_r4 = i0.ɵɵnextContext(4);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(ctx_r4.FormatBucketDate(t_r6.timestamp));
    i0.ɵɵadvance(2);
    i0.ɵɵstyleProp("width", ctx_r4.PassRate(t_r6), "%");
    i0.ɵɵadvance();
    i0.ɵɵclassMap(ctx_r4.PassRateClass(t_r6));
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate1("", i0.ɵɵpipeBind2(7, 6, ctx_r4.PassRate(t_r6), "1.0-0"), "%");
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_9_Conditional_1_Conditional_4_Conditional_0_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "i", 38);
    i0.ɵɵelementStart(1, "span", 39);
    i0.ɵɵtext(2, "Improving");
    i0.ɵɵelementEnd();
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_9_Conditional_1_Conditional_4_Conditional_1_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "i", 40);
    i0.ɵɵelementStart(1, "span", 41);
    i0.ɵɵtext(2, "Declining");
    i0.ɵɵelementEnd();
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_9_Conditional_1_Conditional_4_Conditional_2_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "i", 42);
    i0.ɵɵelementStart(1, "span", 43);
    i0.ɵɵtext(2, "Stable");
    i0.ɵɵelementEnd();
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_9_Conditional_1_Conditional_4_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵconditionalCreate(0, TestingAnalyticsComponent_ng_template_2_Conditional_9_Conditional_1_Conditional_4_Conditional_0_Template, 3, 0)(1, TestingAnalyticsComponent_ng_template_2_Conditional_9_Conditional_1_Conditional_4_Conditional_1_Template, 3, 0)(2, TestingAnalyticsComponent_ng_template_2_Conditional_9_Conditional_1_Conditional_4_Conditional_2_Template, 3, 0);
} if (rf & 2) {
    const dir_r7 = ctx;
    i0.ɵɵconditional(dir_r7 === "up" ? 0 : dir_r7 === "down" ? 1 : 2);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_9_Conditional_1_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 31);
    i0.ɵɵrepeaterCreate(1, TestingAnalyticsComponent_ng_template_2_Conditional_9_Conditional_1_For_2_Template, 8, 9, "div", 32, i0.ɵɵcomponentInstance().trackTrend, true);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(3, "div", 33);
    i0.ɵɵconditionalCreate(4, TestingAnalyticsComponent_ng_template_2_Conditional_9_Conditional_1_Conditional_4_Template, 3, 1);
    i0.ɵɵpipe(5, "async");
    i0.ɵɵelementEnd();
} if (rf & 2) {
    let tmp_6_0;
    const trends_r8 = i0.ɵɵnextContext();
    const ctx_r4 = i0.ɵɵnextContext(2);
    i0.ɵɵadvance();
    i0.ɵɵrepeater(trends_r8);
    i0.ɵɵadvance(3);
    i0.ɵɵconditional((tmp_6_0 = i0.ɵɵpipeBind1(5, 1, ctx_r4.PassRateTrendDirection$)) ? 4 : -1, tmp_6_0);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_9_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵconditionalCreate(0, TestingAnalyticsComponent_ng_template_2_Conditional_9_Conditional_0_Template, 1, 0, "mj-empty-state", 30)(1, TestingAnalyticsComponent_ng_template_2_Conditional_9_Conditional_1_Template, 6, 3);
} if (rf & 2) {
    i0.ɵɵconditional(ctx.length === 0 ? 0 : 1);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_15_Conditional_0_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "mj-empty-state", 44);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_15_Conditional_1_For_2_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 32)(1, "span", 34);
    i0.ɵɵtext(2);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(3, "div", 49);
    i0.ɵɵelement(4, "div", 50)(5, "div", 51)(6, "div", 52);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(7, "span", 37);
    i0.ɵɵtext(8);
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const t_r9 = ctx.$implicit;
    const ctx_r4 = i0.ɵɵnextContext(4);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(ctx_r4.FormatBucketDate(t_r9.timestamp));
    i0.ɵɵadvance(2);
    i0.ɵɵstyleProp("width", ctx_r4.SegmentPct(t_r9, "passed"), "%");
    i0.ɵɵadvance();
    i0.ɵɵstyleProp("width", ctx_r4.SegmentPct(t_r9, "failed"), "%");
    i0.ɵɵadvance();
    i0.ɵɵstyleProp("width", ctx_r4.SegmentPct(t_r9, "skipped"), "%");
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(t_r9.totalRuns);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_15_Conditional_1_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 31);
    i0.ɵɵrepeaterCreate(1, TestingAnalyticsComponent_ng_template_2_Conditional_15_Conditional_1_For_2_Template, 9, 8, "div", 32, i0.ɵɵcomponentInstance().trackTrend, true);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(3, "div", 45);
    i0.ɵɵelement(4, "span", 46);
    i0.ɵɵtext(5, " Passed ");
    i0.ɵɵelement(6, "span", 47);
    i0.ɵɵtext(7, " Failed ");
    i0.ɵɵelement(8, "span", 48);
    i0.ɵɵtext(9, " Skipped ");
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const trends_r10 = i0.ɵɵnextContext();
    i0.ɵɵadvance();
    i0.ɵɵrepeater(trends_r10);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_15_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵconditionalCreate(0, TestingAnalyticsComponent_ng_template_2_Conditional_15_Conditional_0_Template, 1, 0, "mj-empty-state", 44)(1, TestingAnalyticsComponent_ng_template_2_Conditional_15_Conditional_1_Template, 10, 0);
} if (rf & 2) {
    i0.ɵɵconditional(ctx.length === 0 ? 0 : 1);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_21_Conditional_0_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "mj-empty-state", 53);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_21_Conditional_1_For_2_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 32)(1, "span", 34);
    i0.ɵɵtext(2);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(3, "div", 35);
    i0.ɵɵelement(4, "div", 54);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(5, "span", 37);
    i0.ɵɵtext(6);
    i0.ɵɵpipe(7, "number");
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const t_r11 = ctx.$implicit;
    const ctx_r4 = i0.ɵɵnextContext(4);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(ctx_r4.FormatBucketDate(t_r11.timestamp));
    i0.ɵɵadvance(2);
    i0.ɵɵclassMap(ctx_r4.ScoreBarClass(t_r11.averageScore));
    i0.ɵɵstyleProp("width", t_r11.averageScore * 100, "%");
    i0.ɵɵadvance();
    i0.ɵɵclassMap(ctx_r4.ScoreTextClass(t_r11.averageScore));
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate1("", i0.ɵɵpipeBind2(7, 8, t_r11.averageScore * 100, "1.0-0"), "%");
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_21_Conditional_1_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 31);
    i0.ɵɵrepeaterCreate(1, TestingAnalyticsComponent_ng_template_2_Conditional_21_Conditional_1_For_2_Template, 8, 11, "div", 32, i0.ɵɵcomponentInstance().trackTrend, true);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const trends_r12 = i0.ɵɵnextContext();
    i0.ɵɵadvance();
    i0.ɵɵrepeater(trends_r12);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_21_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵconditionalCreate(0, TestingAnalyticsComponent_ng_template_2_Conditional_21_Conditional_0_Template, 1, 0, "mj-empty-state", 53)(1, TestingAnalyticsComponent_ng_template_2_Conditional_21_Conditional_1_Template, 3, 0, "div", 31);
} if (rf & 2) {
    i0.ɵɵconditional(ctx.length === 0 ? 0 : 1);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_27_Conditional_0_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "mj-empty-state", 55);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_27_Conditional_1_For_2_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 32)(1, "span", 34);
    i0.ɵɵtext(2);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(3, "div", 35);
    i0.ɵɵelement(4, "div", 56);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(5, "span", 37);
    i0.ɵɵtext(6);
    i0.ɵɵpipe(7, "number");
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const t_r13 = ctx.$implicit;
    const trends_r14 = i0.ɵɵnextContext(2);
    const ctx_r4 = i0.ɵɵnextContext(2);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(ctx_r4.FormatBucketDate(t_r13.timestamp));
    i0.ɵɵadvance(2);
    i0.ɵɵstyleProp("width", ctx_r4.CostBarPct(t_r13, trends_r14), "%");
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate1("$", i0.ɵɵpipeBind2(7, 4, t_r13.totalCost, "1.2-2"));
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_27_Conditional_1_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 31);
    i0.ɵɵrepeaterCreate(1, TestingAnalyticsComponent_ng_template_2_Conditional_27_Conditional_1_For_2_Template, 8, 7, "div", 32, i0.ɵɵcomponentInstance().trackTrend, true);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const trends_r14 = i0.ɵɵnextContext();
    i0.ɵɵadvance();
    i0.ɵɵrepeater(trends_r14);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_27_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵconditionalCreate(0, TestingAnalyticsComponent_ng_template_2_Conditional_27_Conditional_0_Template, 1, 0, "mj-empty-state", 55)(1, TestingAnalyticsComponent_ng_template_2_Conditional_27_Conditional_1_Template, 3, 0, "div", 31);
} if (rf & 2) {
    i0.ɵɵconditional(ctx.length === 0 ? 0 : 1);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_37_Conditional_0_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "mj-empty-state", 57);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_37_Conditional_1_For_2_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 59)(1, "span", 60);
    i0.ɵɵtext(2);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(3, "span", 61);
    i0.ɵɵtext(4);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(5, "span", 62);
    i0.ɵɵtext(6);
    i0.ɵɵpipe(7, "number");
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const t_r15 = ctx.$implicit;
    i0.ɵɵadvance();
    i0.ɵɵproperty("title", t_r15.testName);
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate(t_r15.testName);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(t_r15.failureCount);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate1("", i0.ɵɵpipeBind2(7, 4, t_r15.failureRate, "1.0-1"), "%");
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_37_Conditional_1_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 58);
    i0.ɵɵrepeaterCreate(1, TestingAnalyticsComponent_ng_template_2_Conditional_37_Conditional_1_For_2_Template, 8, 7, "div", 59, _forTrack1);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const tests_r16 = i0.ɵɵnextContext();
    i0.ɵɵadvance();
    i0.ɵɵrepeater(tests_r16);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_37_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵconditionalCreate(0, TestingAnalyticsComponent_ng_template_2_Conditional_37_Conditional_0_Template, 1, 0, "mj-empty-state", 57)(1, TestingAnalyticsComponent_ng_template_2_Conditional_37_Conditional_1_Template, 3, 0, "div", 58);
} if (rf & 2) {
    i0.ɵɵconditional(ctx.length === 0 ? 0 : 1);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_43_Conditional_0_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "mj-empty-state", 63);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_43_Conditional_1_For_2_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 59)(1, "span", 60);
    i0.ɵɵtext(2);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(3, "span", 64);
    i0.ɵɵtext(4);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(5, "span", 62);
    i0.ɵɵtext(6);
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const t_r17 = ctx.$implicit;
    const ctx_r4 = i0.ɵɵnextContext(4);
    i0.ɵɵadvance();
    i0.ɵɵproperty("title", t_r17.testName);
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate(t_r17.testName);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(ctx_r4.FormatDuration(t_r17.avgDuration));
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate1("max ", ctx_r4.FormatDuration(t_r17.maxDuration));
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_43_Conditional_1_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 58);
    i0.ɵɵrepeaterCreate(1, TestingAnalyticsComponent_ng_template_2_Conditional_43_Conditional_1_For_2_Template, 7, 4, "div", 59, _forTrack1);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const tests_r18 = i0.ɵɵnextContext();
    i0.ɵɵadvance();
    i0.ɵɵrepeater(tests_r18);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_43_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵconditionalCreate(0, TestingAnalyticsComponent_ng_template_2_Conditional_43_Conditional_0_Template, 1, 0, "mj-empty-state", 63)(1, TestingAnalyticsComponent_ng_template_2_Conditional_43_Conditional_1_Template, 3, 0, "div", 58);
} if (rf & 2) {
    i0.ɵɵconditional(ctx.length === 0 ? 0 : 1);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_49_Conditional_0_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "mj-empty-state", 65);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_49_Conditional_1_For_2_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 59)(1, "span", 60);
    i0.ɵɵtext(2);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(3, "span", 64);
    i0.ɵɵtext(4);
    i0.ɵɵpipe(5, "number");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(6, "span", 62);
    i0.ɵɵtext(7);
    i0.ɵɵpipe(8, "number");
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const t_r19 = ctx.$implicit;
    i0.ɵɵadvance();
    i0.ɵɵproperty("title", t_r19.testName);
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate(t_r19.testName);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate1("$", i0.ɵɵpipeBind2(5, 4, t_r19.totalCost, "1.2-2"));
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate1("$", i0.ɵɵpipeBind2(8, 7, t_r19.avgCost, "1.4-4"), "/run");
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_49_Conditional_1_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 58);
    i0.ɵɵrepeaterCreate(1, TestingAnalyticsComponent_ng_template_2_Conditional_49_Conditional_1_For_2_Template, 9, 10, "div", 59, _forTrack1);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const tests_r20 = i0.ɵɵnextContext();
    i0.ɵɵadvance();
    i0.ɵɵrepeater(tests_r20);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_49_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵconditionalCreate(0, TestingAnalyticsComponent_ng_template_2_Conditional_49_Conditional_0_Template, 1, 0, "mj-empty-state", 65)(1, TestingAnalyticsComponent_ng_template_2_Conditional_49_Conditional_1_Template, 3, 0, "div", 58);
} if (rf & 2) {
    i0.ɵɵconditional(ctx.length === 0 ? 0 : 1);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_55_Conditional_0_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "mj-empty-state", 66);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_55_Conditional_1_For_2_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 68)(1, "span", 69);
    i0.ɵɵtext(2);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(3, "div", 70);
    i0.ɵɵelement(4, "div", 71);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(5, "span", 72);
    i0.ɵɵtext(6);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(7, "span", 73);
    i0.ɵɵtext(8);
    i0.ɵɵpipe(9, "number");
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const b_r21 = ctx.$implicit;
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(b_r21.label);
    i0.ɵɵadvance(2);
    i0.ɵɵstyleProp("width", b_r21.percentage, "%")("background", b_r21.color);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(b_r21.count);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate1("", i0.ɵɵpipeBind2(9, 7, b_r21.percentage, "1.0-1"), "%");
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_55_Conditional_1_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 67);
    i0.ɵɵrepeaterCreate(1, TestingAnalyticsComponent_ng_template_2_Conditional_55_Conditional_1_For_2_Template, 10, 10, "div", 68, _forTrack2);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const buckets_r22 = i0.ɵɵnextContext();
    i0.ɵɵadvance();
    i0.ɵɵrepeater(buckets_r22);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_55_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵconditionalCreate(0, TestingAnalyticsComponent_ng_template_2_Conditional_55_Conditional_0_Template, 1, 0, "mj-empty-state", 66)(1, TestingAnalyticsComponent_ng_template_2_Conditional_55_Conditional_1_Template, 3, 0, "div", 67);
} if (rf & 2) {
    i0.ɵɵconditional(ctx.length === 0 ? 0 : 1);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_63_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 27);
    i0.ɵɵelement(1, "i", 74);
    i0.ɵɵelementStart(2, "span");
    i0.ɵɵtext(3, "Loading versions...");
    i0.ɵɵelementEnd()();
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_64_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "mj-empty-state", 28);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_65_For_16_Conditional_15_Conditional_1_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "i", 81);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_65_For_16_Conditional_15_Conditional_2_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "i", 82);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_65_For_16_Conditional_15_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "span", 80);
    i0.ɵɵconditionalCreate(1, TestingAnalyticsComponent_ng_template_2_Conditional_65_For_16_Conditional_15_Conditional_1_Template, 1, 0, "i", 81)(2, TestingAnalyticsComponent_ng_template_2_Conditional_65_For_16_Conditional_15_Conditional_2_Template, 1, 0, "i", 82);
    i0.ɵɵtext(3);
    i0.ɵɵpipe(4, "number");
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const row_r23 = i0.ɵɵnextContext().$implicit;
    const ctx_r4 = i0.ɵɵnextContext(3);
    i0.ɵɵclassProp("delta-up", row_r23.passRateDelta > 0)("delta-down", row_r23.passRateDelta < 0)("delta-neutral", row_r23.passRateDelta === 0);
    i0.ɵɵadvance();
    i0.ɵɵconditional(row_r23.passRateDelta > 0 ? 1 : row_r23.passRateDelta < 0 ? 2 : -1);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind2(4, 8, ctx_r4.AbsNum(row_r23.passRateDelta), "1.1-1"), "% ");
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_65_For_16_Conditional_20_Conditional_1_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "i", 81);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_65_For_16_Conditional_20_Conditional_2_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "i", 82);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_65_For_16_Conditional_20_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "span", 80);
    i0.ɵɵconditionalCreate(1, TestingAnalyticsComponent_ng_template_2_Conditional_65_For_16_Conditional_20_Conditional_1_Template, 1, 0, "i", 81)(2, TestingAnalyticsComponent_ng_template_2_Conditional_65_For_16_Conditional_20_Conditional_2_Template, 1, 0, "i", 82);
    i0.ɵɵtext(3);
    i0.ɵɵpipe(4, "number");
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const row_r23 = i0.ɵɵnextContext().$implicit;
    const ctx_r4 = i0.ɵɵnextContext(3);
    i0.ɵɵclassProp("delta-up", row_r23.costDelta < 0)("delta-down", row_r23.costDelta > 0)("delta-neutral", row_r23.costDelta === 0);
    i0.ɵɵadvance();
    i0.ɵɵconditional(row_r23.costDelta > 0 ? 1 : row_r23.costDelta < 0 ? 2 : -1);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind2(4, 8, ctx_r4.AbsNum(row_r23.costDelta), "1.1-1"), "% ");
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_65_For_16_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "tr")(1, "td")(2, "span", 77);
    i0.ɵɵtext(3);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(4, "span", 78);
    i0.ɵɵtext(5);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(6, "td");
    i0.ɵɵtext(7);
    i0.ɵɵpipe(8, "date");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(9, "td", 76);
    i0.ɵɵtext(10);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(11, "td", 76)(12, "span");
    i0.ɵɵtext(13);
    i0.ɵɵpipe(14, "number");
    i0.ɵɵelementEnd();
    i0.ɵɵconditionalCreate(15, TestingAnalyticsComponent_ng_template_2_Conditional_65_For_16_Conditional_15_Template, 5, 11, "span", 79);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(16, "td", 76)(17, "span");
    i0.ɵɵtext(18);
    i0.ɵɵpipe(19, "number");
    i0.ɵɵelementEnd();
    i0.ɵɵconditionalCreate(20, TestingAnalyticsComponent_ng_template_2_Conditional_65_For_16_Conditional_20_Template, 5, 11, "span", 79);
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const row_r23 = ctx.$implicit;
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate(row_r23.gitCommitShort);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(row_r23.agentVersion);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(8, 8, row_r23.date, "mediumDate"));
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate(row_r23.totalTests);
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate1("", i0.ɵɵpipeBind2(14, 11, row_r23.passRate, "1.1-1"), "%");
    i0.ɵɵadvance(2);
    i0.ɵɵconditional(row_r23.passRateDelta !== null ? 15 : -1);
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate1("$", i0.ɵɵpipeBind2(19, 14, row_r23.totalCost, "1.2-2"));
    i0.ɵɵadvance(2);
    i0.ɵɵconditional(row_r23.costDelta !== null ? 20 : -1);
} }
function TestingAnalyticsComponent_ng_template_2_Conditional_65_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 29)(1, "table", 75)(2, "thead")(3, "tr")(4, "th");
    i0.ɵɵtext(5, "Version");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(6, "th");
    i0.ɵɵtext(7, "Date");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(8, "th", 76);
    i0.ɵɵtext(9, "Tests");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(10, "th", 76);
    i0.ɵɵtext(11, "Pass Rate");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(12, "th", 76);
    i0.ɵɵtext(13, "Cost");
    i0.ɵɵelementEnd()()();
    i0.ɵɵelementStart(14, "tbody");
    i0.ɵɵrepeaterCreate(15, TestingAnalyticsComponent_ng_template_2_Conditional_65_For_16_Template, 21, 17, "tr", null, _forTrack3);
    i0.ɵɵelementEnd()()();
} if (rf & 2) {
    const ctx_r4 = i0.ɵɵnextContext(2);
    i0.ɵɵadvance(15);
    i0.ɵɵrepeater(ctx_r4.VersionRows);
} }
function TestingAnalyticsComponent_ng_template_2_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 7)(1, "div", 8);
    i0.ɵɵelement(2, "i", 9);
    i0.ɵɵtext(3, " Trend Overview ");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(4, "div", 10)(5, "div", 11)(6, "h4");
    i0.ɵɵelement(7, "i", 12);
    i0.ɵɵtext(8, " Pass Rate Trend");
    i0.ɵɵelementEnd();
    i0.ɵɵconditionalCreate(9, TestingAnalyticsComponent_ng_template_2_Conditional_9_Template, 2, 1);
    i0.ɵɵpipe(10, "async");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(11, "div", 11)(12, "h4");
    i0.ɵɵelement(13, "i", 13);
    i0.ɵɵtext(14, " Run Volume");
    i0.ɵɵelementEnd();
    i0.ɵɵconditionalCreate(15, TestingAnalyticsComponent_ng_template_2_Conditional_15_Template, 2, 1);
    i0.ɵɵpipe(16, "async");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(17, "div", 11)(18, "h4");
    i0.ɵɵelement(19, "i", 14);
    i0.ɵɵtext(20, " Score Trend");
    i0.ɵɵelementEnd();
    i0.ɵɵconditionalCreate(21, TestingAnalyticsComponent_ng_template_2_Conditional_21_Template, 2, 1);
    i0.ɵɵpipe(22, "async");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(23, "div", 11)(24, "h4");
    i0.ɵɵelement(25, "i", 15);
    i0.ɵɵtext(26, " Cost Trend");
    i0.ɵɵelementEnd();
    i0.ɵɵconditionalCreate(27, TestingAnalyticsComponent_ng_template_2_Conditional_27_Template, 2, 1);
    i0.ɵɵpipe(28, "async");
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(29, "div", 8);
    i0.ɵɵelement(30, "i", 16);
    i0.ɵɵtext(31, " Insights ");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(32, "div", 17)(33, "div", 18)(34, "h4");
    i0.ɵɵelement(35, "i", 19);
    i0.ɵɵtext(36, " Top Failing Tests");
    i0.ɵɵelementEnd();
    i0.ɵɵconditionalCreate(37, TestingAnalyticsComponent_ng_template_2_Conditional_37_Template, 2, 1);
    i0.ɵɵpipe(38, "async");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(39, "div", 18)(40, "h4");
    i0.ɵɵelement(41, "i", 20);
    i0.ɵɵtext(42, " Slowest Tests");
    i0.ɵɵelementEnd();
    i0.ɵɵconditionalCreate(43, TestingAnalyticsComponent_ng_template_2_Conditional_43_Template, 2, 1);
    i0.ɵɵpipe(44, "async");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(45, "div", 18)(46, "h4");
    i0.ɵɵelement(47, "i", 21);
    i0.ɵɵtext(48, " Most Expensive Tests");
    i0.ɵɵelementEnd();
    i0.ɵɵconditionalCreate(49, TestingAnalyticsComponent_ng_template_2_Conditional_49_Template, 2, 1);
    i0.ɵɵpipe(50, "async");
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(51, "div", 8);
    i0.ɵɵelement(52, "i", 22);
    i0.ɵɵtext(53, " Score Distribution ");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(54, "div", 23);
    i0.ɵɵconditionalCreate(55, TestingAnalyticsComponent_ng_template_2_Conditional_55_Template, 2, 1);
    i0.ɵɵpipe(56, "async");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(57, "div", 8);
    i0.ɵɵelement(58, "i", 24);
    i0.ɵɵtext(59, " Version Comparison ");
    i0.ɵɵelementStart(60, "span", 25);
    i0.ɵɵtext(61, "Compare metrics across different builds");
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(62, "div", 26);
    i0.ɵɵconditionalCreate(63, TestingAnalyticsComponent_ng_template_2_Conditional_63_Template, 4, 0, "div", 27)(64, TestingAnalyticsComponent_ng_template_2_Conditional_64_Template, 1, 0, "mj-empty-state", 28)(65, TestingAnalyticsComponent_ng_template_2_Conditional_65_Template, 17, 0, "div", 29);
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    let tmp_2_0;
    let tmp_3_0;
    let tmp_4_0;
    let tmp_5_0;
    let tmp_6_0;
    let tmp_7_0;
    let tmp_8_0;
    let tmp_9_0;
    const ctx_r4 = i0.ɵɵnextContext();
    i0.ɵɵadvance(9);
    i0.ɵɵconditional((tmp_2_0 = i0.ɵɵpipeBind1(10, 9, ctx_r4.DisplayTrends$)) ? 9 : -1, tmp_2_0);
    i0.ɵɵadvance(6);
    i0.ɵɵconditional((tmp_3_0 = i0.ɵɵpipeBind1(16, 11, ctx_r4.DisplayTrends$)) ? 15 : -1, tmp_3_0);
    i0.ɵɵadvance(6);
    i0.ɵɵconditional((tmp_4_0 = i0.ɵɵpipeBind1(22, 13, ctx_r4.DisplayTrends$)) ? 21 : -1, tmp_4_0);
    i0.ɵɵadvance(6);
    i0.ɵɵconditional((tmp_5_0 = i0.ɵɵpipeBind1(28, 15, ctx_r4.DisplayTrends$)) ? 27 : -1, tmp_5_0);
    i0.ɵɵadvance(10);
    i0.ɵɵconditional((tmp_6_0 = i0.ɵɵpipeBind1(38, 17, ctx_r4.TopFailingTests$)) ? 37 : -1, tmp_6_0);
    i0.ɵɵadvance(6);
    i0.ɵɵconditional((tmp_7_0 = i0.ɵɵpipeBind1(44, 19, ctx_r4.SlowestTests$)) ? 43 : -1, tmp_7_0);
    i0.ɵɵadvance(6);
    i0.ɵɵconditional((tmp_8_0 = i0.ɵɵpipeBind1(50, 21, ctx_r4.MostExpensiveTests$)) ? 49 : -1, tmp_8_0);
    i0.ɵɵadvance(6);
    i0.ɵɵconditional((tmp_9_0 = i0.ɵɵpipeBind1(56, 23, ctx_r4.ScoreDistribution$)) ? 55 : -1, tmp_9_0);
    i0.ɵɵadvance(8);
    i0.ɵɵconditional(ctx_r4.IsLoadingVersions ? 63 : ctx_r4.VersionRows.length === 0 ? 64 : 65);
} }
// ---------------------------------------------------------------------------
// Component
// ---------------------------------------------------------------------------
export class TestingAnalyticsComponent {
    instrumentationService;
    cdr;
    // ------- Inputs / Outputs -------
    initialState = null;
    /** When true, the inner bespoke .page-header is hidden — the parent shell owns the chrome. */
    HideToolbar = false;
    stateChange = new EventEmitter();
    // ------- Public state -------
    TimeRanges = [
        { label: '7 Days', days: 7 },
        { label: '30 Days', days: 30 },
        { label: '90 Days', days: 90 }
    ];
    SelectedDays = 30;
    VersionRows = [];
    IsLoadingVersions = false;
    // Cached breakdown name lists for the dashboard's agent context.
    topFailingNames = [];
    slowestNames = [];
    mostExpensiveNames = [];
    // ------- Observables -------
    DisplayTrends$;
    PassRateTrendDirection$;
    TopFailingTests$;
    SlowestTests$;
    MostExpensiveTests$;
    ScoreDistribution$;
    // ------- Private -------
    destroy$ = new Subject();
    maxTrendRuns = 0; // cached for cost bar scaling
    constructor(instrumentationService, cdr) {
        this.instrumentationService = instrumentationService;
        this.cdr = cdr;
    }
    // ===================================================================
    // Lifecycle
    // ===================================================================
    ngOnInit() {
        this.restoreState();
        this.setupObservables();
        this.loadVersionMetrics();
    }
    ngOnDestroy() {
        this.destroy$.next();
        this.destroy$.complete();
    }
    // ===================================================================
    // Public methods (template-bound)
    // ===================================================================
    OnTimeRangeSelect(days) {
        this.SelectedDays = days;
        const end = new Date();
        const start = new Date(end.getTime() - days * 24 * 60 * 60 * 1000);
        this.instrumentationService.setDateRange(start, end);
        this.loadVersionMetrics();
        this.emitState();
    }
    Refresh() {
        this.instrumentationService.refresh();
        this.loadVersionMetrics();
    }
    // -- Trend helpers (called from template) --
    PassRate(t) {
        return t.totalRuns === 0 ? 0 : (t.passed / t.totalRuns) * 100;
    }
    PassRateClass(t) {
        const rate = this.PassRate(t);
        if (rate >= 80)
            return 'text-pass-good';
        if (rate >= 60)
            return 'text-pass-warn';
        return 'text-pass-bad';
    }
    SegmentPct(t, segment) {
        if (t.totalRuns === 0)
            return 0;
        const value = segment === 'passed' ? t.passed : segment === 'failed' ? t.failed : t.skipped;
        return (value / t.totalRuns) * 100;
    }
    ScoreBarClass(score) {
        if (score >= 0.9)
            return 'bar-fill score-excellent';
        if (score >= 0.7)
            return 'bar-fill score-good';
        if (score >= 0.5)
            return 'bar-fill score-fair';
        return 'bar-fill score-poor';
    }
    ScoreTextClass(score) {
        if (score >= 0.9)
            return 'text-excellent';
        if (score >= 0.7)
            return 'text-good';
        if (score >= 0.5)
            return 'text-fair';
        return 'text-poor';
    }
    CostBarPct(t, all) {
        const maxCost = Math.max(...all.map(x => x.totalCost), 0.01);
        return (t.totalCost / maxCost) * 100;
    }
    FormatBucketDate(d) {
        const dt = d instanceof Date ? d : new Date(d);
        return `${dt.getMonth() + 1}/${dt.getDate()}`;
    }
    FormatDuration(ms) {
        if (ms < 1000)
            return `${Math.round(ms)}ms`;
        const s = Math.floor(ms / 1000);
        const m = Math.floor(s / 60);
        if (m > 0)
            return `${m}m ${s % 60}s`;
        return `${s}s`;
    }
    AbsNum(n) {
        return Math.abs(n);
    }
    /** trackBy for trend @for loops */
    trackTrend(index, t) {
        return index;
    }
    // ===================================================================
    // Private helpers
    // ===================================================================
    restoreState() {
        if (this.initialState != null) {
            if (typeof this.initialState['selectedDays'] === 'number') {
                this.SelectedDays = this.initialState['selectedDays'];
            }
        }
        // Apply initial date range
        const end = new Date();
        const start = new Date(end.getTime() - this.SelectedDays * 24 * 60 * 60 * 1000);
        this.instrumentationService.setDateRange(start, end);
    }
    setupObservables() {
        // Limit trends to last 10 buckets for readability
        this.DisplayTrends$ = this.instrumentationService.trends$.pipe(map(trends => trends.slice(-10)), shareReplay(1));
        this.PassRateTrendDirection$ = this.DisplayTrends$.pipe(map(trends => this.calculateTrendDirection(trends)), shareReplay(1));
        const analytics$ = this.instrumentationService.analytics$;
        this.TopFailingTests$ = analytics$.pipe(map(a => a.topFailingTests.slice(0, 5)), shareReplay(1));
        this.SlowestTests$ = analytics$.pipe(map(a => a.slowestTests.slice(0, 5)), shareReplay(1));
        this.MostExpensiveTests$ = analytics$.pipe(map(a => a.mostExpensiveTests.slice(0, 5)), shareReplay(1));
        // Cache the breakdown name lists so the dashboard's agent context can publish
        // them (top failing / slowest / most expensive tests).
        analytics$.pipe(takeUntil(this.destroy$)).subscribe(a => {
            this.topFailingNames = a.topFailingTests.slice(0, 5).map(t => t.testName);
            this.slowestNames = a.slowestTests.slice(0, 5).map(t => t.testName);
            this.mostExpensiveNames = a.mostExpensiveTests.slice(0, 5).map(t => t.testName);
            this.emitState();
        });
        this.ScoreDistribution$ = this.instrumentationService.testRuns$.pipe(map(runs => this.buildScoreDistribution(runs)), shareReplay(1));
    }
    calculateTrendDirection(trends) {
        if (trends.length < 2)
            return 'stable';
        const recentHalf = trends.slice(Math.floor(trends.length / 2));
        const olderHalf = trends.slice(0, Math.floor(trends.length / 2));
        const avgRecent = this.averagePassRate(recentHalf);
        const avgOlder = this.averagePassRate(olderHalf);
        const diff = avgRecent - avgOlder;
        if (diff > 2)
            return 'up';
        if (diff < -2)
            return 'down';
        return 'stable';
    }
    averagePassRate(trends) {
        const withRuns = trends.filter(t => t.totalRuns > 0);
        if (withRuns.length === 0)
            return 0;
        return withRuns.reduce((s, t) => s + (t.passed / t.totalRuns) * 100, 0) / withRuns.length;
    }
    buildScoreDistribution(runs) {
        const defs = [
            { label: 'Excellent (>=0.9)', color: '#43a047', min: 0.9, max: 1.01 },
            { label: 'Good (0.7-0.89)', color: '#1e88e5', min: 0.7, max: 0.9 },
            { label: 'Fair (0.5-0.69)', color: '#f57c00', min: 0.5, max: 0.7 },
            { label: 'Poor (0.3-0.49)', color: '#e64a19', min: 0.3, max: 0.5 },
            { label: 'Fail (<0.3)', color: '#e53935', min: 0, max: 0.3 }
        ];
        const total = runs.length || 1;
        return defs.map(d => {
            const count = runs.filter(r => r.score >= d.min && r.score < d.max).length;
            return {
                label: d.label,
                color: d.color,
                count,
                percentage: (count / total) * 100
            };
        });
    }
    async loadVersionMetrics() {
        this.IsLoadingVersions = true;
        this.cdr.markForCheck();
        try {
            const metrics = await this.instrumentationService.getVersionMetrics();
            this.VersionRows = this.buildVersionRows(metrics);
        }
        catch {
            this.VersionRows = [];
        }
        finally {
            this.IsLoadingVersions = false;
            this.emitState();
            this.cdr.markForCheck();
        }
    }
    buildVersionRows(metrics) {
        // metrics are already sorted newest-first by the service
        return metrics.map((m, i) => {
            const prev = i < metrics.length - 1 ? metrics[i + 1] : null;
            let passRateDelta = null;
            let costDelta = null;
            if (prev) {
                passRateDelta = m.passRate - prev.passRate;
                costDelta = prev.totalCost !== 0
                    ? ((m.totalCost - prev.totalCost) / prev.totalCost) * 100
                    : null;
            }
            return {
                version: m.version,
                gitCommitShort: m.gitCommit.length > 7 ? m.gitCommit.substring(0, 7) : m.gitCommit,
                agentVersion: m.agentVersion,
                date: m.runDate,
                totalTests: m.totalTests,
                passRate: m.passRate,
                totalCost: m.totalCost,
                passRateDelta,
                costDelta
            };
        });
    }
    emitState() {
        this.stateChange.emit({
            selectedDays: this.SelectedDays,
            // Breakdown name lists + version count for the dashboard's agent context.
            topFailingTests: this.topFailingNames,
            slowestTests: this.slowestNames,
            mostExpensiveTests: this.mostExpensiveNames,
            versionCount: this.VersionRows.length
        });
    }
    static ɵfac = function TestingAnalyticsComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || TestingAnalyticsComponent)(i0.ɵɵdirectiveInject(i1.TestingInstrumentationService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
    static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TestingAnalyticsComponent, selectors: [["app-testing-analytics"]], inputs: { initialState: "initialState", HideToolbar: "HideToolbar" }, outputs: { stateChange: "stateChange" }, standalone: false, decls: 4, vars: 1, consts: [["content", ""], [4, "ngTemplateOutlet"], ["Title", "Testing Analytics", "Icon", "fa-solid fa-chart-bar", "Subtitle", "Test trends, pass rates, and version metrics"], ["actions", ""], [3, "Label", "Active"], [3, "Clicked"], [3, "Clicked", "Label", "Active"], [1, "testing-analytics"], [1, "section-title"], [1, "fa-solid", "fa-chart-line"], [1, "trend-grid"], [1, "card", "trend-card"], [1, "fa-solid", "fa-check-double"], [1, "fa-solid", "fa-layer-group"], [1, "fa-solid", "fa-star-half-stroke"], [1, "fa-solid", "fa-dollar-sign"], [1, "fa-solid", "fa-magnifying-glass-chart"], [1, "insights-grid"], [1, "card", "insight-card"], [1, "fa-solid", "fa-triangle-exclamation"], [1, "fa-solid", "fa-clock"], [1, "fa-solid", "fa-coins"], [1, "fa-solid", "fa-chart-pie"], [1, "card", "distribution-card"], [1, "fa-solid", "fa-code-compare"], [1, "section-subtitle"], [1, "card", "version-card"], [1, "empty-mini"], ["Size", "compact", "Icon", "fa-solid fa-code-branch", "Title", "No version data available"], [1, "version-table-wrap"], ["Size", "compact", "Icon", "fa-solid fa-chart-area", "Title", "No trend data"], [1, "bar-chart"], [1, "bar-row"], [1, "trend-direction"], [1, "bar-label"], [1, "bar-track"], [1, "bar-fill", "pass-rate-bar"], [1, "bar-value"], [1, "fa-solid", "fa-arrow-trend-up", "trend-up"], [1, "trend-up"], [1, "fa-solid", "fa-arrow-trend-down", "trend-down"], [1, "trend-down"], [1, "fa-solid", "fa-minus", "trend-neutral"], [1, "trend-neutral"], ["Size", "compact", "Icon", "fa-solid fa-chart-bar", "Title", "No volume data"], [1, "legend-row"], [1, "legend-dot", "passed-seg"], [1, "legend-dot", "failed-seg"], [1, "legend-dot", "skipped-seg"], [1, "bar-track", "stacked"], [1, "bar-segment", "passed-seg"], [1, "bar-segment", "failed-seg"], [1, "bar-segment", "skipped-seg"], ["Size", "compact", "Icon", "fa-solid fa-star", "Title", "No score data"], [1, "bar-fill"], ["Size", "compact", "Icon", "fa-solid fa-wallet", "Title", "No cost data"], [1, "bar-fill", "cost-bar"], ["Variant", "success", "Size", "compact", "Title", "No failing tests"], [1, "insight-list"], [1, "insight-row"], [1, "insight-name", 3, "title"], [1, "badge-fail"], [1, "insight-secondary"], ["Size", "compact", "Icon", "fa-solid fa-bolt", "Title", "No duration data"], [1, "insight-primary"], ["Size", "compact", "Icon", "fa-solid fa-dollar-sign", "Title", "No cost data"], ["Size", "compact", "Icon", "fa-solid fa-chart-simple", "Title", "No score data available"], [1, "distribution-bars"], [1, "dist-row"], [1, "dist-label"], [1, "dist-track"], [1, "dist-fill"], [1, "dist-count"], [1, "dist-pct"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "version-table"], [1, "num"], [1, "version-label"], [1, "version-agent"], [1, "delta", 3, "delta-up", "delta-down", "delta-neutral"], [1, "delta"], [1, "fa-solid", "fa-arrow-up"], [1, "fa-solid", "fa-arrow-down"]], template: function TestingAnalyticsComponent_Template(rf, ctx) { if (rf & 1) {
            i0.ɵɵconditionalCreate(0, TestingAnalyticsComponent_Conditional_0_Template, 1, 1, "ng-container")(1, TestingAnalyticsComponent_Conditional_1_Template, 8, 1, "mj-page-layout");
            i0.ɵɵtemplate(2, TestingAnalyticsComponent_ng_template_2_Template, 66, 25, "ng-template", null, 0, i0.ɵɵtemplateRefExtractor);
        } if (rf & 2) {
            i0.ɵɵconditional(ctx.HideToolbar ? 0 : 1);
        } }, dependencies: [i2.NgTemplateOutlet, i3.MJPageHeaderComponent, i3.MJPageLayoutComponent, i3.MJPageBodyComponent, i3.MJFilterChipComponent, i3.MJRefreshButtonComponent, i3.MJEmptyStateComponent, i2.AsyncPipe, i2.DecimalPipe, i2.DatePipe], styles: ["\n\n    \n\n    \n\n    .testing-analytics[_ngcontent-%COMP%] {\n      padding: 24px;\n      height: 100%;\n      overflow-y: auto;\n      background: var(--mj-bg-surface-card);\n    }\n\n    \n\n    \n\n    \n\n    .page-header[_ngcontent-%COMP%] {\n      display: flex;\n      justify-content: space-between;\n      align-items: center;\n      flex-wrap: wrap;\n      gap: 12px;\n      background: var(--mj-bg-surface);\n      padding: 20px 24px;\n      border-radius: 12px;\n      box-shadow: var(--mj-shadow-sm);\n      margin-bottom: 24px;\n    }\n    .header-left[_ngcontent-%COMP%]   h2[_ngcontent-%COMP%] {\n      margin: 0;\n      font-size: 20px;\n      font-weight: 600;\n      color: var(--mj-text-primary);\n      display: flex;\n      align-items: center;\n      gap: 10px;\n    }\n    .header-left[_ngcontent-%COMP%]   h2[_ngcontent-%COMP%]   i[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n    .header-actions[_ngcontent-%COMP%] {\n      display: flex;\n      align-items: center;\n      gap: 12px;\n      flex-wrap: wrap;\n    }\n\n    \n\n    .time-range-pills[_ngcontent-%COMP%] {\n      display: flex;\n      gap: 4px;\n      background: var(--mj-bg-surface-sunken);\n      border-radius: 8px;\n      padding: 3px;\n    }\n    .pill[_ngcontent-%COMP%] {\n      padding: 6px 14px;\n      border: none;\n      border-radius: 6px;\n      font-size: 12px;\n      font-weight: 600;\n      color: var(--mj-text-secondary);\n      background: transparent;\n      cursor: pointer;\n      transition: all 0.2s ease;\n    }\n    .pill[_ngcontent-%COMP%]:hover { background: var(--mj-border-default); }\n    .pill.active[_ngcontent-%COMP%] {\n      background: var(--mj-brand-primary);\n      color: var(--mj-text-inverse);\n      box-shadow: var(--mj-shadow-sm);\n    }\n\n    .refresh-btn[_ngcontent-%COMP%] {\n      display: flex;\n      align-items: center;\n      gap: 6px;\n      padding: 8px 16px;\n      border: 1px solid var(--mj-border-default);\n      border-radius: 8px;\n      background: var(--mj-bg-surface);\n      color: var(--mj-text-secondary);\n      font-size: 12px;\n      font-weight: 500;\n      cursor: pointer;\n      transition: all 0.2s ease;\n    }\n    .refresh-btn[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-card); border-color: var(--mj-border-strong); }\n\n    \n\n    \n\n    \n\n    .section-title[_ngcontent-%COMP%] {\n      display: flex;\n      align-items: center;\n      gap: 8px;\n      font-size: 15px;\n      font-weight: 600;\n      color: var(--mj-text-secondary);\n      margin-bottom: 14px;\n    }\n    .section-title[_ngcontent-%COMP%]   i[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n    .section-subtitle[_ngcontent-%COMP%] {\n      font-size: 12px;\n      font-weight: 400;\n      color: var(--mj-text-disabled);\n      margin-left: 4px;\n    }\n\n    \n\n    \n\n    \n\n    .card[_ngcontent-%COMP%] {\n      background: var(--mj-bg-surface);\n      border-radius: 12px;\n      box-shadow: var(--mj-shadow-sm);\n      padding: 20px;\n      transition: transform 0.2s ease, box-shadow 0.2s ease;\n    }\n    .card[_ngcontent-%COMP%]:hover {\n      transform: translateY(-2px);\n      box-shadow: var(--mj-shadow-md);\n    }\n    .card[_ngcontent-%COMP%]   h4[_ngcontent-%COMP%] {\n      margin: 0 0 14px 0;\n      font-size: 13px;\n      font-weight: 600;\n      color: var(--mj-text-secondary);\n      display: flex;\n      align-items: center;\n      gap: 8px;\n    }\n    .card[_ngcontent-%COMP%]   h4[_ngcontent-%COMP%]   i[_ngcontent-%COMP%] { color: var(--mj-brand-primary); font-size: 14px; }\n\n    \n\n    \n\n    \n\n    .trend-grid[_ngcontent-%COMP%] {\n      display: grid;\n      grid-template-columns: 1fr 1fr;\n      gap: 16px;\n      margin-bottom: 28px;\n    }\n\n    \n\n    .bar-chart[_ngcontent-%COMP%] {\n      display: flex;\n      flex-direction: column;\n      gap: 6px;\n    }\n    .bar-row[_ngcontent-%COMP%] {\n      display: grid;\n      grid-template-columns: 60px 1fr 52px;\n      align-items: center;\n      gap: 8px;\n    }\n    .bar-label[_ngcontent-%COMP%] {\n      font-size: 10px;\n      color: var(--mj-text-disabled);\n      font-weight: 500;\n      text-align: right;\n      white-space: nowrap;\n    }\n    .bar-track[_ngcontent-%COMP%] {\n      height: 14px;\n      background: var(--mj-bg-surface-sunken);\n      border-radius: 7px;\n      overflow: hidden;\n      position: relative;\n    }\n    .bar-track.stacked[_ngcontent-%COMP%] {\n      display: flex;\n    }\n    .bar-fill[_ngcontent-%COMP%] {\n      height: 100%;\n      border-radius: 7px;\n      transition: width 0.4s ease;\n    }\n    .bar-value[_ngcontent-%COMP%] {\n      font-size: 11px;\n      font-weight: 600;\n      color: var(--mj-text-secondary);\n      text-align: right;\n    }\n\n    \n\n    .pass-rate-bar[_ngcontent-%COMP%] {\n      background: var(--mj-status-success);\n    }\n    .cost-bar[_ngcontent-%COMP%] {\n      background: var(--mj-status-warning);\n    }\n    .score-excellent[_ngcontent-%COMP%] { background: var(--mj-status-success); }\n    .score-good[_ngcontent-%COMP%]      { background: var(--mj-brand-primary); }\n    .score-fair[_ngcontent-%COMP%]      { background: var(--mj-status-warning); }\n    .score-poor[_ngcontent-%COMP%]      { background: var(--mj-status-error); }\n\n    \n\n    .text-excellent[_ngcontent-%COMP%] { color: var(--mj-status-success); }\n    .text-good[_ngcontent-%COMP%]      { color: var(--mj-brand-primary); }\n    .text-fair[_ngcontent-%COMP%]      { color: var(--mj-status-warning); }\n    .text-poor[_ngcontent-%COMP%]      { color: var(--mj-status-error); }\n    .text-pass-good[_ngcontent-%COMP%] { color: var(--mj-status-success); }\n    .text-pass-warn[_ngcontent-%COMP%] { color: var(--mj-status-warning); }\n    .text-pass-bad[_ngcontent-%COMP%]  { color: var(--mj-status-error); }\n\n    \n\n    .bar-segment[_ngcontent-%COMP%] { height: 100%; transition: width 0.4s ease; }\n    .passed-seg[_ngcontent-%COMP%]  { background: var(--mj-status-success); }\n    .failed-seg[_ngcontent-%COMP%]  { background: var(--mj-status-error); }\n    .skipped-seg[_ngcontent-%COMP%] { background: var(--mj-text-disabled); }\n\n    .legend-row[_ngcontent-%COMP%] {\n      display: flex;\n      align-items: center;\n      gap: 6px;\n      margin-top: 8px;\n      font-size: 10px;\n      color: var(--mj-text-disabled);\n    }\n    .legend-dot[_ngcontent-%COMP%] {\n      width: 8px;\n      height: 8px;\n      border-radius: 50%;\n      display: inline-block;\n      margin-left: 8px;\n    }\n    .legend-dot[_ngcontent-%COMP%]:first-child { margin-left: 0; }\n    .legend-dot.passed-seg[_ngcontent-%COMP%]  { background: var(--mj-status-success); }\n    .legend-dot.failed-seg[_ngcontent-%COMP%]  { background: var(--mj-status-error); }\n    .legend-dot.skipped-seg[_ngcontent-%COMP%] { background: var(--mj-text-disabled); }\n\n    .trend-direction[_ngcontent-%COMP%] {\n      margin-top: 10px;\n      font-size: 12px;\n      font-weight: 600;\n      display: flex;\n      align-items: center;\n      gap: 6px;\n    }\n    .trend-up[_ngcontent-%COMP%]      { color: var(--mj-status-success); }\n    .trend-down[_ngcontent-%COMP%]    { color: var(--mj-status-error); }\n    .trend-neutral[_ngcontent-%COMP%] { color: var(--mj-text-disabled); }\n\n    \n\n    \n\n    \n\n    .insights-grid[_ngcontent-%COMP%] {\n      display: grid;\n      grid-template-columns: repeat(3, 1fr);\n      gap: 16px;\n      margin-bottom: 28px;\n    }\n\n    .insight-list[_ngcontent-%COMP%] {\n      display: flex;\n      flex-direction: column;\n      gap: 4px;\n    }\n    .insight-row[_ngcontent-%COMP%] {\n      display: grid;\n      grid-template-columns: 1fr auto auto;\n      align-items: center;\n      gap: 10px;\n      padding: 8px 10px;\n      border-radius: 6px;\n      transition: background 0.15s ease;\n    }\n    .insight-row[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-card); }\n    .insight-name[_ngcontent-%COMP%] {\n      font-size: 12px;\n      font-weight: 500;\n      color: var(--mj-text-primary);\n      white-space: nowrap;\n      overflow: hidden;\n      text-overflow: ellipsis;\n    }\n    .badge-fail[_ngcontent-%COMP%] {\n      background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n      color: var(--mj-status-error);\n      font-size: 11px;\n      font-weight: 700;\n      padding: 2px 8px;\n      border-radius: 10px;\n    }\n    .insight-primary[_ngcontent-%COMP%] {\n      font-size: 12px;\n      font-weight: 700;\n      color: var(--mj-brand-primary);\n    }\n    .insight-secondary[_ngcontent-%COMP%] {\n      font-size: 11px;\n      font-weight: 500;\n      color: var(--mj-text-disabled);\n    }\n\n    \n\n    \n\n    \n\n    .distribution-card[_ngcontent-%COMP%] {\n      margin-bottom: 28px;\n    }\n    .distribution-bars[_ngcontent-%COMP%] {\n      display: flex;\n      flex-direction: column;\n      gap: 10px;\n    }\n    .dist-row[_ngcontent-%COMP%] {\n      display: grid;\n      grid-template-columns: 110px 1fr 40px 50px;\n      align-items: center;\n      gap: 10px;\n    }\n    .dist-label[_ngcontent-%COMP%] {\n      font-size: 12px;\n      font-weight: 600;\n      color: var(--mj-text-secondary);\n    }\n    .dist-track[_ngcontent-%COMP%] {\n      height: 22px;\n      background: var(--mj-bg-surface-sunken);\n      border-radius: 6px;\n      overflow: hidden;\n    }\n    .dist-fill[_ngcontent-%COMP%] {\n      height: 100%;\n      border-radius: 6px;\n      transition: width 0.4s ease;\n    }\n    .dist-count[_ngcontent-%COMP%] {\n      font-size: 12px;\n      font-weight: 700;\n      color: var(--mj-text-primary);\n      text-align: right;\n    }\n    .dist-pct[_ngcontent-%COMP%] {\n      font-size: 11px;\n      font-weight: 600;\n      color: var(--mj-text-disabled);\n      text-align: right;\n    }\n\n    \n\n    \n\n    \n\n    .version-card[_ngcontent-%COMP%] {\n      margin-bottom: 28px;\n    }\n    .version-table-wrap[_ngcontent-%COMP%] {\n      overflow-x: auto;\n    }\n    .version-table[_ngcontent-%COMP%] {\n      width: 100%;\n      border-collapse: collapse;\n      font-size: 13px;\n    }\n    .version-table[_ngcontent-%COMP%]   th[_ngcontent-%COMP%] {\n      text-align: left;\n      font-size: 11px;\n      font-weight: 600;\n      color: var(--mj-text-disabled);\n      text-transform: uppercase;\n      padding: 10px 12px;\n      border-bottom: 2px solid var(--mj-border-default);\n    }\n    .version-table[_ngcontent-%COMP%]   th.num[_ngcontent-%COMP%], \n   .version-table[_ngcontent-%COMP%]   td.num[_ngcontent-%COMP%] { text-align: right; }\n    .version-table[_ngcontent-%COMP%]   td[_ngcontent-%COMP%] {\n      padding: 10px 12px;\n      border-bottom: 1px solid var(--mj-bg-surface-sunken);\n      color: var(--mj-text-primary);\n      vertical-align: middle;\n    }\n    .version-table[_ngcontent-%COMP%]   tbody[_ngcontent-%COMP%]   tr[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-card); }\n    .version-label[_ngcontent-%COMP%] {\n      font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n      font-weight: 600;\n      font-size: 12px;\n      color: var(--mj-brand-primary);\n    }\n    .version-agent[_ngcontent-%COMP%] {\n      display: block;\n      font-size: 11px;\n      color: var(--mj-text-disabled);\n      margin-top: 2px;\n    }\n\n    .delta[_ngcontent-%COMP%] {\n      display: inline-flex;\n      align-items: center;\n      gap: 3px;\n      font-size: 11px;\n      font-weight: 600;\n      margin-left: 6px;\n      padding: 1px 6px;\n      border-radius: 4px;\n    }\n    .delta[_ngcontent-%COMP%]   i[_ngcontent-%COMP%] { font-size: 9px; }\n    .delta-up[_ngcontent-%COMP%]   { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n    .delta-down[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n    .delta-neutral[_ngcontent-%COMP%] { background: var(--mj-bg-surface-card); color: var(--mj-text-disabled); }\n\n    \n\n    \n\n    \n\n    .empty-mini[_ngcontent-%COMP%] {\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      justify-content: center;\n      padding: 32px 16px;\n      color: var(--mj-border-strong);\n      gap: 8px;\n    }\n    .empty-mini[_ngcontent-%COMP%]   i[_ngcontent-%COMP%] { font-size: 28px; opacity: 0.5; }\n    .empty-mini[_ngcontent-%COMP%]   span[_ngcontent-%COMP%] { font-size: 12px; }\n\n    \n\n    \n\n    \n\n    @media (max-width: 1100px) {\n      .trend-grid[_ngcontent-%COMP%] { grid-template-columns: 1fr; }\n      .insights-grid[_ngcontent-%COMP%] { grid-template-columns: 1fr 1fr; }\n    }\n    @media (max-width: 720px) {\n      .page-header[_ngcontent-%COMP%] { flex-direction: column; align-items: flex-start; }\n      .insights-grid[_ngcontent-%COMP%] { grid-template-columns: 1fr; }\n      .dist-row[_ngcontent-%COMP%] { grid-template-columns: 80px 1fr 32px 42px; }\n    }"], changeDetection: 0 });
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TestingAnalyticsComponent, [{
        type: Component,
        args: [{ standalone: false, selector: 'app-testing-analytics', changeDetection: ChangeDetectionStrategy.OnPush, template: `
    @if (HideToolbar) {
      <ng-container *ngTemplateOutlet="content"></ng-container>
    } @else {
      <mj-page-layout>
        <mj-page-header
          Title="Testing Analytics"
          Icon="fa-solid fa-chart-bar"
          Subtitle="Test trends, pass rates, and version metrics">
          <div actions>
            @for (range of TimeRanges; track range.days) {
              <mj-filter-chip
                [Label]="range.label"
                [Active]="SelectedDays === range.days"
                (Clicked)="OnTimeRangeSelect(range.days)">
              </mj-filter-chip>
            }
            <mj-refresh-button (Clicked)="Refresh()"></mj-refresh-button>
          </div>
        </mj-page-header>
        <mj-page-body>
          <ng-container *ngTemplateOutlet="content"></ng-container>
        </mj-page-body>
      </mj-page-layout>
    }

    <ng-template #content>
    <div class="testing-analytics">

      <!-- ===== 2. Trend Overview (2-column CSS charts) ===== -->
      <div class="section-title">
        <i class="fa-solid fa-chart-line"></i>
        Trend Overview
      </div>
      <div class="trend-grid">

        <!-- Pass Rate Trend -->
        <div class="card trend-card">
          <h4><i class="fa-solid fa-check-double"></i> Pass Rate Trend</h4>
          @if (DisplayTrends$ | async; as trends) {
            @if (trends.length === 0) {
              <mj-empty-state Size="compact" Icon="fa-solid fa-chart-area" Title="No trend data" />
            } @else {
              <div class="bar-chart">
                @for (t of trends; track trackTrend($index, t)) {
                  <div class="bar-row">
                    <span class="bar-label">{{ FormatBucketDate(t.timestamp) }}</span>
                    <div class="bar-track">
                      <div class="bar-fill pass-rate-bar" [style.width.%]="PassRate(t)"></div>
                    </div>
                    <span class="bar-value" [class]="PassRateClass(t)">{{ PassRate(t) | number:'1.0-0' }}%</span>
                  </div>
                }
              </div>
              <div class="trend-direction">
                @if (PassRateTrendDirection$ | async; as dir) {
                  @if (dir === 'up') {
                    <i class="fa-solid fa-arrow-trend-up trend-up"></i> <span class="trend-up">Improving</span>
                  } @else if (dir === 'down') {
                    <i class="fa-solid fa-arrow-trend-down trend-down"></i> <span class="trend-down">Declining</span>
                  } @else {
                    <i class="fa-solid fa-minus trend-neutral"></i> <span class="trend-neutral">Stable</span>
                  }
                }
              </div>
            }
          }
        </div>

        <!-- Run Volume -->
        <div class="card trend-card">
          <h4><i class="fa-solid fa-layer-group"></i> Run Volume</h4>
          @if (DisplayTrends$ | async; as trends) {
            @if (trends.length === 0) {
              <mj-empty-state Size="compact" Icon="fa-solid fa-chart-bar" Title="No volume data" />
            } @else {
              <div class="bar-chart">
                @for (t of trends; track trackTrend($index, t)) {
                  <div class="bar-row">
                    <span class="bar-label">{{ FormatBucketDate(t.timestamp) }}</span>
                    <div class="bar-track stacked">
                      <div class="bar-segment passed-seg" [style.width.%]="SegmentPct(t, 'passed')"></div>
                      <div class="bar-segment failed-seg" [style.width.%]="SegmentPct(t, 'failed')"></div>
                      <div class="bar-segment skipped-seg" [style.width.%]="SegmentPct(t, 'skipped')"></div>
                    </div>
                    <span class="bar-value">{{ t.totalRuns }}</span>
                  </div>
                }
              </div>
              <div class="legend-row">
                <span class="legend-dot passed-seg"></span> Passed
                <span class="legend-dot failed-seg"></span> Failed
                <span class="legend-dot skipped-seg"></span> Skipped
              </div>
            }
          }
        </div>

        <!-- Score Trend -->
        <div class="card trend-card">
          <h4><i class="fa-solid fa-star-half-stroke"></i> Score Trend</h4>
          @if (DisplayTrends$ | async; as trends) {
            @if (trends.length === 0) {
              <mj-empty-state Size="compact" Icon="fa-solid fa-star" Title="No score data" />
            } @else {
              <div class="bar-chart">
                @for (t of trends; track trackTrend($index, t)) {
                  <div class="bar-row">
                    <span class="bar-label">{{ FormatBucketDate(t.timestamp) }}</span>
                    <div class="bar-track">
                      <div class="bar-fill" [class]="ScoreBarClass(t.averageScore)" [style.width.%]="t.averageScore * 100"></div>
                    </div>
                    <span class="bar-value" [class]="ScoreTextClass(t.averageScore)">{{ (t.averageScore * 100) | number:'1.0-0' }}%</span>
                  </div>
                }
              </div>
            }
          }
        </div>

        <!-- Cost Trend -->
        <div class="card trend-card">
          <h4><i class="fa-solid fa-dollar-sign"></i> Cost Trend</h4>
          @if (DisplayTrends$ | async; as trends) {
            @if (trends.length === 0) {
              <mj-empty-state Size="compact" Icon="fa-solid fa-wallet" Title="No cost data" />
            } @else {
              <div class="bar-chart">
                @for (t of trends; track trackTrend($index, t)) {
                  <div class="bar-row">
                    <span class="bar-label">{{ FormatBucketDate(t.timestamp) }}</span>
                    <div class="bar-track">
                      <div class="bar-fill cost-bar" [style.width.%]="CostBarPct(t, trends)"></div>
                    </div>
                    <span class="bar-value">\${{ t.totalCost | number:'1.2-2' }}</span>
                  </div>
                }
              </div>
            }
          }
        </div>
      </div>

      <!-- ===== 3. Insights Section ===== -->
      <div class="section-title">
        <i class="fa-solid fa-magnifying-glass-chart"></i>
        Insights
      </div>
      <div class="insights-grid">

        <!-- Top Failing Tests -->
        <div class="card insight-card">
          <h4><i class="fa-solid fa-triangle-exclamation"></i> Top Failing Tests</h4>
          @if (TopFailingTests$ | async; as tests) {
            @if (tests.length === 0) {
              <mj-empty-state Variant="success" Size="compact" Title="No failing tests" />
            } @else {
              <div class="insight-list">
                @for (t of tests; track t.testName) {
                  <div class="insight-row">
                    <span class="insight-name" [title]="t.testName">{{ t.testName }}</span>
                    <span class="badge-fail">{{ t.failureCount }}</span>
                    <span class="insight-secondary">{{ t.failureRate | number:'1.0-1' }}%</span>
                  </div>
                }
              </div>
            }
          }
        </div>

        <!-- Slowest Tests -->
        <div class="card insight-card">
          <h4><i class="fa-solid fa-clock"></i> Slowest Tests</h4>
          @if (SlowestTests$ | async; as tests) {
            @if (tests.length === 0) {
              <mj-empty-state Size="compact" Icon="fa-solid fa-bolt" Title="No duration data" />
            } @else {
              <div class="insight-list">
                @for (t of tests; track t.testName) {
                  <div class="insight-row">
                    <span class="insight-name" [title]="t.testName">{{ t.testName }}</span>
                    <span class="insight-primary">{{ FormatDuration(t.avgDuration) }}</span>
                    <span class="insight-secondary">max {{ FormatDuration(t.maxDuration) }}</span>
                  </div>
                }
              </div>
            }
          }
        </div>

        <!-- Most Expensive Tests -->
        <div class="card insight-card">
          <h4><i class="fa-solid fa-coins"></i> Most Expensive Tests</h4>
          @if (MostExpensiveTests$ | async; as tests) {
            @if (tests.length === 0) {
              <mj-empty-state Size="compact" Icon="fa-solid fa-dollar-sign" Title="No cost data" />
            } @else {
              <div class="insight-list">
                @for (t of tests; track t.testName) {
                  <div class="insight-row">
                    <span class="insight-name" [title]="t.testName">{{ t.testName }}</span>
                    <span class="insight-primary">\${{ t.totalCost | number:'1.2-2' }}</span>
                    <span class="insight-secondary">\${{ t.avgCost | number:'1.4-4' }}/run</span>
                  </div>
                }
              </div>
            }
          }
        </div>
      </div>

      <!-- ===== 4. Score Distribution ===== -->
      <div class="section-title">
        <i class="fa-solid fa-chart-pie"></i>
        Score Distribution
      </div>
      <div class="card distribution-card">
        @if (ScoreDistribution$ | async; as buckets) {
          @if (buckets.length === 0) {
            <mj-empty-state Size="compact" Icon="fa-solid fa-chart-simple" Title="No score data available" />
          } @else {
            <div class="distribution-bars">
              @for (b of buckets; track b.label) {
                <div class="dist-row">
                  <span class="dist-label">{{ b.label }}</span>
                  <div class="dist-track">
                    <div class="dist-fill" [style.width.%]="b.percentage" [style.background]="b.color"></div>
                  </div>
                  <span class="dist-count">{{ b.count }}</span>
                  <span class="dist-pct">{{ b.percentage | number:'1.0-1' }}%</span>
                </div>
              }
            </div>
          }
        }
      </div>

      <!-- ===== 5. Version Comparison ===== -->
      <div class="section-title">
        <i class="fa-solid fa-code-compare"></i>
        Version Comparison
        <span class="section-subtitle">Compare metrics across different builds</span>
      </div>
      <div class="card version-card">
        @if (IsLoadingVersions) {
          <div class="empty-mini"><i class="fa-solid fa-spinner fa-spin"></i><span>Loading versions...</span></div>
        } @else if (VersionRows.length === 0) {
          <mj-empty-state Size="compact" Icon="fa-solid fa-code-branch" Title="No version data available" />
        } @else {
          <div class="version-table-wrap">
            <table class="version-table">
              <thead>
                <tr>
                  <th>Version</th>
                  <th>Date</th>
                  <th class="num">Tests</th>
                  <th class="num">Pass Rate</th>
                  <th class="num">Cost</th>
                </tr>
              </thead>
              <tbody>
                @for (row of VersionRows; track row.version) {
                  <tr>
                    <td>
                      <span class="version-label">{{ row.gitCommitShort }}</span>
                      <span class="version-agent">{{ row.agentVersion }}</span>
                    </td>
                    <td>{{ row.date | date:'mediumDate' }}</td>
                    <td class="num">{{ row.totalTests }}</td>
                    <td class="num">
                      <span>{{ row.passRate | number:'1.1-1' }}%</span>
                      @if (row.passRateDelta !== null) {
                        <span class="delta" [class.delta-up]="row.passRateDelta > 0" [class.delta-down]="row.passRateDelta < 0" [class.delta-neutral]="row.passRateDelta === 0">
                          @if (row.passRateDelta > 0) {
                            <i class="fa-solid fa-arrow-up"></i>
                          } @else if (row.passRateDelta < 0) {
                            <i class="fa-solid fa-arrow-down"></i>
                          }
                          {{ AbsNum(row.passRateDelta) | number:'1.1-1' }}%
                        </span>
                      }
                    </td>
                    <td class="num">
                      <span>\${{ row.totalCost | number:'1.2-2' }}</span>
                      @if (row.costDelta !== null) {
                        <span class="delta" [class.delta-up]="row.costDelta < 0" [class.delta-down]="row.costDelta > 0" [class.delta-neutral]="row.costDelta === 0">
                          @if (row.costDelta > 0) {
                            <i class="fa-solid fa-arrow-up"></i>
                          } @else if (row.costDelta < 0) {
                            <i class="fa-solid fa-arrow-down"></i>
                          }
                          {{ AbsNum(row.costDelta) | number:'1.1-1' }}%
                        </span>
                      }
                    </td>
                  </tr>
                }
              </tbody>
            </table>
          </div>
        }
      </div>
    </div>
    </ng-template>
  `, styles: ["\n    /* ------------------------------------------------------------------ */\n    /*  Layout & page                                                      */\n    /* ------------------------------------------------------------------ */\n    .testing-analytics {\n      padding: 24px;\n      height: 100%;\n      overflow-y: auto;\n      background: var(--mj-bg-surface-card);\n    }\n\n    /* ------------------------------------------------------------------ */\n    /*  Page header                                                        */\n    /* ------------------------------------------------------------------ */\n    .page-header {\n      display: flex;\n      justify-content: space-between;\n      align-items: center;\n      flex-wrap: wrap;\n      gap: 12px;\n      background: var(--mj-bg-surface);\n      padding: 20px 24px;\n      border-radius: 12px;\n      box-shadow: var(--mj-shadow-sm);\n      margin-bottom: 24px;\n    }\n    .header-left h2 {\n      margin: 0;\n      font-size: 20px;\n      font-weight: 600;\n      color: var(--mj-text-primary);\n      display: flex;\n      align-items: center;\n      gap: 10px;\n    }\n    .header-left h2 i { color: var(--mj-brand-primary); }\n    .header-actions {\n      display: flex;\n      align-items: center;\n      gap: 12px;\n      flex-wrap: wrap;\n    }\n\n    /* time-range pills */\n    .time-range-pills {\n      display: flex;\n      gap: 4px;\n      background: var(--mj-bg-surface-sunken);\n      border-radius: 8px;\n      padding: 3px;\n    }\n    .pill {\n      padding: 6px 14px;\n      border: none;\n      border-radius: 6px;\n      font-size: 12px;\n      font-weight: 600;\n      color: var(--mj-text-secondary);\n      background: transparent;\n      cursor: pointer;\n      transition: all 0.2s ease;\n    }\n    .pill:hover { background: var(--mj-border-default); }\n    .pill.active {\n      background: var(--mj-brand-primary);\n      color: var(--mj-text-inverse);\n      box-shadow: var(--mj-shadow-sm);\n    }\n\n    .refresh-btn {\n      display: flex;\n      align-items: center;\n      gap: 6px;\n      padding: 8px 16px;\n      border: 1px solid var(--mj-border-default);\n      border-radius: 8px;\n      background: var(--mj-bg-surface);\n      color: var(--mj-text-secondary);\n      font-size: 12px;\n      font-weight: 500;\n      cursor: pointer;\n      transition: all 0.2s ease;\n    }\n    .refresh-btn:hover { background: var(--mj-bg-surface-card); border-color: var(--mj-border-strong); }\n\n    /* ------------------------------------------------------------------ */\n    /*  Section titles                                                     */\n    /* ------------------------------------------------------------------ */\n    .section-title {\n      display: flex;\n      align-items: center;\n      gap: 8px;\n      font-size: 15px;\n      font-weight: 600;\n      color: var(--mj-text-secondary);\n      margin-bottom: 14px;\n    }\n    .section-title i { color: var(--mj-brand-primary); }\n    .section-subtitle {\n      font-size: 12px;\n      font-weight: 400;\n      color: var(--mj-text-disabled);\n      margin-left: 4px;\n    }\n\n    /* ------------------------------------------------------------------ */\n    /*  Cards                                                              */\n    /* ------------------------------------------------------------------ */\n    .card {\n      background: var(--mj-bg-surface);\n      border-radius: 12px;\n      box-shadow: var(--mj-shadow-sm);\n      padding: 20px;\n      transition: transform 0.2s ease, box-shadow 0.2s ease;\n    }\n    .card:hover {\n      transform: translateY(-2px);\n      box-shadow: var(--mj-shadow-md);\n    }\n    .card h4 {\n      margin: 0 0 14px 0;\n      font-size: 13px;\n      font-weight: 600;\n      color: var(--mj-text-secondary);\n      display: flex;\n      align-items: center;\n      gap: 8px;\n    }\n    .card h4 i { color: var(--mj-brand-primary); font-size: 14px; }\n\n    /* ------------------------------------------------------------------ */\n    /*  Trend grid (2 columns)                                             */\n    /* ------------------------------------------------------------------ */\n    .trend-grid {\n      display: grid;\n      grid-template-columns: 1fr 1fr;\n      gap: 16px;\n      margin-bottom: 28px;\n    }\n\n    /* CSS bar charts */\n    .bar-chart {\n      display: flex;\n      flex-direction: column;\n      gap: 6px;\n    }\n    .bar-row {\n      display: grid;\n      grid-template-columns: 60px 1fr 52px;\n      align-items: center;\n      gap: 8px;\n    }\n    .bar-label {\n      font-size: 10px;\n      color: var(--mj-text-disabled);\n      font-weight: 500;\n      text-align: right;\n      white-space: nowrap;\n    }\n    .bar-track {\n      height: 14px;\n      background: var(--mj-bg-surface-sunken);\n      border-radius: 7px;\n      overflow: hidden;\n      position: relative;\n    }\n    .bar-track.stacked {\n      display: flex;\n    }\n    .bar-fill {\n      height: 100%;\n      border-radius: 7px;\n      transition: width 0.4s ease;\n    }\n    .bar-value {\n      font-size: 11px;\n      font-weight: 600;\n      color: var(--mj-text-secondary);\n      text-align: right;\n    }\n\n    /* colour classes for bars */\n    .pass-rate-bar {\n      background: var(--mj-status-success);\n    }\n    .cost-bar {\n      background: var(--mj-status-warning);\n    }\n    .score-excellent { background: var(--mj-status-success); }\n    .score-good      { background: var(--mj-brand-primary); }\n    .score-fair      { background: var(--mj-status-warning); }\n    .score-poor      { background: var(--mj-status-error); }\n\n    /* text colour classes */\n    .text-excellent { color: var(--mj-status-success); }\n    .text-good      { color: var(--mj-brand-primary); }\n    .text-fair      { color: var(--mj-status-warning); }\n    .text-poor      { color: var(--mj-status-error); }\n    .text-pass-good { color: var(--mj-status-success); }\n    .text-pass-warn { color: var(--mj-status-warning); }\n    .text-pass-bad  { color: var(--mj-status-error); }\n\n    /* stacked segments */\n    .bar-segment { height: 100%; transition: width 0.4s ease; }\n    .passed-seg  { background: var(--mj-status-success); }\n    .failed-seg  { background: var(--mj-status-error); }\n    .skipped-seg { background: var(--mj-text-disabled); }\n\n    .legend-row {\n      display: flex;\n      align-items: center;\n      gap: 6px;\n      margin-top: 8px;\n      font-size: 10px;\n      color: var(--mj-text-disabled);\n    }\n    .legend-dot {\n      width: 8px;\n      height: 8px;\n      border-radius: 50%;\n      display: inline-block;\n      margin-left: 8px;\n    }\n    .legend-dot:first-child { margin-left: 0; }\n    .legend-dot.passed-seg  { background: var(--mj-status-success); }\n    .legend-dot.failed-seg  { background: var(--mj-status-error); }\n    .legend-dot.skipped-seg { background: var(--mj-text-disabled); }\n\n    .trend-direction {\n      margin-top: 10px;\n      font-size: 12px;\n      font-weight: 600;\n      display: flex;\n      align-items: center;\n      gap: 6px;\n    }\n    .trend-up      { color: var(--mj-status-success); }\n    .trend-down    { color: var(--mj-status-error); }\n    .trend-neutral { color: var(--mj-text-disabled); }\n\n    /* ------------------------------------------------------------------ */\n    /*  Insights grid (3 columns)                                          */\n    /* ------------------------------------------------------------------ */\n    .insights-grid {\n      display: grid;\n      grid-template-columns: repeat(3, 1fr);\n      gap: 16px;\n      margin-bottom: 28px;\n    }\n\n    .insight-list {\n      display: flex;\n      flex-direction: column;\n      gap: 4px;\n    }\n    .insight-row {\n      display: grid;\n      grid-template-columns: 1fr auto auto;\n      align-items: center;\n      gap: 10px;\n      padding: 8px 10px;\n      border-radius: 6px;\n      transition: background 0.15s ease;\n    }\n    .insight-row:hover { background: var(--mj-bg-surface-card); }\n    .insight-name {\n      font-size: 12px;\n      font-weight: 500;\n      color: var(--mj-text-primary);\n      white-space: nowrap;\n      overflow: hidden;\n      text-overflow: ellipsis;\n    }\n    .badge-fail {\n      background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n      color: var(--mj-status-error);\n      font-size: 11px;\n      font-weight: 700;\n      padding: 2px 8px;\n      border-radius: 10px;\n    }\n    .insight-primary {\n      font-size: 12px;\n      font-weight: 700;\n      color: var(--mj-brand-primary);\n    }\n    .insight-secondary {\n      font-size: 11px;\n      font-weight: 500;\n      color: var(--mj-text-disabled);\n    }\n\n    /* ------------------------------------------------------------------ */\n    /*  Score Distribution                                                 */\n    /* ------------------------------------------------------------------ */\n    .distribution-card {\n      margin-bottom: 28px;\n    }\n    .distribution-bars {\n      display: flex;\n      flex-direction: column;\n      gap: 10px;\n    }\n    .dist-row {\n      display: grid;\n      grid-template-columns: 110px 1fr 40px 50px;\n      align-items: center;\n      gap: 10px;\n    }\n    .dist-label {\n      font-size: 12px;\n      font-weight: 600;\n      color: var(--mj-text-secondary);\n    }\n    .dist-track {\n      height: 22px;\n      background: var(--mj-bg-surface-sunken);\n      border-radius: 6px;\n      overflow: hidden;\n    }\n    .dist-fill {\n      height: 100%;\n      border-radius: 6px;\n      transition: width 0.4s ease;\n    }\n    .dist-count {\n      font-size: 12px;\n      font-weight: 700;\n      color: var(--mj-text-primary);\n      text-align: right;\n    }\n    .dist-pct {\n      font-size: 11px;\n      font-weight: 600;\n      color: var(--mj-text-disabled);\n      text-align: right;\n    }\n\n    /* ------------------------------------------------------------------ */\n    /*  Version Comparison                                                 */\n    /* ------------------------------------------------------------------ */\n    .version-card {\n      margin-bottom: 28px;\n    }\n    .version-table-wrap {\n      overflow-x: auto;\n    }\n    .version-table {\n      width: 100%;\n      border-collapse: collapse;\n      font-size: 13px;\n    }\n    .version-table th {\n      text-align: left;\n      font-size: 11px;\n      font-weight: 600;\n      color: var(--mj-text-disabled);\n      text-transform: uppercase;\n      padding: 10px 12px;\n      border-bottom: 2px solid var(--mj-border-default);\n    }\n    .version-table th.num,\n    .version-table td.num { text-align: right; }\n    .version-table td {\n      padding: 10px 12px;\n      border-bottom: 1px solid var(--mj-bg-surface-sunken);\n      color: var(--mj-text-primary);\n      vertical-align: middle;\n    }\n    .version-table tbody tr:hover { background: var(--mj-bg-surface-card); }\n    .version-label {\n      font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n      font-weight: 600;\n      font-size: 12px;\n      color: var(--mj-brand-primary);\n    }\n    .version-agent {\n      display: block;\n      font-size: 11px;\n      color: var(--mj-text-disabled);\n      margin-top: 2px;\n    }\n\n    .delta {\n      display: inline-flex;\n      align-items: center;\n      gap: 3px;\n      font-size: 11px;\n      font-weight: 600;\n      margin-left: 6px;\n      padding: 1px 6px;\n      border-radius: 4px;\n    }\n    .delta i { font-size: 9px; }\n    .delta-up   { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n    .delta-down { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n    .delta-neutral { background: var(--mj-bg-surface-card); color: var(--mj-text-disabled); }\n\n    /* ------------------------------------------------------------------ */\n    /*  Loading placeholder (data-empty states now use <mj-empty-state>)   */\n    /* ------------------------------------------------------------------ */\n    .empty-mini {\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      justify-content: center;\n      padding: 32px 16px;\n      color: var(--mj-border-strong);\n      gap: 8px;\n    }\n    .empty-mini i { font-size: 28px; opacity: 0.5; }\n    .empty-mini span { font-size: 12px; }\n\n    /* ------------------------------------------------------------------ */\n    /*  Responsive                                                         */\n    /* ------------------------------------------------------------------ */\n    @media (max-width: 1100px) {\n      .trend-grid { grid-template-columns: 1fr; }\n      .insights-grid { grid-template-columns: 1fr 1fr; }\n    }\n    @media (max-width: 720px) {\n      .page-header { flex-direction: column; align-items: flex-start; }\n      .insights-grid { grid-template-columns: 1fr; }\n      .dist-row { grid-template-columns: 80px 1fr 32px 42px; }\n    }\n  "] }]
    }], () => [{ type: i1.TestingInstrumentationService }, { type: i0.ChangeDetectorRef }], { initialState: [{
            type: Input
        }], HideToolbar: [{
            type: Input
        }], stateChange: [{
            type: Output
        }] }); })();
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestingAnalyticsComponent, { className: "TestingAnalyticsComponent", filePath: "src/Testing/components/testing-analytics.component.ts", lineNumber: 780 }); })();
//# sourceMappingURL=testing-analytics.component.js.map