@memberjunction/ng-core-entity-forms 6.2.1 → 6.3.0-edge.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/README.md +5 -6
  2. package/dist/lib/custom/AIAgentCategories/ai-agent-category-header.panel.d.ts.map +1 -1
  3. package/dist/lib/custom/AIAgentCategories/ai-agent-category-header.panel.js +3 -3
  4. package/dist/lib/custom/AIAgentCategories/ai-agent-category-header.panel.js.map +1 -1
  5. package/dist/lib/custom/AIAgentSessions/ai-agent-session-form.component.d.ts +12 -0
  6. package/dist/lib/custom/AIAgentSessions/ai-agent-session-form.component.d.ts.map +1 -1
  7. package/dist/lib/custom/AIAgentSessions/ai-agent-session-form.component.js +293 -230
  8. package/dist/lib/custom/AIAgentSessions/ai-agent-session-form.component.js.map +1 -1
  9. package/dist/lib/custom/AIAgents/add-action-dialog.component.js +2 -2
  10. package/dist/lib/custom/AIAgents/agent-prompt-advanced-settings-dialog.component.js +2 -2
  11. package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts +11 -0
  12. package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts.map +1 -1
  13. package/dist/lib/custom/AIAgents/ai-agent-form.component.js +862 -812
  14. package/dist/lib/custom/AIAgents/ai-agent-form.component.js.map +1 -1
  15. package/dist/lib/custom/AIAgents/create-prompt-dialog.component.js +2 -2
  16. package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.js +2 -2
  17. package/dist/lib/custom/AIAgents/new-agent-dialog.component.js +2 -2
  18. package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.js +2 -2
  19. package/dist/lib/custom/AIAgents/sub-agent-advanced-settings-dialog.component.js +2 -2
  20. package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.js +2 -2
  21. package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.d.ts +12 -0
  22. package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.d.ts.map +1 -1
  23. package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js +821 -763
  24. package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js.map +1 -1
  25. package/dist/lib/custom/AIPromptRuns/chat-message-viewer.component.js +2 -2
  26. package/dist/lib/custom/AIPrompts/ai-prompt-form.component.d.ts +10 -0
  27. package/dist/lib/custom/AIPrompts/ai-prompt-form.component.d.ts.map +1 -1
  28. package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js +700 -605
  29. package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js.map +1 -1
  30. package/dist/lib/custom/Actions/action-execution-log-form.component.d.ts +10 -0
  31. package/dist/lib/custom/Actions/action-execution-log-form.component.d.ts.map +1 -1
  32. package/dist/lib/custom/Actions/action-execution-log-form.component.js +223 -175
  33. package/dist/lib/custom/Actions/action-execution-log-form.component.js.map +1 -1
  34. package/dist/lib/custom/Actions/action-form.component.d.ts +10 -0
  35. package/dist/lib/custom/Actions/action-form.component.d.ts.map +1 -1
  36. package/dist/lib/custom/Actions/action-form.component.js +502 -453
  37. package/dist/lib/custom/Actions/action-form.component.js.map +1 -1
  38. package/dist/lib/custom/Companies/company-header.panel.d.ts.map +1 -1
  39. package/dist/lib/custom/Companies/company-header.panel.js +3 -3
  40. package/dist/lib/custom/Companies/company-header.panel.js.map +1 -1
  41. package/dist/lib/custom/Conversations/conversation-header.panel.d.ts.map +1 -1
  42. package/dist/lib/custom/Conversations/conversation-header.panel.js +3 -3
  43. package/dist/lib/custom/Conversations/conversation-header.panel.js.map +1 -1
  44. package/dist/lib/custom/Employees/employee-header.panel.d.ts.map +1 -1
  45. package/dist/lib/custom/Employees/employee-header.panel.js +3 -3
  46. package/dist/lib/custom/Employees/employee-header.panel.js.map +1 -1
  47. package/dist/lib/custom/Entities/entity-form.component.d.ts +15 -0
  48. package/dist/lib/custom/Entities/entity-form.component.d.ts.map +1 -1
  49. package/dist/lib/custom/Entities/entity-form.component.js +836 -801
  50. package/dist/lib/custom/Entities/entity-form.component.js.map +1 -1
  51. package/dist/lib/custom/EntityActions/entityaction.form.component.js +2 -2
  52. package/dist/lib/custom/Files/file-form.component.js +2 -2
  53. package/dist/lib/custom/Lists/list-form.component.d.ts +5 -0
  54. package/dist/lib/custom/Lists/list-form.component.d.ts.map +1 -1
  55. package/dist/lib/custom/Lists/list-form.component.js +355 -338
  56. package/dist/lib/custom/Lists/list-form.component.js.map +1 -1
  57. package/dist/lib/custom/MLModels/ml-model-form.component.js +3 -3
  58. package/dist/lib/custom/MLModels/ml-model-form.component.js.map +1 -1
  59. package/dist/lib/custom/MLModels/ml-model-view-models.d.ts +17 -35
  60. package/dist/lib/custom/MLModels/ml-model-view-models.d.ts.map +1 -1
  61. package/dist/lib/custom/MLModels/ml-model-view-models.js +55 -54
  62. package/dist/lib/custom/MLModels/ml-model-view-models.js.map +1 -1
  63. package/dist/lib/custom/MLModels/ps-model-detail.component.d.ts +7 -99
  64. package/dist/lib/custom/MLModels/ps-model-detail.component.d.ts.map +1 -1
  65. package/dist/lib/custom/MLModels/ps-model-detail.component.js +124 -303
  66. package/dist/lib/custom/MLModels/ps-model-detail.component.js.map +1 -1
  67. package/dist/lib/custom/Queries/query-form.component.d.ts +9 -0
  68. package/dist/lib/custom/Queries/query-form.component.d.ts.map +1 -1
  69. package/dist/lib/custom/Queries/query-form.component.js +493 -444
  70. package/dist/lib/custom/Queries/query-form.component.js.map +1 -1
  71. package/dist/lib/custom/Queries/query-run-dialog.component.js +2 -2
  72. package/dist/lib/custom/Templates/template-param-dialog.component.js +2 -2
  73. package/dist/lib/custom/Templates/templates-form.component.d.ts +9 -0
  74. package/dist/lib/custom/Templates/templates-form.component.d.ts.map +1 -1
  75. package/dist/lib/custom/Templates/templates-form.component.js +118 -74
  76. package/dist/lib/custom/Templates/templates-form.component.js.map +1 -1
  77. package/dist/lib/custom/Tests/test-form.component.d.ts +5 -0
  78. package/dist/lib/custom/Tests/test-form.component.d.ts.map +1 -1
  79. package/dist/lib/custom/Tests/test-form.component.js +471 -451
  80. package/dist/lib/custom/Tests/test-form.component.js.map +1 -1
  81. package/dist/lib/custom/Tests/test-run-form.component.d.ts +5 -0
  82. package/dist/lib/custom/Tests/test-run-form.component.d.ts.map +1 -1
  83. package/dist/lib/custom/Tests/test-run-form.component.js +312 -289
  84. package/dist/lib/custom/Tests/test-run-form.component.js.map +1 -1
  85. package/dist/lib/custom/Tests/test-suite-form.component.d.ts +5 -0
  86. package/dist/lib/custom/Tests/test-suite-form.component.d.ts.map +1 -1
  87. package/dist/lib/custom/Tests/test-suite-form.component.js +697 -677
  88. package/dist/lib/custom/Tests/test-suite-form.component.js.map +1 -1
  89. package/dist/lib/custom/Tests/test-suite-run-form.component.d.ts +5 -0
  90. package/dist/lib/custom/Tests/test-suite-run-form.component.d.ts.map +1 -1
  91. package/dist/lib/custom/Tests/test-suite-run-form.component.js +453 -433
  92. package/dist/lib/custom/Tests/test-suite-run-form.component.js.map +1 -1
  93. package/dist/lib/custom/Users/user-header.panel.d.ts.map +1 -1
  94. package/dist/lib/custom/Users/user-header.panel.js +3 -3
  95. package/dist/lib/custom/Users/user-header.panel.js.map +1 -1
  96. package/dist/lib/custom/ai-agent-run/agent-run-cost-split.d.ts +2 -2
  97. package/dist/lib/custom/ai-agent-run/agent-run-cost-split.d.ts.map +1 -1
  98. package/dist/lib/custom/ai-agent-run/agent-run-cost-split.js +30 -13
  99. package/dist/lib/custom/ai-agent-run/agent-run-cost-split.js.map +1 -1
  100. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.d.ts +23 -0
  101. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.d.ts.map +1 -1
  102. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js +276 -216
  103. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js.map +1 -1
  104. package/dist/lib/custom/custom-forms.module.d.ts +1 -1
  105. package/dist/lib/custom/custom-forms.module.d.ts.map +1 -1
  106. package/dist/lib/custom/custom-forms.module.js +7 -1
  107. package/dist/lib/custom/custom-forms.module.js.map +1 -1
  108. package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.d.ts.map +1 -1
  109. package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.js +32 -14
  110. package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.js.map +1 -1
  111. package/dist/lib/generated/Entities/MJAction/mjaction.form.component.d.ts.map +1 -1
  112. package/dist/lib/generated/Entities/MJAction/mjaction.form.component.js +119 -95
  113. package/dist/lib/generated/Entities/MJAction/mjaction.form.component.js.map +1 -1
  114. package/dist/lib/generated/Entities/MJComment/mjcomment.form.component.d.ts +10 -0
  115. package/dist/lib/generated/Entities/MJComment/mjcomment.form.component.d.ts.map +1 -0
  116. package/dist/lib/generated/Entities/MJComment/mjcomment.form.component.js +124 -0
  117. package/dist/lib/generated/Entities/MJComment/mjcomment.form.component.js.map +1 -0
  118. package/dist/lib/generated/Entities/MJCommentType/mjcommenttype.form.component.d.ts +10 -0
  119. package/dist/lib/generated/Entities/MJCommentType/mjcommenttype.form.component.d.ts.map +1 -0
  120. package/dist/lib/generated/Entities/MJCommentType/mjcommenttype.form.component.js +99 -0
  121. package/dist/lib/generated/Entities/MJCommentType/mjcommenttype.form.component.js.map +1 -0
  122. package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.js +2 -2
  123. package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.js.map +1 -1
  124. package/dist/lib/generated/Entities/MJConversationType/mjconversationtype.form.component.d.ts +10 -0
  125. package/dist/lib/generated/Entities/MJConversationType/mjconversationtype.form.component.d.ts.map +1 -0
  126. package/dist/lib/generated/Entities/MJConversationType/mjconversationtype.form.component.js +95 -0
  127. package/dist/lib/generated/Entities/MJConversationType/mjconversationtype.form.component.js.map +1 -0
  128. package/dist/lib/generated/Entities/MJDocumentSequenceCounter/mjdocumentsequencecounter.form.component.d.ts +10 -0
  129. package/dist/lib/generated/Entities/MJDocumentSequenceCounter/mjdocumentsequencecounter.form.component.d.ts.map +1 -0
  130. package/dist/lib/generated/Entities/MJDocumentSequenceCounter/mjdocumentsequencecounter.form.component.js +60 -0
  131. package/dist/lib/generated/Entities/MJDocumentSequenceCounter/mjdocumentsequencecounter.form.component.js.map +1 -0
  132. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.d.ts.map +1 -1
  133. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js +124 -106
  134. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js.map +1 -1
  135. package/dist/lib/generated/Entities/MJEntityFieldValue/mjentityfieldvalue.form.component.d.ts.map +1 -1
  136. package/dist/lib/generated/Entities/MJEntityFieldValue/mjentityfieldvalue.form.component.js +12 -4
  137. package/dist/lib/generated/Entities/MJEntityFieldValue/mjentityfieldvalue.form.component.js.map +1 -1
  138. package/dist/lib/generated/Entities/MJEntityOrganicKey/mjentityorganickey.form.component.d.ts.map +1 -1
  139. package/dist/lib/generated/Entities/MJEntityOrganicKey/mjentityorganickey.form.component.js +19 -11
  140. package/dist/lib/generated/Entities/MJEntityOrganicKey/mjentityorganickey.form.component.js.map +1 -1
  141. package/dist/lib/generated/Entities/MJEntityUniqueKey/mjentityuniquekey.form.component.d.ts +10 -0
  142. package/dist/lib/generated/Entities/MJEntityUniqueKey/mjentityuniquekey.form.component.d.ts.map +1 -0
  143. package/dist/lib/generated/Entities/MJEntityUniqueKey/mjentityuniquekey.form.component.js +62 -0
  144. package/dist/lib/generated/Entities/MJEntityUniqueKey/mjentityuniquekey.form.component.js.map +1 -0
  145. package/dist/lib/generated/Entities/MJFeatureValue/mjfeaturevalue.form.component.d.ts.map +1 -1
  146. package/dist/lib/generated/Entities/MJFeatureValue/mjfeaturevalue.form.component.js +26 -12
  147. package/dist/lib/generated/Entities/MJFeatureValue/mjfeaturevalue.form.component.js.map +1 -1
  148. package/dist/lib/generated/Entities/MJFieldSuggestion/mjfieldsuggestion.form.component.d.ts +10 -0
  149. package/dist/lib/generated/Entities/MJFieldSuggestion/mjfieldsuggestion.form.component.d.ts.map +1 -0
  150. package/dist/lib/generated/Entities/MJFieldSuggestion/mjfieldsuggestion.form.component.js +140 -0
  151. package/dist/lib/generated/Entities/MJFieldSuggestion/mjfieldsuggestion.form.component.js.map +1 -0
  152. package/dist/lib/generated/Entities/MJFile/mjfile.form.component.d.ts.map +1 -1
  153. package/dist/lib/generated/Entities/MJFile/mjfile.form.component.js +69 -15
  154. package/dist/lib/generated/Entities/MJFile/mjfile.form.component.js.map +1 -1
  155. package/dist/lib/generated/Entities/MJFileStorageProvider/mjfilestorageprovider.form.component.d.ts.map +1 -1
  156. package/dist/lib/generated/Entities/MJFileStorageProvider/mjfilestorageprovider.form.component.js +31 -13
  157. package/dist/lib/generated/Entities/MJFileStorageProvider/mjfilestorageprovider.form.component.js.map +1 -1
  158. package/dist/lib/generated/Entities/MJMLEvaluationProtocol/mjmlevaluationprotocol.form.component.d.ts +10 -0
  159. package/dist/lib/generated/Entities/MJMLEvaluationProtocol/mjmlevaluationprotocol.form.component.d.ts.map +1 -0
  160. package/dist/lib/generated/Entities/MJMLEvaluationProtocol/mjmlevaluationprotocol.form.component.js +205 -0
  161. package/dist/lib/generated/Entities/MJMLEvaluationProtocol/mjmlevaluationprotocol.form.component.js.map +1 -0
  162. package/dist/lib/generated/Entities/MJMLModel/mjmlmodel.form.component.d.ts.map +1 -1
  163. package/dist/lib/generated/Entities/MJMLModel/mjmlmodel.form.component.js +24 -6
  164. package/dist/lib/generated/Entities/MJMLModel/mjmlmodel.form.component.js.map +1 -1
  165. package/dist/lib/generated/Entities/MJMLPredictionUnit/mjmlpredictionunit.form.component.d.ts +10 -0
  166. package/dist/lib/generated/Entities/MJMLPredictionUnit/mjmlpredictionunit.form.component.d.ts.map +1 -0
  167. package/dist/lib/generated/Entities/MJMLPredictionUnit/mjmlpredictionunit.form.component.js +173 -0
  168. package/dist/lib/generated/Entities/MJMLPredictionUnit/mjmlpredictionunit.form.component.js.map +1 -0
  169. package/dist/lib/generated/Entities/MJMLTrainingPipeline/mjmltrainingpipeline.form.component.d.ts.map +1 -1
  170. package/dist/lib/generated/Entities/MJMLTrainingPipeline/mjmltrainingpipeline.form.component.js +46 -24
  171. package/dist/lib/generated/Entities/MJMLTrainingPipeline/mjmltrainingpipeline.form.component.js.map +1 -1
  172. package/dist/lib/generated/Entities/MJMLTrainingRun/mjmltrainingrun.form.component.js +22 -14
  173. package/dist/lib/generated/Entities/MJMLTrainingRun/mjmltrainingrun.form.component.js.map +1 -1
  174. package/dist/lib/generated/Entities/MJMLTrainingSnapshot/mjmltrainingsnapshot.form.component.d.ts +10 -0
  175. package/dist/lib/generated/Entities/MJMLTrainingSnapshot/mjmltrainingsnapshot.form.component.d.ts.map +1 -0
  176. package/dist/lib/generated/Entities/MJMLTrainingSnapshot/mjmltrainingsnapshot.form.component.js +175 -0
  177. package/dist/lib/generated/Entities/MJMLTrainingSnapshot/mjmltrainingsnapshot.form.component.js.map +1 -0
  178. package/dist/lib/generated/Entities/MJQueryField/mjqueryfield.form.component.js +8 -6
  179. package/dist/lib/generated/Entities/MJQueryField/mjqueryfield.form.component.js.map +1 -1
  180. package/dist/lib/generated/Entities/MJRecordProcess/mjrecordprocess.form.component.d.ts.map +1 -1
  181. package/dist/lib/generated/Entities/MJRecordProcess/mjrecordprocess.form.component.js +44 -36
  182. package/dist/lib/generated/Entities/MJRecordProcess/mjrecordprocess.form.component.js.map +1 -1
  183. package/dist/lib/generated/Entities/MJTask/mjtask.form.component.d.ts.map +1 -1
  184. package/dist/lib/generated/Entities/MJTask/mjtask.form.component.js +54 -32
  185. package/dist/lib/generated/Entities/MJTask/mjtask.form.component.js.map +1 -1
  186. package/dist/lib/generated/generated-forms.module.d.ts +452 -443
  187. package/dist/lib/generated/generated-forms.module.d.ts.map +1 -1
  188. package/dist/lib/generated/generated-forms.module.js +27 -0
  189. package/dist/lib/generated/generated-forms.module.js.map +1 -1
  190. package/dist/lib/panels/feature-values/feature-values.panel.js +1 -1
  191. package/dist/lib/panels/feature-values/feature-values.panel.js.map +1 -1
  192. package/dist/lib/panels/model-predictions/model-prediction.logic.d.ts +1 -1
  193. package/dist/lib/panels/model-predictions/model-prediction.logic.d.ts.map +1 -1
  194. package/dist/lib/panels/model-predictions/model-prediction.logic.js.map +1 -1
  195. package/dist/lib/shared/components/template-editor.component.js +2 -2
  196. package/dist/lib/shared/phone-hero.d.ts +17 -0
  197. package/dist/lib/shared/phone-hero.d.ts.map +1 -0
  198. package/dist/lib/shared/phone-hero.js +30 -0
  199. package/dist/lib/shared/phone-hero.js.map +1 -0
  200. package/dist/lib/shared/phone-sections-state.d.ts +28 -0
  201. package/dist/lib/shared/phone-sections-state.d.ts.map +1 -0
  202. package/dist/lib/shared/phone-sections-state.js +38 -0
  203. package/dist/lib/shared/phone-sections-state.js.map +1 -0
  204. package/package.json +50 -50
@@ -36,7 +36,7 @@ function MJTestFormComponentExtended_Conditional_21_Template(rf, ctx) { if (rf &
36
36
  } }
37
37
  function MJTestFormComponentExtended_Conditional_26_Template(rf, ctx) { if (rf & 1) {
38
38
  i0.ɵɵelementStart(0, "span", 18);
39
- i0.ɵɵelement(1, "i", 54);
39
+ i0.ɵɵelement(1, "i", 55);
40
40
  i0.ɵɵtext(2);
41
41
  i0.ɵɵelementEnd();
42
42
  } if (rf & 2) {
@@ -46,7 +46,7 @@ function MJTestFormComponentExtended_Conditional_26_Template(rf, ctx) { if (rf &
46
46
  } }
47
47
  function MJTestFormComponentExtended_Conditional_27_Template(rf, ctx) { if (rf & 1) {
48
48
  i0.ɵɵelementStart(0, "span", 19);
49
- i0.ɵɵelement(1, "i", 55);
49
+ i0.ɵɵelement(1, "i", 56);
50
50
  i0.ɵɵtext(2, " Unsaved ");
51
51
  i0.ɵɵelementEnd();
52
52
  } }
@@ -60,31 +60,31 @@ function MJTestFormComponentExtended_Conditional_36_Template(rf, ctx) { if (rf &
60
60
  i0.ɵɵtextInterpolate(ctx_r0.record.Description);
61
61
  } }
62
62
  function MJTestFormComponentExtended_Conditional_37_Template(rf, ctx) { if (rf & 1) {
63
- i0.ɵɵelementStart(0, "div", 25)(1, "div", 56)(2, "div", 57);
63
+ i0.ɵɵelementStart(0, "div", 25)(1, "div", 57)(2, "div", 58);
64
64
  i0.ɵɵtext(3, "Total Runs");
65
65
  i0.ɵɵelementEnd();
66
- i0.ɵɵelementStart(4, "div", 58);
66
+ i0.ɵɵelementStart(4, "div", 59);
67
67
  i0.ɵɵtext(5);
68
68
  i0.ɵɵelementEnd()();
69
- i0.ɵɵelementStart(6, "div", 56)(7, "div", 57);
69
+ i0.ɵɵelementStart(6, "div", 57)(7, "div", 58);
70
70
  i0.ɵɵtext(8, "Pass Rate");
71
71
  i0.ɵɵelementEnd();
72
- i0.ɵɵelementStart(9, "div", 58);
72
+ i0.ɵɵelementStart(9, "div", 59);
73
73
  i0.ɵɵtext(10);
74
74
  i0.ɵɵelementEnd();
75
- i0.ɵɵelementStart(11, "div", 59);
76
- i0.ɵɵelement(12, "div", 60);
75
+ i0.ɵɵelementStart(11, "div", 60);
76
+ i0.ɵɵelement(12, "div", 61);
77
77
  i0.ɵɵelementEnd()();
78
- i0.ɵɵelementStart(13, "div", 56)(14, "div", 57);
78
+ i0.ɵɵelementStart(13, "div", 57)(14, "div", 58);
79
79
  i0.ɵɵtext(15, "Avg Cost");
80
80
  i0.ɵɵelementEnd();
81
- i0.ɵɵelementStart(16, "div", 58);
81
+ i0.ɵɵelementStart(16, "div", 59);
82
82
  i0.ɵɵtext(17);
83
83
  i0.ɵɵelementEnd()();
84
- i0.ɵɵelementStart(18, "div", 56)(19, "div", 57);
84
+ i0.ɵɵelementStart(18, "div", 57)(19, "div", 58);
85
85
  i0.ɵɵtext(20, "Avg Duration");
86
86
  i0.ɵɵelementEnd();
87
- i0.ɵɵelementStart(21, "div", 58);
87
+ i0.ɵɵelementStart(21, "div", 59);
88
88
  i0.ɵɵtext(22);
89
89
  i0.ɵɵelementEnd()()();
90
90
  } if (rf & 2) {
@@ -100,8 +100,8 @@ function MJTestFormComponentExtended_Conditional_37_Template(rf, ctx) { if (rf &
100
100
  i0.ɵɵadvance(5);
101
101
  i0.ɵɵtextInterpolate(ctx_r0.formatDuration(ctx_r0.getAverageDuration()));
102
102
  } }
103
- function MJTestFormComponentExtended_Conditional_52_Template(rf, ctx) { if (rf & 1) {
104
- i0.ɵɵelementStart(0, "span", 32);
103
+ function MJTestFormComponentExtended_Conditional_53_Template(rf, ctx) { if (rf & 1) {
104
+ i0.ɵɵelementStart(0, "span", 33);
105
105
  i0.ɵɵtext(1);
106
106
  i0.ɵɵelementEnd();
107
107
  } if (rf & 2) {
@@ -109,8 +109,8 @@ function MJTestFormComponentExtended_Conditional_52_Template(rf, ctx) { if (rf &
109
109
  i0.ɵɵadvance();
110
110
  i0.ɵɵtextInterpolate(ctx_r0.testRuns.length);
111
111
  } }
112
- function MJTestFormComponentExtended_Conditional_57_Template(rf, ctx) { if (rf & 1) {
113
- i0.ɵɵelementStart(0, "span", 32);
112
+ function MJTestFormComponentExtended_Conditional_58_Template(rf, ctx) { if (rf & 1) {
113
+ i0.ɵɵelementStart(0, "span", 33);
114
114
  i0.ɵɵtext(1);
115
115
  i0.ɵɵelementEnd();
116
116
  } if (rf & 2) {
@@ -118,100 +118,100 @@ function MJTestFormComponentExtended_Conditional_57_Template(rf, ctx) { if (rf &
118
118
  i0.ɵɵadvance();
119
119
  i0.ɵɵtextInterpolate(ctx_r0.suiteTests.length);
120
120
  } }
121
- function MJTestFormComponentExtended_Conditional_63_Template(rf, ctx) { if (rf & 1) {
121
+ function MJTestFormComponentExtended_Conditional_64_Template(rf, ctx) { if (rf & 1) {
122
122
  const _r2 = i0.ɵɵgetCurrentView();
123
- i0.ɵɵelementStart(0, "div", 36)(1, "div", 61)(2, "h3");
124
- i0.ɵɵelement(3, "i", 62);
123
+ i0.ɵɵelementStart(0, "div", 37)(1, "div", 62)(2, "h3");
124
+ i0.ɵɵelement(3, "i", 63);
125
125
  i0.ɵɵtext(4, " Test Information");
126
126
  i0.ɵɵelementEnd();
127
- i0.ɵɵelementStart(5, "div", 63)(6, "div", 64)(7, "div", 65);
127
+ i0.ɵɵelementStart(5, "div", 64)(6, "div", 65)(7, "div", 66);
128
128
  i0.ɵɵtext(8, "Name");
129
129
  i0.ɵɵelementEnd();
130
- i0.ɵɵelementStart(9, "div", 66);
130
+ i0.ɵɵelementStart(9, "div", 67);
131
131
  i0.ɵɵtext(10);
132
132
  i0.ɵɵelementEnd()();
133
- i0.ɵɵelementStart(11, "div", 64)(12, "div", 65);
133
+ i0.ɵɵelementStart(11, "div", 65)(12, "div", 66);
134
134
  i0.ɵɵtext(13, "Type");
135
135
  i0.ɵɵelementEnd();
136
- i0.ɵɵelementStart(14, "div", 66);
136
+ i0.ɵɵelementStart(14, "div", 67);
137
137
  i0.ɵɵtext(15);
138
138
  i0.ɵɵelementEnd()();
139
- i0.ɵɵelementStart(16, "div", 64)(17, "div", 65);
139
+ i0.ɵɵelementStart(16, "div", 65)(17, "div", 66);
140
140
  i0.ɵɵtext(18, "Status");
141
141
  i0.ɵɵelementEnd();
142
- i0.ɵɵelementStart(19, "div", 66)(20, "span", 67);
142
+ i0.ɵɵelementStart(19, "div", 67)(20, "span", 68);
143
143
  i0.ɵɵtext(21);
144
144
  i0.ɵɵelementEnd()()();
145
- i0.ɵɵelementStart(22, "div", 64)(23, "div", 65);
145
+ i0.ɵɵelementStart(22, "div", 65)(23, "div", 66);
146
146
  i0.ɵɵtext(24, "Priority");
147
147
  i0.ɵɵelementEnd();
148
- i0.ɵɵelementStart(25, "div", 66);
148
+ i0.ɵɵelementStart(25, "div", 67);
149
149
  i0.ɵɵtext(26);
150
150
  i0.ɵɵelementEnd()();
151
- i0.ɵɵelementStart(27, "div", 64)(28, "div", 65);
151
+ i0.ɵɵelementStart(27, "div", 65)(28, "div", 66);
152
152
  i0.ɵɵtext(29, "Estimated Duration");
153
153
  i0.ɵɵelementEnd();
154
- i0.ɵɵelementStart(30, "div", 66);
154
+ i0.ɵɵelementStart(30, "div", 67);
155
155
  i0.ɵɵtext(31);
156
156
  i0.ɵɵelementEnd()();
157
- i0.ɵɵelementStart(32, "div", 64)(33, "div", 65);
157
+ i0.ɵɵelementStart(32, "div", 65)(33, "div", 66);
158
158
  i0.ɵɵtext(34, "Estimated Cost");
159
159
  i0.ɵɵelementEnd();
160
- i0.ɵɵelementStart(35, "div", 66);
160
+ i0.ɵɵelementStart(35, "div", 67);
161
161
  i0.ɵɵtext(36);
162
162
  i0.ɵɵelementEnd()();
163
- i0.ɵɵelementStart(37, "div", 64)(38, "div", 65);
163
+ i0.ɵɵelementStart(37, "div", 65)(38, "div", 66);
164
164
  i0.ɵɵtext(39, "Repeat Count");
165
165
  i0.ɵɵelementEnd();
166
- i0.ɵɵelementStart(40, "div", 66);
166
+ i0.ɵɵelementStart(40, "div", 67);
167
167
  i0.ɵɵtext(41);
168
168
  i0.ɵɵelementEnd()();
169
- i0.ɵɵelementStart(42, "div", 64)(43, "div", 65);
169
+ i0.ɵɵelementStart(42, "div", 65)(43, "div", 66);
170
170
  i0.ɵɵtext(44, "Max Execution Time");
171
171
  i0.ɵɵelementEnd();
172
- i0.ɵɵelementStart(45, "div", 66);
172
+ i0.ɵɵelementStart(45, "div", 67);
173
173
  i0.ɵɵtext(46);
174
174
  i0.ɵɵelementEnd()();
175
- i0.ɵɵelementStart(47, "div", 64)(48, "div", 65);
175
+ i0.ɵɵelementStart(47, "div", 65)(48, "div", 66);
176
176
  i0.ɵɵtext(49, "Created");
177
177
  i0.ɵɵelementEnd();
178
- i0.ɵɵelementStart(50, "div", 66);
178
+ i0.ɵɵelementStart(50, "div", 67);
179
179
  i0.ɵɵtext(51);
180
180
  i0.ɵɵpipe(52, "date");
181
181
  i0.ɵɵelementEnd()();
182
- i0.ɵɵelementStart(53, "div", 64)(54, "div", 65);
182
+ i0.ɵɵelementStart(53, "div", 65)(54, "div", 66);
183
183
  i0.ɵɵtext(55, "Updated");
184
184
  i0.ɵɵelementEnd();
185
- i0.ɵɵelementStart(56, "div", 66);
185
+ i0.ɵɵelementStart(56, "div", 67);
186
186
  i0.ɵɵtext(57);
187
187
  i0.ɵɵpipe(58, "date");
188
188
  i0.ɵɵelementEnd()()()();
189
- i0.ɵɵelementStart(59, "div", 68)(60, "h3");
190
- i0.ɵɵelement(61, "i", 69);
189
+ i0.ɵɵelementStart(59, "div", 69)(60, "h3");
190
+ i0.ɵɵelement(61, "i", 70);
191
191
  i0.ɵɵtext(62, " Test Definition");
192
192
  i0.ɵɵelementEnd();
193
- i0.ɵɵelementStart(63, "div", 70)(64, "button", 71);
194
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_63_Template_button_click_64_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.setJsonView("input")); });
195
- i0.ɵɵelement(65, "i", 72);
193
+ i0.ɵɵelementStart(63, "div", 71)(64, "button", 72);
194
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_64_Template_button_click_64_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.setJsonView("input")); });
195
+ i0.ɵɵelement(65, "i", 73);
196
196
  i0.ɵɵtext(66, " Input Definition ");
197
197
  i0.ɵɵelementEnd();
198
- i0.ɵɵelementStart(67, "button", 71);
199
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_63_Template_button_click_67_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.setJsonView("expected")); });
200
- i0.ɵɵelement(68, "i", 73);
198
+ i0.ɵɵelementStart(67, "button", 72);
199
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_64_Template_button_click_67_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.setJsonView("expected")); });
200
+ i0.ɵɵelement(68, "i", 74);
201
201
  i0.ɵɵtext(69, " Expected Outcomes ");
202
202
  i0.ɵɵelementEnd();
203
- i0.ɵɵelementStart(70, "button", 71);
204
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_63_Template_button_click_70_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.setJsonView("config")); });
205
- i0.ɵɵelement(71, "i", 74);
203
+ i0.ɵɵelementStart(70, "button", 72);
204
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_64_Template_button_click_70_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.setJsonView("config")); });
205
+ i0.ɵɵelement(71, "i", 75);
206
206
  i0.ɵɵtext(72, " Configuration ");
207
207
  i0.ɵɵelementEnd();
208
- i0.ɵɵelementStart(73, "button", 71);
209
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_63_Template_button_click_73_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.setJsonView("tags")); });
210
- i0.ɵɵelement(74, "i", 75);
208
+ i0.ɵɵelementStart(73, "button", 72);
209
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_64_Template_button_click_73_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.setJsonView("tags")); });
210
+ i0.ɵɵelement(74, "i", 76);
211
211
  i0.ɵɵtext(75, " Tags ");
212
212
  i0.ɵɵelementEnd()();
213
- i0.ɵɵelementStart(76, "div", 76);
214
- i0.ɵɵelement(77, "mj-code-editor", 77);
213
+ i0.ɵɵelementStart(76, "div", 77);
214
+ i0.ɵɵelement(77, "mj-code-editor", 78);
215
215
  i0.ɵɵelementEnd()()();
216
216
  } if (rf & 2) {
217
217
  const ctx_r0 = i0.ɵɵnextContext();
@@ -248,8 +248,8 @@ function MJTestFormComponentExtended_Conditional_63_Template(rf, ctx) { if (rf &
248
248
  i0.ɵɵadvance(4);
249
249
  i0.ɵɵproperty("value", ctx_r0.getJsonData())("readonly", true)("toolbar", ctx_r0.jsonToolbar)("lineWrapping", true);
250
250
  } }
251
- function MJTestFormComponentExtended_Conditional_64_For_25_Template(rf, ctx) { if (rf & 1) {
252
- i0.ɵɵelementStart(0, "option", 93);
251
+ function MJTestFormComponentExtended_Conditional_65_For_25_Template(rf, ctx) { if (rf & 1) {
252
+ i0.ɵɵelementStart(0, "option", 94);
253
253
  i0.ɵɵtext(1);
254
254
  i0.ɵɵelementEnd();
255
255
  } if (rf & 2) {
@@ -258,8 +258,8 @@ function MJTestFormComponentExtended_Conditional_64_For_25_Template(rf, ctx) { i
258
258
  i0.ɵɵadvance();
259
259
  i0.ɵɵtextInterpolate(opt_r4);
260
260
  } }
261
- function MJTestFormComponentExtended_Conditional_64_For_33_Template(rf, ctx) { if (rf & 1) {
262
- i0.ɵɵelementStart(0, "option", 93);
261
+ function MJTestFormComponentExtended_Conditional_65_For_33_Template(rf, ctx) { if (rf & 1) {
262
+ i0.ɵɵelementStart(0, "option", 94);
263
263
  i0.ɵɵtext(1);
264
264
  i0.ɵɵelementEnd();
265
265
  } if (rf & 2) {
@@ -268,8 +268,8 @@ function MJTestFormComponentExtended_Conditional_64_For_33_Template(rf, ctx) { i
268
268
  i0.ɵɵadvance();
269
269
  i0.ɵɵtextInterpolate(rubric_r5.name);
270
270
  } }
271
- function MJTestFormComponentExtended_Conditional_64_For_39_Template(rf, ctx) { if (rf & 1) {
272
- i0.ɵɵelementStart(0, "option", 93);
271
+ function MJTestFormComponentExtended_Conditional_65_For_39_Template(rf, ctx) { if (rf & 1) {
272
+ i0.ɵɵelementStart(0, "option", 94);
273
273
  i0.ɵɵtext(1);
274
274
  i0.ɵɵelementEnd();
275
275
  } if (rf & 2) {
@@ -278,13 +278,13 @@ function MJTestFormComponentExtended_Conditional_64_For_39_Template(rf, ctx) { i
278
278
  i0.ɵɵadvance();
279
279
  i0.ɵɵtextInterpolate(t_r6.Name);
280
280
  } }
281
- function MJTestFormComponentExtended_Conditional_64_For_45_Template(rf, ctx) { if (rf & 1) {
281
+ function MJTestFormComponentExtended_Conditional_65_For_45_Template(rf, ctx) { if (rf & 1) {
282
282
  const _r8 = i0.ɵɵgetCurrentView();
283
- i0.ɵɵelementStart(0, "span", 100);
283
+ i0.ɵɵelementStart(0, "span", 101);
284
284
  i0.ɵɵtext(1);
285
- i0.ɵɵelementStart(2, "button", 123);
286
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_64_For_45_Template_button_click_2_listener($event) { const tag_r9 = i0.ɵɵrestoreView(_r8).$implicit; const ctx_r0 = i0.ɵɵnextContext(2); ctx_r0.removeTag(tag_r9); return i0.ɵɵresetView($event.stopPropagation()); });
287
- i0.ɵɵelement(3, "i", 124);
285
+ i0.ɵɵelementStart(2, "button", 124);
286
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_65_For_45_Template_button_click_2_listener($event) { const tag_r9 = i0.ɵɵrestoreView(_r8).$implicit; const ctx_r0 = i0.ɵɵnextContext(2); ctx_r0.removeTag(tag_r9); return i0.ɵɵresetView($event.stopPropagation()); });
287
+ i0.ɵɵelement(3, "i", 125);
288
288
  i0.ɵɵelementEnd()();
289
289
  } if (rf & 2) {
290
290
  const tag_r9 = ctx.$implicit;
@@ -293,148 +293,148 @@ function MJTestFormComponentExtended_Conditional_64_For_45_Template(rf, ctx) { i
293
293
  i0.ɵɵadvance();
294
294
  i0.ɵɵattribute("aria-label", "Remove tag " + tag_r9);
295
295
  } }
296
- function MJTestFormComponentExtended_Conditional_64_Template(rf, ctx) { if (rf & 1) {
296
+ function MJTestFormComponentExtended_Conditional_65_Template(rf, ctx) { if (rf & 1) {
297
297
  const _r3 = i0.ɵɵgetCurrentView();
298
- i0.ɵɵelementStart(0, "div", 37)(1, "section", 78)(2, "header", 79)(3, "h3");
299
- i0.ɵɵelement(4, "i", 80);
298
+ i0.ɵɵelementStart(0, "div", 38)(1, "section", 79)(2, "header", 80)(3, "h3");
299
+ i0.ɵɵelement(4, "i", 81);
300
300
  i0.ɵɵtext(5, " Details");
301
301
  i0.ɵɵelementEnd();
302
- i0.ɵɵelementStart(6, "p", 81);
302
+ i0.ɵɵelementStart(6, "p", 82);
303
303
  i0.ɵɵtext(7, "Edit any field \u2014 changes are saved with the bar at the bottom.");
304
304
  i0.ɵɵelementEnd()();
305
- i0.ɵɵelementStart(8, "div", 82)(9, "div", 83)(10, "label", 84);
305
+ i0.ɵɵelementStart(8, "div", 83)(9, "div", 84)(10, "label", 85);
306
306
  i0.ɵɵtext(11, "Name ");
307
- i0.ɵɵelementStart(12, "span", 85);
307
+ i0.ɵɵelementStart(12, "span", 86);
308
308
  i0.ɵɵtext(13, "*");
309
309
  i0.ɵɵelementEnd()();
310
- i0.ɵɵelementStart(14, "input", 86);
311
- i0.ɵɵtwoWayListener("ngModelChange", function MJTestFormComponentExtended_Conditional_64_Template_input_ngModelChange_14_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.record.Name, $event) || (ctx_r0.record.Name = $event); return i0.ɵɵresetView($event); });
310
+ i0.ɵɵelementStart(14, "input", 87);
311
+ i0.ɵɵtwoWayListener("ngModelChange", function MJTestFormComponentExtended_Conditional_65_Template_input_ngModelChange_14_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.record.Name, $event) || (ctx_r0.record.Name = $event); return i0.ɵɵresetView($event); });
312
312
  i0.ɵɵelementEnd()();
313
- i0.ɵɵelementStart(15, "div", 83)(16, "label", 87);
313
+ i0.ɵɵelementStart(15, "div", 84)(16, "label", 88);
314
314
  i0.ɵɵtext(17, "Description");
315
315
  i0.ɵɵelementEnd();
316
- i0.ɵɵelementStart(18, "textarea", 88);
317
- i0.ɵɵlistener("ngModelChange", function MJTestFormComponentExtended_Conditional_64_Template_textarea_ngModelChange_18_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.Description = $event || null); });
316
+ i0.ɵɵelementStart(18, "textarea", 89);
317
+ i0.ɵɵlistener("ngModelChange", function MJTestFormComponentExtended_Conditional_65_Template_textarea_ngModelChange_18_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.Description = $event || null); });
318
318
  i0.ɵɵelementEnd()();
319
- i0.ɵɵelementStart(19, "div", 89)(20, "label", 90);
319
+ i0.ɵɵelementStart(19, "div", 90)(20, "label", 91);
320
320
  i0.ɵɵtext(21, "Status");
321
321
  i0.ɵɵelementEnd();
322
- i0.ɵɵelementStart(22, "div", 91)(23, "select", 92);
323
- i0.ɵɵtwoWayListener("ngModelChange", function MJTestFormComponentExtended_Conditional_64_Template_select_ngModelChange_23_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.record.Status, $event) || (ctx_r0.record.Status = $event); return i0.ɵɵresetView($event); });
324
- i0.ɵɵrepeaterCreate(24, MJTestFormComponentExtended_Conditional_64_For_25_Template, 2, 2, "option", 93, i0.ɵɵrepeaterTrackByIdentity);
322
+ i0.ɵɵelementStart(22, "div", 92)(23, "select", 93);
323
+ i0.ɵɵtwoWayListener("ngModelChange", function MJTestFormComponentExtended_Conditional_65_Template_select_ngModelChange_23_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.record.Status, $event) || (ctx_r0.record.Status = $event); return i0.ɵɵresetView($event); });
324
+ i0.ɵɵrepeaterCreate(24, MJTestFormComponentExtended_Conditional_65_For_25_Template, 2, 2, "option", 94, i0.ɵɵrepeaterTrackByIdentity);
325
325
  i0.ɵɵelementEnd()()();
326
- i0.ɵɵelementStart(26, "div", 89)(27, "label", 94);
326
+ i0.ɵɵelementStart(26, "div", 90)(27, "label", 95);
327
327
  i0.ɵɵtext(28, "Rubric");
328
328
  i0.ɵɵelementEnd();
329
- i0.ɵɵelementStart(29, "select", 95);
330
- i0.ɵɵlistener("ngModelChange", function MJTestFormComponentExtended_Conditional_64_Template_select_ngModelChange_29_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.RubricID = $event || null); });
331
- i0.ɵɵelementStart(30, "option", 93);
329
+ i0.ɵɵelementStart(29, "select", 96);
330
+ i0.ɵɵlistener("ngModelChange", function MJTestFormComponentExtended_Conditional_65_Template_select_ngModelChange_29_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.RubricID = $event || null); });
331
+ i0.ɵɵelementStart(30, "option", 94);
332
332
  i0.ɵɵtext(31, "\u2014 None \u2014");
333
333
  i0.ɵɵelementEnd();
334
- i0.ɵɵrepeaterCreate(32, MJTestFormComponentExtended_Conditional_64_For_33_Template, 2, 2, "option", 93, _forTrack0);
334
+ i0.ɵɵrepeaterCreate(32, MJTestFormComponentExtended_Conditional_65_For_33_Template, 2, 2, "option", 94, _forTrack0);
335
335
  i0.ɵɵelementEnd()();
336
- i0.ɵɵelementStart(34, "div", 89)(35, "label", 96);
336
+ i0.ɵɵelementStart(34, "div", 90)(35, "label", 97);
337
337
  i0.ɵɵtext(36, "Test Type");
338
338
  i0.ɵɵelementEnd();
339
- i0.ɵɵelementStart(37, "select", 97);
340
- i0.ɵɵtwoWayListener("ngModelChange", function MJTestFormComponentExtended_Conditional_64_Template_select_ngModelChange_37_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.record.TypeID, $event) || (ctx_r0.record.TypeID = $event); return i0.ɵɵresetView($event); });
341
- i0.ɵɵrepeaterCreate(38, MJTestFormComponentExtended_Conditional_64_For_39_Template, 2, 2, "option", 93, _forTrack1);
339
+ i0.ɵɵelementStart(37, "select", 98);
340
+ i0.ɵɵtwoWayListener("ngModelChange", function MJTestFormComponentExtended_Conditional_65_Template_select_ngModelChange_37_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.record.TypeID, $event) || (ctx_r0.record.TypeID = $event); return i0.ɵɵresetView($event); });
341
+ i0.ɵɵrepeaterCreate(38, MJTestFormComponentExtended_Conditional_65_For_39_Template, 2, 2, "option", 94, _forTrack1);
342
342
  i0.ɵɵelementEnd()();
343
- i0.ɵɵelementStart(40, "div", 83)(41, "label", 98);
343
+ i0.ɵɵelementStart(40, "div", 84)(41, "label", 99);
344
344
  i0.ɵɵtext(42, "Tags");
345
345
  i0.ɵɵelementEnd();
346
- i0.ɵɵelementStart(43, "div", 99);
347
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_64_Template_div_click_43_listener() { i0.ɵɵrestoreView(_r3); const tagInput_r7 = i0.ɵɵreference(47); return i0.ɵɵresetView(tagInput_r7.focus()); });
348
- i0.ɵɵrepeaterCreate(44, MJTestFormComponentExtended_Conditional_64_For_45_Template, 4, 2, "span", 100, i0.ɵɵrepeaterTrackByIdentity);
349
- i0.ɵɵelementStart(46, "input", 101, 0);
350
- i0.ɵɵtwoWayListener("ngModelChange", function MJTestFormComponentExtended_Conditional_64_Template_input_ngModelChange_46_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.tagDraft, $event) || (ctx_r0.tagDraft = $event); return i0.ɵɵresetView($event); });
351
- i0.ɵɵlistener("keydown", function MJTestFormComponentExtended_Conditional_64_Template_input_keydown_46_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onTagInputKeydown($event)); })("blur", function MJTestFormComponentExtended_Conditional_64_Template_input_blur_46_listener() { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.addTagFromDraft()); });
346
+ i0.ɵɵelementStart(43, "div", 100);
347
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_65_Template_div_click_43_listener() { i0.ɵɵrestoreView(_r3); const tagInput_r7 = i0.ɵɵreference(47); return i0.ɵɵresetView(tagInput_r7.focus()); });
348
+ i0.ɵɵrepeaterCreate(44, MJTestFormComponentExtended_Conditional_65_For_45_Template, 4, 2, "span", 101, i0.ɵɵrepeaterTrackByIdentity);
349
+ i0.ɵɵelementStart(46, "input", 102, 0);
350
+ i0.ɵɵtwoWayListener("ngModelChange", function MJTestFormComponentExtended_Conditional_65_Template_input_ngModelChange_46_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.tagDraft, $event) || (ctx_r0.tagDraft = $event); return i0.ɵɵresetView($event); });
351
+ i0.ɵɵlistener("keydown", function MJTestFormComponentExtended_Conditional_65_Template_input_keydown_46_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onTagInputKeydown($event)); })("blur", function MJTestFormComponentExtended_Conditional_65_Template_input_blur_46_listener() { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.addTagFromDraft()); });
352
352
  i0.ɵɵelementEnd()();
353
- i0.ɵɵelementStart(48, "span", 102);
353
+ i0.ɵɵelementStart(48, "span", 103);
354
354
  i0.ɵɵtext(49, "Press Enter or comma to add a tag. Backspace on empty input removes the last tag.");
355
355
  i0.ɵɵelementEnd()()()();
356
- i0.ɵɵelementStart(50, "section", 78)(51, "header", 79)(52, "h3");
357
- i0.ɵɵelement(53, "i", 103);
356
+ i0.ɵɵelementStart(50, "section", 79)(51, "header", 80)(52, "h3");
357
+ i0.ɵɵelement(53, "i", 104);
358
358
  i0.ɵɵtext(54, " Execution Settings");
359
359
  i0.ɵɵelementEnd()();
360
- i0.ɵɵelementStart(55, "div", 82)(56, "div", 89)(57, "label", 104);
360
+ i0.ɵɵelementStart(55, "div", 83)(56, "div", 90)(57, "label", 105);
361
361
  i0.ɵɵtext(58, "Priority");
362
362
  i0.ɵɵelementEnd();
363
- i0.ɵɵelementStart(59, "input", 105);
364
- i0.ɵɵlistener("ngModelChange", function MJTestFormComponentExtended_Conditional_64_Template_input_ngModelChange_59_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.Priority = $event === "" || $event === null ? null : +$event); });
363
+ i0.ɵɵelementStart(59, "input", 106);
364
+ i0.ɵɵlistener("ngModelChange", function MJTestFormComponentExtended_Conditional_65_Template_input_ngModelChange_59_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.Priority = $event === "" || $event === null ? null : +$event); });
365
365
  i0.ɵɵelementEnd();
366
- i0.ɵɵelementStart(60, "span", 102);
366
+ i0.ɵɵelementStart(60, "span", 103);
367
367
  i0.ɵɵtext(61, "Lower numbers run first.");
368
368
  i0.ɵɵelementEnd()();
369
- i0.ɵɵelementStart(62, "div", 89)(63, "label", 106);
369
+ i0.ɵɵelementStart(62, "div", 90)(63, "label", 107);
370
370
  i0.ɵɵtext(64, "Repeat Count");
371
371
  i0.ɵɵelementEnd();
372
- i0.ɵɵelementStart(65, "input", 107);
373
- i0.ɵɵlistener("ngModelChange", function MJTestFormComponentExtended_Conditional_64_Template_input_ngModelChange_65_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.RepeatCount = $event === "" || $event === null ? null : +$event); });
372
+ i0.ɵɵelementStart(65, "input", 108);
373
+ i0.ɵɵlistener("ngModelChange", function MJTestFormComponentExtended_Conditional_65_Template_input_ngModelChange_65_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.RepeatCount = $event === "" || $event === null ? null : +$event); });
374
374
  i0.ɵɵelementEnd();
375
- i0.ɵɵelementStart(66, "span", 102);
375
+ i0.ɵɵelementStart(66, "span", 103);
376
376
  i0.ɵɵtext(67, "Number of times to repeat for statistical analysis.");
377
377
  i0.ɵɵelementEnd()();
378
- i0.ɵɵelementStart(68, "div", 89)(69, "label", 108);
378
+ i0.ɵɵelementStart(68, "div", 90)(69, "label", 109);
379
379
  i0.ɵɵtext(70, "Estimated Duration (seconds)");
380
380
  i0.ɵɵelementEnd();
381
- i0.ɵɵelementStart(71, "input", 109);
382
- i0.ɵɵlistener("ngModelChange", function MJTestFormComponentExtended_Conditional_64_Template_input_ngModelChange_71_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.EstimatedDurationSeconds = $event === "" || $event === null ? null : +$event); });
381
+ i0.ɵɵelementStart(71, "input", 110);
382
+ i0.ɵɵlistener("ngModelChange", function MJTestFormComponentExtended_Conditional_65_Template_input_ngModelChange_71_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.EstimatedDurationSeconds = $event === "" || $event === null ? null : +$event); });
383
383
  i0.ɵɵelementEnd()();
384
- i0.ɵɵelementStart(72, "div", 89)(73, "label", 110);
384
+ i0.ɵɵelementStart(72, "div", 90)(73, "label", 111);
385
385
  i0.ɵɵtext(74, "Estimated Cost (USD)");
386
386
  i0.ɵɵelementEnd();
387
- i0.ɵɵelementStart(75, "input", 111);
388
- i0.ɵɵlistener("ngModelChange", function MJTestFormComponentExtended_Conditional_64_Template_input_ngModelChange_75_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.EstimatedCostUSD = $event === "" || $event === null ? null : +$event); });
387
+ i0.ɵɵelementStart(75, "input", 112);
388
+ i0.ɵɵlistener("ngModelChange", function MJTestFormComponentExtended_Conditional_65_Template_input_ngModelChange_75_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.EstimatedCostUSD = $event === "" || $event === null ? null : +$event); });
389
389
  i0.ɵɵelementEnd()();
390
- i0.ɵɵelementStart(76, "div", 83)(77, "label", 112);
390
+ i0.ɵɵelementStart(76, "div", 84)(77, "label", 113);
391
391
  i0.ɵɵtext(78, "Max Execution Time (ms)");
392
392
  i0.ɵɵelementEnd();
393
- i0.ɵɵelementStart(79, "input", 113);
394
- i0.ɵɵlistener("ngModelChange", function MJTestFormComponentExtended_Conditional_64_Template_input_ngModelChange_79_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.MaxExecutionTimeMS = $event === "" || $event === null ? null : +$event); });
393
+ i0.ɵɵelementStart(79, "input", 114);
394
+ i0.ɵɵlistener("ngModelChange", function MJTestFormComponentExtended_Conditional_65_Template_input_ngModelChange_79_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.MaxExecutionTimeMS = $event === "" || $event === null ? null : +$event); });
395
395
  i0.ɵɵelementEnd();
396
- i0.ɵɵelementStart(80, "span", 102);
396
+ i0.ɵɵelementStart(80, "span", 103);
397
397
  i0.ɵɵtext(81);
398
398
  i0.ɵɵelementEnd()()()();
399
- i0.ɵɵelementStart(82, "div", 114)(83, "h3");
400
- i0.ɵɵelement(84, "i", 72);
399
+ i0.ɵɵelementStart(82, "div", 115)(83, "h3");
400
+ i0.ɵɵelement(84, "i", 73);
401
401
  i0.ɵɵtext(85, " Input Definition (JSON)");
402
402
  i0.ɵɵelementEnd();
403
- i0.ɵɵelementStart(86, "div", 115)(87, "mj-code-editor", 116);
404
- i0.ɵɵlistener("change", function MJTestFormComponentExtended_Conditional_64_Template_mj_code_editor_change_87_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.InputDefinition = $event); });
403
+ i0.ɵɵelementStart(86, "div", 116)(87, "mj-code-editor", 117);
404
+ i0.ɵɵlistener("change", function MJTestFormComponentExtended_Conditional_65_Template_mj_code_editor_change_87_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.InputDefinition = $event); });
405
405
  i0.ɵɵelementEnd()()();
406
- i0.ɵɵelementStart(88, "div", 114)(89, "h3");
407
- i0.ɵɵelement(90, "i", 73);
406
+ i0.ɵɵelementStart(88, "div", 115)(89, "h3");
407
+ i0.ɵɵelement(90, "i", 74);
408
408
  i0.ɵɵtext(91, " Expected Outcomes (JSON)");
409
409
  i0.ɵɵelementEnd();
410
- i0.ɵɵelementStart(92, "div", 115)(93, "mj-code-editor", 116);
411
- i0.ɵɵlistener("change", function MJTestFormComponentExtended_Conditional_64_Template_mj_code_editor_change_93_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.ExpectedOutcomes = $event); });
410
+ i0.ɵɵelementStart(92, "div", 116)(93, "mj-code-editor", 117);
411
+ i0.ɵɵlistener("change", function MJTestFormComponentExtended_Conditional_65_Template_mj_code_editor_change_93_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.ExpectedOutcomes = $event); });
412
412
  i0.ɵɵelementEnd()()();
413
- i0.ɵɵelementStart(94, "div", 114)(95, "h3");
414
- i0.ɵɵelement(96, "i", 74);
413
+ i0.ɵɵelementStart(94, "div", 115)(95, "h3");
414
+ i0.ɵɵelement(96, "i", 75);
415
415
  i0.ɵɵtext(97, " Configuration (JSON)");
416
416
  i0.ɵɵelementEnd();
417
- i0.ɵɵelementStart(98, "div", 115)(99, "mj-code-editor", 116);
418
- i0.ɵɵlistener("change", function MJTestFormComponentExtended_Conditional_64_Template_mj_code_editor_change_99_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.Configuration = $event); });
417
+ i0.ɵɵelementStart(98, "div", 116)(99, "mj-code-editor", 117);
418
+ i0.ɵɵlistener("change", function MJTestFormComponentExtended_Conditional_65_Template_mj_code_editor_change_99_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.Configuration = $event); });
419
419
  i0.ɵɵelementEnd()()();
420
- i0.ɵɵelementStart(100, "section", 117)(101, "div", 118)(102, "div", 119)(103, "div", 120);
420
+ i0.ɵɵelementStart(100, "section", 118)(101, "div", 119)(102, "div", 120)(103, "div", 121);
421
421
  i0.ɵɵtext(104, "Created");
422
422
  i0.ɵɵelementEnd();
423
- i0.ɵɵelementStart(105, "div", 121);
423
+ i0.ɵɵelementStart(105, "div", 122);
424
424
  i0.ɵɵtext(106);
425
425
  i0.ɵɵpipe(107, "date");
426
426
  i0.ɵɵelementEnd()();
427
- i0.ɵɵelementStart(108, "div", 119)(109, "div", 120);
427
+ i0.ɵɵelementStart(108, "div", 120)(109, "div", 121);
428
428
  i0.ɵɵtext(110, "Last updated");
429
429
  i0.ɵɵelementEnd();
430
- i0.ɵɵelementStart(111, "div", 121);
430
+ i0.ɵɵelementStart(111, "div", 122);
431
431
  i0.ɵɵtext(112);
432
432
  i0.ɵɵpipe(113, "date");
433
433
  i0.ɵɵelementEnd()();
434
- i0.ɵɵelementStart(114, "div", 119)(115, "div", 120);
434
+ i0.ɵɵelementStart(114, "div", 120)(115, "div", 121);
435
435
  i0.ɵɵtext(116, "Test ID");
436
436
  i0.ɵɵelementEnd();
437
- i0.ɵɵelementStart(117, "div", 122);
437
+ i0.ɵɵelementStart(117, "div", 123);
438
438
  i0.ɵɵtext(118);
439
439
  i0.ɵɵelementEnd()()()()();
440
440
  } if (rf & 2) {
@@ -487,24 +487,24 @@ function MJTestFormComponentExtended_Conditional_64_Template(rf, ctx) { if (rf &
487
487
  i0.ɵɵadvance(6);
488
488
  i0.ɵɵtextInterpolate(ctx_r0.record.ID);
489
489
  } }
490
- function MJTestFormComponentExtended_Conditional_65_Conditional_1_For_3_Template(rf, ctx) { if (rf & 1) {
491
- i0.ɵɵelementStart(0, "div", 129);
492
- i0.ɵɵelement(1, "div", 130);
493
- i0.ɵɵelementStart(2, "div", 131);
494
- i0.ɵɵelement(3, "div", 132)(4, "div", 133);
490
+ function MJTestFormComponentExtended_Conditional_66_Conditional_1_For_3_Template(rf, ctx) { if (rf & 1) {
491
+ i0.ɵɵelementStart(0, "div", 130);
492
+ i0.ɵɵelement(1, "div", 131);
493
+ i0.ɵɵelementStart(2, "div", 132);
494
+ i0.ɵɵelement(3, "div", 133)(4, "div", 134);
495
495
  i0.ɵɵelementEnd()();
496
496
  } }
497
- function MJTestFormComponentExtended_Conditional_65_Conditional_1_Template(rf, ctx) { if (rf & 1) {
498
- i0.ɵɵelementStart(0, "div", 125)(1, "div", 128);
499
- i0.ɵɵrepeaterCreate(2, MJTestFormComponentExtended_Conditional_65_Conditional_1_For_3_Template, 5, 0, "div", 129, i0.ɵɵrepeaterTrackByIdentity);
497
+ function MJTestFormComponentExtended_Conditional_66_Conditional_1_Template(rf, ctx) { if (rf & 1) {
498
+ i0.ɵɵelementStart(0, "div", 126)(1, "div", 129);
499
+ i0.ɵɵrepeaterCreate(2, MJTestFormComponentExtended_Conditional_66_Conditional_1_For_3_Template, 5, 0, "div", 130, i0.ɵɵrepeaterTrackByIdentity);
500
500
  i0.ɵɵelementEnd()();
501
501
  } if (rf & 2) {
502
502
  i0.ɵɵadvance(2);
503
503
  i0.ɵɵrepeater(i0.ɵɵpureFunction0(0, _c0));
504
504
  } }
505
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_13_Template(rf, ctx) { if (rf & 1) {
505
+ function MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_13_Template(rf, ctx) { if (rf & 1) {
506
506
  i0.ɵɵelementStart(0, "span");
507
- i0.ɵɵelement(1, "i", 149);
507
+ i0.ɵɵelement(1, "i", 150);
508
508
  i0.ɵɵtext(2);
509
509
  i0.ɵɵelementEnd();
510
510
  } if (rf & 2) {
@@ -513,9 +513,9 @@ function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditio
513
513
  i0.ɵɵadvance(2);
514
514
  i0.ɵɵtextInterpolate1(" ", ctx_r0.formatDuration(run_r11.DurationSeconds));
515
515
  } }
516
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_14_Template(rf, ctx) { if (rf & 1) {
516
+ function MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_14_Template(rf, ctx) { if (rf & 1) {
517
517
  i0.ɵɵelementStart(0, "span");
518
- i0.ɵɵelement(1, "i", 150);
518
+ i0.ɵɵelement(1, "i", 151);
519
519
  i0.ɵɵtext(2);
520
520
  i0.ɵɵelementEnd();
521
521
  } if (rf & 2) {
@@ -524,15 +524,15 @@ function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditio
524
524
  i0.ɵɵadvance(2);
525
525
  i0.ɵɵtextInterpolate1(" ", ctx_r0.formatCost(run_r11.CostUSD));
526
526
  } }
527
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_15_Template(rf, ctx) { if (rf & 1) {
528
- i0.ɵɵelement(0, "mj-entity-link-pill", 144);
527
+ function MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_15_Template(rf, ctx) { if (rf & 1) {
528
+ i0.ɵɵelement(0, "mj-entity-link-pill", 145);
529
529
  } if (rf & 2) {
530
530
  const run_r11 = i0.ɵɵnextContext().$implicit;
531
531
  i0.ɵɵproperty("entityName", run_r11.TargetLogEntity)("recordId", run_r11.TargetLogID);
532
532
  } }
533
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_17_Template(rf, ctx) { if (rf & 1) {
534
- i0.ɵɵelementStart(0, "span", 146);
535
- i0.ɵɵelement(1, "i", 137);
533
+ function MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_17_Template(rf, ctx) { if (rf & 1) {
534
+ i0.ɵɵelementStart(0, "span", 147);
535
+ i0.ɵɵelement(1, "i", 138);
536
536
  i0.ɵɵelementStart(2, "span");
537
537
  i0.ɵɵtext(3);
538
538
  i0.ɵɵelementEnd()();
@@ -545,14 +545,14 @@ function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditio
545
545
  i0.ɵɵadvance(2);
546
546
  i0.ɵɵtextInterpolate(run_r11.Status);
547
547
  } }
548
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_18_Conditional_0_Template(rf, ctx) { if (rf & 1) {
549
- i0.ɵɵelementStart(0, "span", 151);
550
- i0.ɵɵelement(1, "i", 153);
548
+ function MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_18_Conditional_0_Template(rf, ctx) { if (rf & 1) {
549
+ i0.ɵɵelementStart(0, "span", 152);
550
+ i0.ɵɵelement(1, "i", 154);
551
551
  i0.ɵɵelementEnd();
552
552
  } }
553
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_18_Conditional_1_Template(rf, ctx) { if (rf & 1) {
554
- i0.ɵɵelementStart(0, "span", 154);
555
- i0.ɵɵelement(1, "i", 155);
553
+ function MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_18_Conditional_1_Template(rf, ctx) { if (rf & 1) {
554
+ i0.ɵɵelementStart(0, "span", 155);
555
+ i0.ɵɵelement(1, "i", 156);
556
556
  i0.ɵɵelementStart(2, "span");
557
557
  i0.ɵɵtext(3);
558
558
  i0.ɵɵelementEnd()();
@@ -566,9 +566,9 @@ function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditio
566
566
  i0.ɵɵadvance(3);
567
567
  i0.ɵɵtextInterpolate(rating_r12);
568
568
  } }
569
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_18_Template(rf, ctx) { if (rf & 1) {
570
- i0.ɵɵconditionalCreate(0, MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_18_Conditional_0_Template, 2, 0, "span", 151);
571
- i0.ɵɵconditionalCreate(1, MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_18_Conditional_1_Template, 4, 10, "span", 152);
569
+ function MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_18_Template(rf, ctx) { if (rf & 1) {
570
+ i0.ɵɵconditionalCreate(0, MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_18_Conditional_0_Template, 2, 0, "span", 152);
571
+ i0.ɵɵconditionalCreate(1, MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_18_Conditional_1_Template, 4, 10, "span", 153);
572
572
  } if (rf & 2) {
573
573
  let tmp_13_0;
574
574
  let tmp_14_0;
@@ -578,14 +578,14 @@ function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditio
578
578
  i0.ɵɵadvance();
579
579
  i0.ɵɵconditional((tmp_14_0 = (tmp_14_0 = ctx_r0.getFeedbackForRun(run_r11.ID)) == null ? null : tmp_14_0.Rating) ? 1 : -1, tmp_14_0);
580
580
  } }
581
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_19_Conditional_0_Template(rf, ctx) { if (rf & 1) {
582
- i0.ɵɵelementStart(0, "span", 156);
583
- i0.ɵɵelement(1, "i", 158);
581
+ function MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_19_Conditional_0_Template(rf, ctx) { if (rf & 1) {
582
+ i0.ɵɵelementStart(0, "span", 157);
583
+ i0.ɵɵelement(1, "i", 159);
584
584
  i0.ɵɵelementEnd();
585
585
  } }
586
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_19_Conditional_1_Template(rf, ctx) { if (rf & 1) {
587
- i0.ɵɵelementStart(0, "span", 159);
588
- i0.ɵɵelement(1, "i", 158);
586
+ function MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_19_Conditional_1_Template(rf, ctx) { if (rf & 1) {
587
+ i0.ɵɵelementStart(0, "span", 160);
588
+ i0.ɵɵelement(1, "i", 159);
589
589
  i0.ɵɵelementStart(2, "span");
590
590
  i0.ɵɵtext(3);
591
591
  i0.ɵɵelementEnd()();
@@ -596,17 +596,17 @@ function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditio
596
596
  i0.ɵɵadvance(3);
597
597
  i0.ɵɵtextInterpolate1("", (run_r11.Score * 100).toFixed(0), "%");
598
598
  } }
599
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_19_Template(rf, ctx) { if (rf & 1) {
600
- i0.ɵɵconditionalCreate(0, MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_19_Conditional_0_Template, 2, 0, "span", 156);
601
- i0.ɵɵconditionalCreate(1, MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_19_Conditional_1_Template, 4, 10, "span", 157);
599
+ function MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_19_Template(rf, ctx) { if (rf & 1) {
600
+ i0.ɵɵconditionalCreate(0, MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_19_Conditional_0_Template, 2, 0, "span", 157);
601
+ i0.ɵɵconditionalCreate(1, MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_19_Conditional_1_Template, 4, 10, "span", 158);
602
602
  } if (rf & 2) {
603
603
  const run_r11 = i0.ɵɵnextContext().$implicit;
604
604
  i0.ɵɵconditional(run_r11.Score == null ? 0 : -1);
605
605
  i0.ɵɵadvance();
606
606
  i0.ɵɵconditional(run_r11.Score != null ? 1 : -1);
607
607
  } }
608
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_20_For_2_Template(rf, ctx) { if (rf & 1) {
609
- i0.ɵɵelementStart(0, "span", 160);
608
+ function MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_20_For_2_Template(rf, ctx) { if (rf & 1) {
609
+ i0.ɵɵelementStart(0, "span", 161);
610
610
  i0.ɵɵtext(1);
611
611
  i0.ɵɵelementEnd();
612
612
  } if (rf & 2) {
@@ -614,8 +614,8 @@ function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditio
614
614
  i0.ɵɵadvance();
615
615
  i0.ɵɵtextInterpolate(tag_r13);
616
616
  } }
617
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_20_Conditional_3_Template(rf, ctx) { if (rf & 1) {
618
- i0.ɵɵelementStart(0, "span", 161);
617
+ function MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_20_Conditional_3_Template(rf, ctx) { if (rf & 1) {
618
+ i0.ɵɵelementStart(0, "span", 162);
619
619
  i0.ɵɵtext(1);
620
620
  i0.ɵɵelementEnd();
621
621
  } if (rf & 2) {
@@ -624,10 +624,10 @@ function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditio
624
624
  i0.ɵɵadvance();
625
625
  i0.ɵɵtextInterpolate1("+", ctx_r0.getRunTags(run_r11).length - 3);
626
626
  } }
627
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_20_Template(rf, ctx) { if (rf & 1) {
628
- i0.ɵɵelementStart(0, "div", 147);
629
- i0.ɵɵrepeaterCreate(1, MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_20_For_2_Template, 2, 1, "span", 160, i0.ɵɵrepeaterTrackByIdentity);
630
- i0.ɵɵconditionalCreate(3, MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_20_Conditional_3_Template, 2, 1, "span", 161);
627
+ function MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_20_Template(rf, ctx) { if (rf & 1) {
628
+ i0.ɵɵelementStart(0, "div", 148);
629
+ i0.ɵɵrepeaterCreate(1, MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_20_For_2_Template, 2, 1, "span", 161, i0.ɵɵrepeaterTrackByIdentity);
630
+ i0.ɵɵconditionalCreate(3, MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_20_Conditional_3_Template, 2, 1, "span", 162);
631
631
  i0.ɵɵelementEnd();
632
632
  } if (rf & 2) {
633
633
  const run_r11 = i0.ɵɵnextContext().$implicit;
@@ -637,35 +637,35 @@ function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditio
637
637
  i0.ɵɵadvance(2);
638
638
  i0.ɵɵconditional(ctx_r0.getRunTags(run_r11).length > 3 ? 3 : -1);
639
639
  } }
640
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Template(rf, ctx) { if (rf & 1) {
640
+ function MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Template(rf, ctx) { if (rf & 1) {
641
641
  const _r10 = i0.ɵɵgetCurrentView();
642
- i0.ɵɵelementStart(0, "div", 135);
643
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Template_div_click_0_listener() { const run_r11 = i0.ɵɵrestoreView(_r10).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.openTestRun(run_r11.ID)); });
644
- i0.ɵɵelementStart(1, "div", 136);
645
- i0.ɵɵelement(2, "i", 137);
642
+ i0.ɵɵelementStart(0, "div", 136);
643
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Template_div_click_0_listener() { const run_r11 = i0.ɵɵrestoreView(_r10).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.openTestRun(run_r11.ID)); });
644
+ i0.ɵɵelementStart(1, "div", 137);
645
+ i0.ɵɵelement(2, "i", 138);
646
646
  i0.ɵɵelementEnd();
647
- i0.ɵɵelementStart(3, "div", 138)(4, "div", 139)(5, "span", 140);
647
+ i0.ɵɵelementStart(3, "div", 139)(4, "div", 140)(5, "span", 141);
648
648
  i0.ɵɵtext(6);
649
649
  i0.ɵɵelementEnd();
650
- i0.ɵɵelementStart(7, "span", 141);
650
+ i0.ɵɵelementStart(7, "span", 142);
651
651
  i0.ɵɵtext(8);
652
652
  i0.ɵɵelementEnd()();
653
- i0.ɵɵelementStart(9, "div", 142)(10, "span");
654
- i0.ɵɵelement(11, "i", 143);
653
+ i0.ɵɵelementStart(9, "div", 143)(10, "span");
654
+ i0.ɵɵelement(11, "i", 144);
655
655
  i0.ɵɵtext(12);
656
656
  i0.ɵɵelementEnd();
657
- i0.ɵɵconditionalCreate(13, MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_13_Template, 3, 1, "span");
658
- i0.ɵɵconditionalCreate(14, MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_14_Template, 3, 1, "span");
659
- i0.ɵɵconditionalCreate(15, MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_15_Template, 1, 2, "mj-entity-link-pill", 144);
657
+ i0.ɵɵconditionalCreate(13, MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_13_Template, 3, 1, "span");
658
+ i0.ɵɵconditionalCreate(14, MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_14_Template, 3, 1, "span");
659
+ i0.ɵɵconditionalCreate(15, MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_15_Template, 1, 2, "mj-entity-link-pill", 145);
660
660
  i0.ɵɵelementEnd();
661
- i0.ɵɵelementStart(16, "div", 145);
662
- i0.ɵɵconditionalCreate(17, MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_17_Template, 4, 17, "span", 146);
663
- i0.ɵɵconditionalCreate(18, MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_18_Template, 2, 2);
664
- i0.ɵɵconditionalCreate(19, MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_19_Template, 2, 2);
661
+ i0.ɵɵelementStart(16, "div", 146);
662
+ i0.ɵɵconditionalCreate(17, MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_17_Template, 4, 17, "span", 147);
663
+ i0.ɵɵconditionalCreate(18, MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_18_Template, 2, 2);
664
+ i0.ɵɵconditionalCreate(19, MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_19_Template, 2, 2);
665
665
  i0.ɵɵelementEnd();
666
- i0.ɵɵconditionalCreate(20, MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_20_Template, 4, 1, "div", 147);
666
+ i0.ɵɵconditionalCreate(20, MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_20_Template, 4, 1, "div", 148);
667
667
  i0.ɵɵelementEnd();
668
- i0.ɵɵelement(21, "i", 148);
668
+ i0.ɵɵelement(21, "i", 149);
669
669
  i0.ɵɵelementEnd();
670
670
  } if (rf & 2) {
671
671
  const run_r11 = ctx.$implicit;
@@ -697,26 +697,26 @@ function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Template
697
697
  i0.ɵɵadvance();
698
698
  i0.ɵɵconditional(ctx_r0.getRunTags(run_r11).length > 0 ? 20 : -1);
699
699
  } }
700
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_Template(rf, ctx) { if (rf & 1) {
701
- i0.ɵɵelementStart(0, "div", 126);
702
- i0.ɵɵrepeaterCreate(1, MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Template, 22, 26, "div", 134, i0.ɵɵrepeaterTrackByIdentity);
700
+ function MJTestFormComponentExtended_Conditional_66_Conditional_2_Template(rf, ctx) { if (rf & 1) {
701
+ i0.ɵɵelementStart(0, "div", 127);
702
+ i0.ɵɵrepeaterCreate(1, MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Template, 22, 26, "div", 135, i0.ɵɵrepeaterTrackByIdentity);
703
703
  i0.ɵɵelementEnd();
704
704
  } if (rf & 2) {
705
705
  const ctx_r0 = i0.ɵɵnextContext(2);
706
706
  i0.ɵɵadvance();
707
707
  i0.ɵɵrepeater(ctx_r0.testRuns);
708
708
  } }
709
- function MJTestFormComponentExtended_Conditional_65_Conditional_3_Template(rf, ctx) { if (rf & 1) {
709
+ function MJTestFormComponentExtended_Conditional_66_Conditional_3_Template(rf, ctx) { if (rf & 1) {
710
710
  const _r14 = i0.ɵɵgetCurrentView();
711
- i0.ɵɵelementStart(0, "mj-empty-state", 162);
712
- i0.ɵɵlistener("Action", function MJTestFormComponentExtended_Conditional_65_Conditional_3_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r14); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.runTest()); });
711
+ i0.ɵɵelementStart(0, "mj-empty-state", 163);
712
+ i0.ɵɵlistener("Action", function MJTestFormComponentExtended_Conditional_66_Conditional_3_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r14); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.runTest()); });
713
713
  i0.ɵɵelementEnd();
714
714
  } }
715
- function MJTestFormComponentExtended_Conditional_65_Template(rf, ctx) { if (rf & 1) {
716
- i0.ɵɵelementStart(0, "div", 38);
717
- i0.ɵɵconditionalCreate(1, MJTestFormComponentExtended_Conditional_65_Conditional_1_Template, 4, 1, "div", 125);
718
- i0.ɵɵconditionalCreate(2, MJTestFormComponentExtended_Conditional_65_Conditional_2_Template, 3, 0, "div", 126);
719
- i0.ɵɵconditionalCreate(3, MJTestFormComponentExtended_Conditional_65_Conditional_3_Template, 1, 0, "mj-empty-state", 127);
715
+ function MJTestFormComponentExtended_Conditional_66_Template(rf, ctx) { if (rf & 1) {
716
+ i0.ɵɵelementStart(0, "div", 39);
717
+ i0.ɵɵconditionalCreate(1, MJTestFormComponentExtended_Conditional_66_Conditional_1_Template, 4, 1, "div", 126);
718
+ i0.ɵɵconditionalCreate(2, MJTestFormComponentExtended_Conditional_66_Conditional_2_Template, 3, 0, "div", 127);
719
+ i0.ɵɵconditionalCreate(3, MJTestFormComponentExtended_Conditional_66_Conditional_3_Template, 1, 0, "mj-empty-state", 128);
720
720
  i0.ɵɵelementEnd();
721
721
  } if (rf & 2) {
722
722
  const ctx_r0 = i0.ɵɵnextContext();
@@ -727,24 +727,24 @@ function MJTestFormComponentExtended_Conditional_65_Template(rf, ctx) { if (rf &
727
727
  i0.ɵɵadvance();
728
728
  i0.ɵɵconditional(ctx_r0.testRunsLoaded && !ctx_r0.loadingRuns && ctx_r0.testRuns.length === 0 ? 3 : -1);
729
729
  } }
730
- function MJTestFormComponentExtended_Conditional_66_Conditional_1_For_3_Template(rf, ctx) { if (rf & 1) {
731
- i0.ɵɵelementStart(0, "div", 129);
732
- i0.ɵɵelement(1, "div", 130);
733
- i0.ɵɵelementStart(2, "div", 131);
734
- i0.ɵɵelement(3, "div", 132)(4, "div", 133);
730
+ function MJTestFormComponentExtended_Conditional_67_Conditional_1_For_3_Template(rf, ctx) { if (rf & 1) {
731
+ i0.ɵɵelementStart(0, "div", 130);
732
+ i0.ɵɵelement(1, "div", 131);
733
+ i0.ɵɵelementStart(2, "div", 132);
734
+ i0.ɵɵelement(3, "div", 133)(4, "div", 134);
735
735
  i0.ɵɵelementEnd()();
736
736
  } }
737
- function MJTestFormComponentExtended_Conditional_66_Conditional_1_Template(rf, ctx) { if (rf & 1) {
738
- i0.ɵɵelementStart(0, "div", 125)(1, "div", 128);
739
- i0.ɵɵrepeaterCreate(2, MJTestFormComponentExtended_Conditional_66_Conditional_1_For_3_Template, 5, 0, "div", 129, i0.ɵɵrepeaterTrackByIdentity);
737
+ function MJTestFormComponentExtended_Conditional_67_Conditional_1_Template(rf, ctx) { if (rf & 1) {
738
+ i0.ɵɵelementStart(0, "div", 126)(1, "div", 129);
739
+ i0.ɵɵrepeaterCreate(2, MJTestFormComponentExtended_Conditional_67_Conditional_1_For_3_Template, 5, 0, "div", 130, i0.ɵɵrepeaterTrackByIdentity);
740
740
  i0.ɵɵelementEnd()();
741
741
  } if (rf & 2) {
742
742
  i0.ɵɵadvance(2);
743
743
  i0.ɵɵrepeater(i0.ɵɵpureFunction0(0, _c1));
744
744
  } }
745
- function MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_10_Template(rf, ctx) { if (rf & 1) {
745
+ function MJTestFormComponentExtended_Conditional_67_Conditional_2_For_2_Conditional_10_Template(rf, ctx) { if (rf & 1) {
746
746
  i0.ɵɵelementStart(0, "span");
747
- i0.ɵɵelement(1, "i", 62);
747
+ i0.ɵɵelement(1, "i", 63);
748
748
  i0.ɵɵtext(2);
749
749
  i0.ɵɵelementEnd();
750
750
  } if (rf & 2) {
@@ -752,23 +752,23 @@ function MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditio
752
752
  i0.ɵɵadvance(2);
753
753
  i0.ɵɵtextInterpolate1(" ", suiteTest_r16.Status);
754
754
  } }
755
- function MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Template(rf, ctx) { if (rf & 1) {
755
+ function MJTestFormComponentExtended_Conditional_67_Conditional_2_For_2_Template(rf, ctx) { if (rf & 1) {
756
756
  const _r15 = i0.ɵɵgetCurrentView();
757
- i0.ɵɵelementStart(0, "div", 166);
758
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Template_div_click_0_listener() { const suiteTest_r16 = i0.ɵɵrestoreView(_r15).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.openTestSuite(suiteTest_r16.SuiteID)); });
759
- i0.ɵɵelementStart(1, "div", 167);
760
- i0.ɵɵelement(2, "i", 33);
757
+ i0.ɵɵelementStart(0, "div", 167);
758
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_67_Conditional_2_For_2_Template_div_click_0_listener() { const suiteTest_r16 = i0.ɵɵrestoreView(_r15).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.openTestSuite(suiteTest_r16.SuiteID)); });
759
+ i0.ɵɵelementStart(1, "div", 168);
760
+ i0.ɵɵelement(2, "i", 34);
761
761
  i0.ɵɵelementEnd();
762
- i0.ɵɵelementStart(3, "div", 168)(4, "div", 169);
762
+ i0.ɵɵelementStart(3, "div", 169)(4, "div", 170);
763
763
  i0.ɵɵtext(5);
764
764
  i0.ɵɵelementEnd();
765
- i0.ɵɵelementStart(6, "div", 170)(7, "span");
766
- i0.ɵɵelement(8, "i", 171);
765
+ i0.ɵɵelementStart(6, "div", 171)(7, "span");
766
+ i0.ɵɵelement(8, "i", 172);
767
767
  i0.ɵɵtext(9);
768
768
  i0.ɵɵelementEnd();
769
- i0.ɵɵconditionalCreate(10, MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_10_Template, 3, 1, "span");
769
+ i0.ɵɵconditionalCreate(10, MJTestFormComponentExtended_Conditional_67_Conditional_2_For_2_Conditional_10_Template, 3, 1, "span");
770
770
  i0.ɵɵelementEnd()();
771
- i0.ɵɵelement(11, "i", 148);
771
+ i0.ɵɵelement(11, "i", 149);
772
772
  i0.ɵɵelementEnd();
773
773
  } if (rf & 2) {
774
774
  const suiteTest_r16 = ctx.$implicit;
@@ -779,23 +779,23 @@ function MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Template
779
779
  i0.ɵɵadvance();
780
780
  i0.ɵɵconditional(suiteTest_r16.Status ? 10 : -1);
781
781
  } }
782
- function MJTestFormComponentExtended_Conditional_66_Conditional_2_Template(rf, ctx) { if (rf & 1) {
783
- i0.ɵɵelementStart(0, "div", 163);
784
- i0.ɵɵrepeaterCreate(1, MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Template, 12, 3, "div", 165, i0.ɵɵrepeaterTrackByIdentity);
782
+ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Template(rf, ctx) { if (rf & 1) {
783
+ i0.ɵɵelementStart(0, "div", 164);
784
+ i0.ɵɵrepeaterCreate(1, MJTestFormComponentExtended_Conditional_67_Conditional_2_For_2_Template, 12, 3, "div", 166, i0.ɵɵrepeaterTrackByIdentity);
785
785
  i0.ɵɵelementEnd();
786
786
  } if (rf & 2) {
787
787
  const ctx_r0 = i0.ɵɵnextContext(2);
788
788
  i0.ɵɵadvance();
789
789
  i0.ɵɵrepeater(ctx_r0.suiteTests);
790
790
  } }
791
- function MJTestFormComponentExtended_Conditional_66_Conditional_3_Template(rf, ctx) { if (rf & 1) {
792
- i0.ɵɵelement(0, "mj-empty-state", 164);
791
+ function MJTestFormComponentExtended_Conditional_67_Conditional_3_Template(rf, ctx) { if (rf & 1) {
792
+ i0.ɵɵelement(0, "mj-empty-state", 165);
793
793
  } }
794
- function MJTestFormComponentExtended_Conditional_66_Template(rf, ctx) { if (rf & 1) {
795
- i0.ɵɵelementStart(0, "div", 39);
796
- i0.ɵɵconditionalCreate(1, MJTestFormComponentExtended_Conditional_66_Conditional_1_Template, 4, 1, "div", 125);
797
- i0.ɵɵconditionalCreate(2, MJTestFormComponentExtended_Conditional_66_Conditional_2_Template, 3, 0, "div", 163);
798
- i0.ɵɵconditionalCreate(3, MJTestFormComponentExtended_Conditional_66_Conditional_3_Template, 1, 0, "mj-empty-state", 164);
794
+ function MJTestFormComponentExtended_Conditional_67_Template(rf, ctx) { if (rf & 1) {
795
+ i0.ɵɵelementStart(0, "div", 40);
796
+ i0.ɵɵconditionalCreate(1, MJTestFormComponentExtended_Conditional_67_Conditional_1_Template, 4, 1, "div", 126);
797
+ i0.ɵɵconditionalCreate(2, MJTestFormComponentExtended_Conditional_67_Conditional_2_Template, 3, 0, "div", 164);
798
+ i0.ɵɵconditionalCreate(3, MJTestFormComponentExtended_Conditional_67_Conditional_3_Template, 1, 0, "mj-empty-state", 165);
799
799
  i0.ɵɵelementEnd();
800
800
  } if (rf & 2) {
801
801
  const ctx_r0 = i0.ɵɵnextContext();
@@ -806,20 +806,20 @@ function MJTestFormComponentExtended_Conditional_66_Template(rf, ctx) { if (rf &
806
806
  i0.ɵɵadvance();
807
807
  i0.ɵɵconditional(ctx_r0.suiteTestsLoaded && !ctx_r0.loadingSuites && ctx_r0.suiteTests.length === 0 ? 3 : -1);
808
808
  } }
809
- function MJTestFormComponentExtended_Conditional_67_Conditional_1_Template(rf, ctx) { if (rf & 1) {
810
- i0.ɵɵelementStart(0, "div", 125);
811
- i0.ɵɵelement(1, "mj-loading", 173);
809
+ function MJTestFormComponentExtended_Conditional_68_Conditional_1_Template(rf, ctx) { if (rf & 1) {
810
+ i0.ɵɵelementStart(0, "div", 126);
811
+ i0.ɵɵelement(1, "mj-loading", 174);
812
812
  i0.ɵɵelementEnd();
813
813
  } }
814
- function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_17_Conditional_9_Template(rf, ctx) { if (rf & 1) {
815
- i0.ɵɵelementStart(0, "div", 183)(1, "div", 189);
816
- i0.ɵɵelement(2, "i", 190);
814
+ function MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_17_Conditional_9_Template(rf, ctx) { if (rf & 1) {
815
+ i0.ɵɵelementStart(0, "div", 184)(1, "div", 190);
816
+ i0.ɵɵelement(2, "i", 191);
817
817
  i0.ɵɵelementEnd();
818
- i0.ɵɵelementStart(3, "div", 186)(4, "div", 187);
818
+ i0.ɵɵelementStart(3, "div", 187)(4, "div", 188);
819
819
  i0.ɵɵtext(5);
820
- i0.ɵɵelement(6, "i", 191);
820
+ i0.ɵɵelement(6, "i", 192);
821
821
  i0.ɵɵelementEnd();
822
- i0.ɵɵelementStart(7, "div", 188);
822
+ i0.ɵɵelementStart(7, "div", 189);
823
823
  i0.ɵɵtext(8, "Pass Rate");
824
824
  i0.ɵɵelementEnd()()();
825
825
  } if (rf & 2) {
@@ -829,14 +829,14 @@ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_17
829
829
  i0.ɵɵadvance();
830
830
  i0.ɵɵclassProp("fa-arrow-up", ctx_r0.getPassRateTrend() === "up")("fa-arrow-down", ctx_r0.getPassRateTrend() === "down")("fa-minus", ctx_r0.getPassRateTrend() === "stable")("trend-up", ctx_r0.getPassRateTrend() === "up")("trend-down", ctx_r0.getPassRateTrend() === "down");
831
831
  } }
832
- function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_17_Conditional_10_Template(rf, ctx) { if (rf & 1) {
833
- i0.ɵɵelementStart(0, "div", 183)(1, "div", 184);
834
- i0.ɵɵelement(2, "i", 192);
832
+ function MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_17_Conditional_10_Template(rf, ctx) { if (rf & 1) {
833
+ i0.ɵɵelementStart(0, "div", 184)(1, "div", 185);
834
+ i0.ɵɵelement(2, "i", 193);
835
835
  i0.ɵɵelementEnd();
836
- i0.ɵɵelementStart(3, "div", 186)(4, "div", 187);
836
+ i0.ɵɵelementStart(3, "div", 187)(4, "div", 188);
837
837
  i0.ɵɵtext(5);
838
838
  i0.ɵɵelementEnd();
839
- i0.ɵɵelementStart(6, "div", 188);
839
+ i0.ɵɵelementStart(6, "div", 189);
840
840
  i0.ɵɵtext(7, "Avg Score");
841
841
  i0.ɵɵelementEnd()()();
842
842
  } if (rf & 2) {
@@ -844,34 +844,34 @@ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_17
844
844
  i0.ɵɵadvance(5);
845
845
  i0.ɵɵtextInterpolate1("", (ctx_r0.getOverallAvgScore() * 100).toFixed(1), "%");
846
846
  } }
847
- function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_17_Template(rf, ctx) { if (rf & 1) {
848
- i0.ɵɵelementStart(0, "div", 180)(1, "div", 183)(2, "div", 184);
849
- i0.ɵɵelement(3, "i", 185);
847
+ function MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_17_Template(rf, ctx) { if (rf & 1) {
848
+ i0.ɵɵelementStart(0, "div", 181)(1, "div", 184)(2, "div", 185);
849
+ i0.ɵɵelement(3, "i", 186);
850
850
  i0.ɵɵelementEnd();
851
- i0.ɵɵelementStart(4, "div", 186)(5, "div", 187);
851
+ i0.ɵɵelementStart(4, "div", 187)(5, "div", 188);
852
852
  i0.ɵɵtext(6);
853
853
  i0.ɵɵelementEnd();
854
- i0.ɵɵelementStart(7, "div", 188);
854
+ i0.ɵɵelementStart(7, "div", 189);
855
855
  i0.ɵɵtext(8, "Total Runs");
856
856
  i0.ɵɵelementEnd()()();
857
- i0.ɵɵconditionalCreate(9, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_17_Conditional_9_Template, 9, 11, "div", 183);
858
- i0.ɵɵconditionalCreate(10, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_17_Conditional_10_Template, 8, 1, "div", 183);
859
- i0.ɵɵelementStart(11, "div", 183)(12, "div", 184);
860
- i0.ɵɵelement(13, "i", 149);
857
+ i0.ɵɵconditionalCreate(9, MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_17_Conditional_9_Template, 9, 11, "div", 184);
858
+ i0.ɵɵconditionalCreate(10, MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_17_Conditional_10_Template, 8, 1, "div", 184);
859
+ i0.ɵɵelementStart(11, "div", 184)(12, "div", 185);
860
+ i0.ɵɵelement(13, "i", 150);
861
861
  i0.ɵɵelementEnd();
862
- i0.ɵɵelementStart(14, "div", 186)(15, "div", 187);
862
+ i0.ɵɵelementStart(14, "div", 187)(15, "div", 188);
863
863
  i0.ɵɵtext(16);
864
864
  i0.ɵɵelementEnd();
865
- i0.ɵɵelementStart(17, "div", 188);
865
+ i0.ɵɵelementStart(17, "div", 189);
866
866
  i0.ɵɵtext(18, "Avg Duration");
867
867
  i0.ɵɵelementEnd()()();
868
- i0.ɵɵelementStart(19, "div", 183)(20, "div", 184);
869
- i0.ɵɵelement(21, "i", 150);
868
+ i0.ɵɵelementStart(19, "div", 184)(20, "div", 185);
869
+ i0.ɵɵelement(21, "i", 151);
870
870
  i0.ɵɵelementEnd();
871
- i0.ɵɵelementStart(22, "div", 186)(23, "div", 187);
871
+ i0.ɵɵelementStart(22, "div", 187)(23, "div", 188);
872
872
  i0.ɵɵtext(24);
873
873
  i0.ɵɵelementEnd();
874
- i0.ɵɵelementStart(25, "div", 188);
874
+ i0.ɵɵelementStart(25, "div", 189);
875
875
  i0.ɵɵtext(26, "Avg Cost");
876
876
  i0.ɵɵelementEnd()()()();
877
877
  } if (rf & 2) {
@@ -887,28 +887,28 @@ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_17
887
887
  i0.ɵɵadvance(8);
888
888
  i0.ɵɵtextInterpolate(ctx_r0.formatCost(ctx_r0.getOverallAvgCost()));
889
889
  } }
890
- function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_Conditional_12_Template(rf, ctx) { if (rf & 1) {
890
+ function MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_18_Conditional_12_Template(rf, ctx) { if (rf & 1) {
891
891
  i0.ɵɵelementStart(0, "th");
892
892
  i0.ɵɵtext(1, "Passed");
893
893
  i0.ɵɵelementEnd();
894
894
  } }
895
- function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_Conditional_13_Template(rf, ctx) { if (rf & 1) {
895
+ function MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_18_Conditional_13_Template(rf, ctx) { if (rf & 1) {
896
896
  i0.ɵɵelementStart(0, "th");
897
897
  i0.ɵɵtext(1, "Failed");
898
898
  i0.ɵɵelementEnd();
899
899
  } }
900
- function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_Conditional_14_Template(rf, ctx) { if (rf & 1) {
900
+ function MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_18_Conditional_14_Template(rf, ctx) { if (rf & 1) {
901
901
  i0.ɵɵelementStart(0, "th");
902
902
  i0.ɵɵtext(1, "Pass Rate");
903
903
  i0.ɵɵelementEnd();
904
904
  } }
905
- function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_Conditional_15_Template(rf, ctx) { if (rf & 1) {
905
+ function MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_18_Conditional_15_Template(rf, ctx) { if (rf & 1) {
906
906
  i0.ɵɵelementStart(0, "th");
907
907
  i0.ɵɵtext(1, "Avg Score");
908
908
  i0.ɵɵelementEnd();
909
909
  } }
910
- function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_For_22_Conditional_6_Template(rf, ctx) { if (rf & 1) {
911
- i0.ɵɵelementStart(0, "td", 198);
910
+ function MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_18_For_22_Conditional_6_Template(rf, ctx) { if (rf & 1) {
911
+ i0.ɵɵelementStart(0, "td", 199);
912
912
  i0.ɵɵtext(1);
913
913
  i0.ɵɵelementEnd();
914
914
  } if (rf & 2) {
@@ -916,8 +916,8 @@ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18
916
916
  i0.ɵɵadvance();
917
917
  i0.ɵɵtextInterpolate(day_r18.passCount);
918
918
  } }
919
- function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_For_22_Conditional_7_Template(rf, ctx) { if (rf & 1) {
920
- i0.ɵɵelementStart(0, "td", 199);
919
+ function MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_18_For_22_Conditional_7_Template(rf, ctx) { if (rf & 1) {
920
+ i0.ɵɵelementStart(0, "td", 200);
921
921
  i0.ɵɵtext(1);
922
922
  i0.ɵɵelementEnd();
923
923
  } if (rf & 2) {
@@ -925,10 +925,10 @@ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18
925
925
  i0.ɵɵadvance();
926
926
  i0.ɵɵtextInterpolate(day_r18.failCount);
927
927
  } }
928
- function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_For_22_Conditional_8_Template(rf, ctx) { if (rf & 1) {
929
- i0.ɵɵelementStart(0, "td", 200)(1, "div", 204);
930
- i0.ɵɵelement(2, "div", 205);
931
- i0.ɵɵelementStart(3, "span", 206);
928
+ function MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_18_For_22_Conditional_8_Template(rf, ctx) { if (rf & 1) {
929
+ i0.ɵɵelementStart(0, "td", 201)(1, "div", 205);
930
+ i0.ɵɵelement(2, "div", 206);
931
+ i0.ɵɵelementStart(3, "span", 207);
932
932
  i0.ɵɵtext(4);
933
933
  i0.ɵɵelementEnd()()();
934
934
  } if (rf & 2) {
@@ -938,8 +938,8 @@ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18
938
938
  i0.ɵɵadvance(2);
939
939
  i0.ɵɵtextInterpolate1("", day_r18.passRate.toFixed(1), "%");
940
940
  } }
941
- function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_For_22_Conditional_9_Template(rf, ctx) { if (rf & 1) {
942
- i0.ɵɵelementStart(0, "td", 201);
941
+ function MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_18_For_22_Conditional_9_Template(rf, ctx) { if (rf & 1) {
942
+ i0.ɵɵelementStart(0, "td", 202);
943
943
  i0.ɵɵtext(1);
944
944
  i0.ɵɵelementEnd();
945
945
  } if (rf & 2) {
@@ -947,22 +947,22 @@ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18
947
947
  i0.ɵɵadvance();
948
948
  i0.ɵɵtextInterpolate1("", (day_r18.avgScore * 100).toFixed(1), "%");
949
949
  } }
950
- function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_For_22_Template(rf, ctx) { if (rf & 1) {
951
- i0.ɵɵelementStart(0, "tr")(1, "td", 196);
950
+ function MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_18_For_22_Template(rf, ctx) { if (rf & 1) {
951
+ i0.ɵɵelementStart(0, "tr")(1, "td", 197);
952
952
  i0.ɵɵtext(2);
953
953
  i0.ɵɵpipe(3, "date");
954
954
  i0.ɵɵelementEnd();
955
- i0.ɵɵelementStart(4, "td", 197);
955
+ i0.ɵɵelementStart(4, "td", 198);
956
956
  i0.ɵɵtext(5);
957
957
  i0.ɵɵelementEnd();
958
- i0.ɵɵconditionalCreate(6, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_For_22_Conditional_6_Template, 2, 1, "td", 198);
959
- i0.ɵɵconditionalCreate(7, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_For_22_Conditional_7_Template, 2, 1, "td", 199);
960
- i0.ɵɵconditionalCreate(8, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_For_22_Conditional_8_Template, 5, 3, "td", 200);
961
- i0.ɵɵconditionalCreate(9, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_For_22_Conditional_9_Template, 2, 1, "td", 201);
962
- i0.ɵɵelementStart(10, "td", 202);
958
+ i0.ɵɵconditionalCreate(6, MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_18_For_22_Conditional_6_Template, 2, 1, "td", 199);
959
+ i0.ɵɵconditionalCreate(7, MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_18_For_22_Conditional_7_Template, 2, 1, "td", 200);
960
+ i0.ɵɵconditionalCreate(8, MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_18_For_22_Conditional_8_Template, 5, 3, "td", 201);
961
+ i0.ɵɵconditionalCreate(9, MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_18_For_22_Conditional_9_Template, 2, 1, "td", 202);
962
+ i0.ɵɵelementStart(10, "td", 203);
963
963
  i0.ɵɵtext(11);
964
964
  i0.ɵɵelementEnd();
965
- i0.ɵɵelementStart(12, "td", 203);
965
+ i0.ɵɵelementStart(12, "td", 204);
966
966
  i0.ɵɵtext(13);
967
967
  i0.ɵɵelementEnd()();
968
968
  } if (rf & 2) {
@@ -985,21 +985,21 @@ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18
985
985
  i0.ɵɵadvance(2);
986
986
  i0.ɵɵtextInterpolate(ctx_r0.formatCost(day_r18.avgCost));
987
987
  } }
988
- function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_Template(rf, ctx) { if (rf & 1) {
989
- i0.ɵɵelementStart(0, "div", 181)(1, "h3");
990
- i0.ɵɵelement(2, "i", 193);
988
+ function MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_18_Template(rf, ctx) { if (rf & 1) {
989
+ i0.ɵɵelementStart(0, "div", 182)(1, "h3");
990
+ i0.ɵɵelement(2, "i", 194);
991
991
  i0.ɵɵtext(3, " Daily Performance");
992
992
  i0.ɵɵelementEnd();
993
- i0.ɵɵelementStart(4, "div", 194)(5, "table", 195)(6, "thead")(7, "tr")(8, "th");
993
+ i0.ɵɵelementStart(4, "div", 195)(5, "table", 196)(6, "thead")(7, "tr")(8, "th");
994
994
  i0.ɵɵtext(9, "Date");
995
995
  i0.ɵɵelementEnd();
996
996
  i0.ɵɵelementStart(10, "th");
997
997
  i0.ɵɵtext(11, "Runs");
998
998
  i0.ɵɵelementEnd();
999
- i0.ɵɵconditionalCreate(12, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_Conditional_12_Template, 2, 0, "th");
1000
- i0.ɵɵconditionalCreate(13, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_Conditional_13_Template, 2, 0, "th");
1001
- i0.ɵɵconditionalCreate(14, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_Conditional_14_Template, 2, 0, "th");
1002
- i0.ɵɵconditionalCreate(15, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_Conditional_15_Template, 2, 0, "th");
999
+ i0.ɵɵconditionalCreate(12, MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_18_Conditional_12_Template, 2, 0, "th");
1000
+ i0.ɵɵconditionalCreate(13, MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_18_Conditional_13_Template, 2, 0, "th");
1001
+ i0.ɵɵconditionalCreate(14, MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_18_Conditional_14_Template, 2, 0, "th");
1002
+ i0.ɵɵconditionalCreate(15, MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_18_Conditional_15_Template, 2, 0, "th");
1003
1003
  i0.ɵɵelementStart(16, "th");
1004
1004
  i0.ɵɵtext(17, "Avg Duration");
1005
1005
  i0.ɵɵelementEnd();
@@ -1007,7 +1007,7 @@ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18
1007
1007
  i0.ɵɵtext(19, "Avg Cost");
1008
1008
  i0.ɵɵelementEnd()()();
1009
1009
  i0.ɵɵelementStart(20, "tbody");
1010
- i0.ɵɵrepeaterCreate(21, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_For_22_Template, 14, 11, "tr", null, i0.ɵɵrepeaterTrackByIdentity);
1010
+ i0.ɵɵrepeaterCreate(21, MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_18_For_22_Template, 14, 11, "tr", null, i0.ɵɵrepeaterTrackByIdentity);
1011
1011
  i0.ɵɵelementEnd()()()();
1012
1012
  } if (rf & 2) {
1013
1013
  const ctx_r0 = i0.ɵɵnextContext(3);
@@ -1022,8 +1022,8 @@ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18
1022
1022
  i0.ɵɵadvance(6);
1023
1023
  i0.ɵɵrepeater(ctx_r0.historyData);
1024
1024
  } }
1025
- function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Conditional_4_For_2_Template(rf, ctx) { if (rf & 1) {
1026
- i0.ɵɵelementStart(0, "span", 218);
1025
+ function MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_19_For_6_Conditional_4_For_2_Template(rf, ctx) { if (rf & 1) {
1026
+ i0.ɵɵelementStart(0, "span", 219);
1027
1027
  i0.ɵɵtext(1);
1028
1028
  i0.ɵɵelementEnd();
1029
1029
  } if (rf & 2) {
@@ -1031,8 +1031,8 @@ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19
1031
1031
  i0.ɵɵadvance();
1032
1032
  i0.ɵɵtextInterpolate(tag_r21);
1033
1033
  } }
1034
- function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Conditional_4_Conditional_3_Template(rf, ctx) { if (rf & 1) {
1035
- i0.ɵɵelementStart(0, "span", 219);
1034
+ function MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_19_For_6_Conditional_4_Conditional_3_Template(rf, ctx) { if (rf & 1) {
1035
+ i0.ɵɵelementStart(0, "span", 220);
1036
1036
  i0.ɵɵtext(1);
1037
1037
  i0.ɵɵelementEnd();
1038
1038
  } if (rf & 2) {
@@ -1040,10 +1040,10 @@ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19
1040
1040
  i0.ɵɵadvance();
1041
1041
  i0.ɵɵtextInterpolate1("+", suite_r20.tags.length - 3);
1042
1042
  } }
1043
- function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Conditional_4_Template(rf, ctx) { if (rf & 1) {
1044
- i0.ɵɵelementStart(0, "div", 212);
1045
- i0.ɵɵrepeaterCreate(1, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Conditional_4_For_2_Template, 2, 1, "span", 218, i0.ɵɵrepeaterTrackByIdentity);
1046
- i0.ɵɵconditionalCreate(3, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Conditional_4_Conditional_3_Template, 2, 1, "span", 219);
1043
+ function MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_19_For_6_Conditional_4_Template(rf, ctx) { if (rf & 1) {
1044
+ i0.ɵɵelementStart(0, "div", 213);
1045
+ i0.ɵɵrepeaterCreate(1, MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_19_For_6_Conditional_4_For_2_Template, 2, 1, "span", 219, i0.ɵɵrepeaterTrackByIdentity);
1046
+ i0.ɵɵconditionalCreate(3, MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_19_For_6_Conditional_4_Conditional_3_Template, 2, 1, "span", 220);
1047
1047
  i0.ɵɵelementEnd();
1048
1048
  } if (rf & 2) {
1049
1049
  const suite_r20 = i0.ɵɵnextContext().$implicit;
@@ -1052,11 +1052,11 @@ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19
1052
1052
  i0.ɵɵadvance(2);
1053
1053
  i0.ɵɵconditional(suite_r20.tags.length > 3 ? 3 : -1);
1054
1054
  } }
1055
- function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Conditional_11_Template(rf, ctx) { if (rf & 1) {
1056
- i0.ɵɵelementStart(0, "div", 214)(1, "span", 220);
1055
+ function MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_19_For_6_Conditional_11_Template(rf, ctx) { if (rf & 1) {
1056
+ i0.ɵɵelementStart(0, "div", 215)(1, "span", 221);
1057
1057
  i0.ɵɵtext(2);
1058
1058
  i0.ɵɵelementEnd();
1059
- i0.ɵɵelementStart(3, "span", 216);
1059
+ i0.ɵɵelementStart(3, "span", 217);
1060
1060
  i0.ɵɵtext(4, "Pass Rate");
1061
1061
  i0.ɵɵelementEnd()();
1062
1062
  } if (rf & 2) {
@@ -1066,11 +1066,11 @@ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19
1066
1066
  i0.ɵɵadvance();
1067
1067
  i0.ɵɵtextInterpolate1(" ", suite_r20.passRate.toFixed(1), "% ");
1068
1068
  } }
1069
- function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Conditional_12_Template(rf, ctx) { if (rf & 1) {
1070
- i0.ɵɵelementStart(0, "div", 214)(1, "span", 215);
1069
+ function MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_19_For_6_Conditional_12_Template(rf, ctx) { if (rf & 1) {
1070
+ i0.ɵɵelementStart(0, "div", 215)(1, "span", 216);
1071
1071
  i0.ɵɵtext(2);
1072
1072
  i0.ɵɵelementEnd();
1073
- i0.ɵɵelementStart(3, "span", 216);
1073
+ i0.ɵɵelementStart(3, "span", 217);
1074
1074
  i0.ɵɵtext(4, "Avg Score");
1075
1075
  i0.ɵɵelementEnd()();
1076
1076
  } if (rf & 2) {
@@ -1078,11 +1078,11 @@ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19
1078
1078
  i0.ɵɵadvance(2);
1079
1079
  i0.ɵɵtextInterpolate1("", (suite_r20.avgScore * 100).toFixed(1), "%");
1080
1080
  } }
1081
- function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Conditional_23_Template(rf, ctx) { if (rf & 1) {
1082
- i0.ɵɵelementStart(0, "div", 214)(1, "span", 215);
1081
+ function MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_19_For_6_Conditional_23_Template(rf, ctx) { if (rf & 1) {
1082
+ i0.ɵɵelementStart(0, "div", 215)(1, "span", 216);
1083
1083
  i0.ɵɵtext(2);
1084
1084
  i0.ɵɵelementEnd();
1085
- i0.ɵɵelementStart(3, "span", 216);
1085
+ i0.ɵɵelementStart(3, "span", 217);
1086
1086
  i0.ɵɵtext(4, "Last Run");
1087
1087
  i0.ɵɵelementEnd()();
1088
1088
  } if (rf & 2) {
@@ -1091,38 +1091,38 @@ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19
1091
1091
  i0.ɵɵadvance(2);
1092
1092
  i0.ɵɵtextInterpolate(ctx_r0.getRelativeTime(suite_r20.lastRun));
1093
1093
  } }
1094
- function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Template(rf, ctx) { if (rf & 1) {
1094
+ function MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_19_For_6_Template(rf, ctx) { if (rf & 1) {
1095
1095
  const _r19 = i0.ɵɵgetCurrentView();
1096
- i0.ɵɵelementStart(0, "div", 209);
1097
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Template_div_click_0_listener() { const suite_r20 = i0.ɵɵrestoreView(_r19).$implicit; const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.openSuiteFromHistory(suite_r20.suiteId)); });
1098
- i0.ɵɵelementStart(1, "div", 210)(2, "div", 211);
1096
+ i0.ɵɵelementStart(0, "div", 210);
1097
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_19_For_6_Template_div_click_0_listener() { const suite_r20 = i0.ɵɵrestoreView(_r19).$implicit; const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.openSuiteFromHistory(suite_r20.suiteId)); });
1098
+ i0.ɵɵelementStart(1, "div", 211)(2, "div", 212);
1099
1099
  i0.ɵɵtext(3);
1100
1100
  i0.ɵɵelementEnd();
1101
- i0.ɵɵconditionalCreate(4, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Conditional_4_Template, 4, 1, "div", 212);
1101
+ i0.ɵɵconditionalCreate(4, MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_19_For_6_Conditional_4_Template, 4, 1, "div", 213);
1102
1102
  i0.ɵɵelementEnd();
1103
- i0.ɵɵelementStart(5, "div", 213)(6, "div", 214)(7, "span", 215);
1103
+ i0.ɵɵelementStart(5, "div", 214)(6, "div", 215)(7, "span", 216);
1104
1104
  i0.ɵɵtext(8);
1105
1105
  i0.ɵɵelementEnd();
1106
- i0.ɵɵelementStart(9, "span", 216);
1106
+ i0.ɵɵelementStart(9, "span", 217);
1107
1107
  i0.ɵɵtext(10, "Runs");
1108
1108
  i0.ɵɵelementEnd()();
1109
- i0.ɵɵconditionalCreate(11, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Conditional_11_Template, 5, 5, "div", 214);
1110
- i0.ɵɵconditionalCreate(12, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Conditional_12_Template, 5, 1, "div", 214);
1111
- i0.ɵɵelementStart(13, "div", 214)(14, "span", 215);
1109
+ i0.ɵɵconditionalCreate(11, MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_19_For_6_Conditional_11_Template, 5, 5, "div", 215);
1110
+ i0.ɵɵconditionalCreate(12, MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_19_For_6_Conditional_12_Template, 5, 1, "div", 215);
1111
+ i0.ɵɵelementStart(13, "div", 215)(14, "span", 216);
1112
1112
  i0.ɵɵtext(15);
1113
1113
  i0.ɵɵelementEnd();
1114
- i0.ɵɵelementStart(16, "span", 216);
1114
+ i0.ɵɵelementStart(16, "span", 217);
1115
1115
  i0.ɵɵtext(17, "Avg Duration");
1116
1116
  i0.ɵɵelementEnd()();
1117
- i0.ɵɵelementStart(18, "div", 214)(19, "span", 215);
1117
+ i0.ɵɵelementStart(18, "div", 215)(19, "span", 216);
1118
1118
  i0.ɵɵtext(20);
1119
1119
  i0.ɵɵelementEnd();
1120
- i0.ɵɵelementStart(21, "span", 216);
1120
+ i0.ɵɵelementStart(21, "span", 217);
1121
1121
  i0.ɵɵtext(22, "Avg Cost");
1122
1122
  i0.ɵɵelementEnd()();
1123
- i0.ɵɵconditionalCreate(23, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Conditional_23_Template, 5, 1, "div", 214);
1123
+ i0.ɵɵconditionalCreate(23, MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_19_For_6_Conditional_23_Template, 5, 1, "div", 215);
1124
1124
  i0.ɵɵelementEnd();
1125
- i0.ɵɵelement(24, "i", 217);
1125
+ i0.ɵɵelement(24, "i", 218);
1126
1126
  i0.ɵɵelementEnd();
1127
1127
  } if (rf & 2) {
1128
1128
  const suite_r20 = ctx.$implicit;
@@ -1144,55 +1144,55 @@ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19
1144
1144
  i0.ɵɵadvance(3);
1145
1145
  i0.ɵɵconditional(suite_r20.lastRun ? 23 : -1);
1146
1146
  } }
1147
- function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_Template(rf, ctx) { if (rf & 1) {
1148
- i0.ɵɵelementStart(0, "div", 181)(1, "h3");
1149
- i0.ɵɵelement(2, "i", 33);
1147
+ function MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_19_Template(rf, ctx) { if (rf & 1) {
1148
+ i0.ɵɵelementStart(0, "div", 182)(1, "h3");
1149
+ i0.ɵɵelement(2, "i", 34);
1150
1150
  i0.ɵɵtext(3, " Performance by Suite");
1151
1151
  i0.ɵɵelementEnd();
1152
- i0.ɵɵelementStart(4, "div", 207);
1153
- i0.ɵɵrepeaterCreate(5, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Template, 25, 8, "div", 208, i0.ɵɵrepeaterTrackByIdentity);
1152
+ i0.ɵɵelementStart(4, "div", 208);
1153
+ i0.ɵɵrepeaterCreate(5, MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_19_For_6_Template, 25, 8, "div", 209, i0.ɵɵrepeaterTrackByIdentity);
1154
1154
  i0.ɵɵelementEnd()();
1155
1155
  } if (rf & 2) {
1156
1156
  const ctx_r0 = i0.ɵɵnextContext(3);
1157
1157
  i0.ɵɵadvance(5);
1158
1158
  i0.ɵɵrepeater(ctx_r0.suitePerformance);
1159
1159
  } }
1160
- function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_20_Template(rf, ctx) { if (rf & 1) {
1160
+ function MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_20_Template(rf, ctx) { if (rf & 1) {
1161
1161
  const _r22 = i0.ɵɵgetCurrentView();
1162
- i0.ɵɵelementStart(0, "mj-empty-state", 221);
1163
- i0.ɵɵlistener("Action", function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_20_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r22); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.runTest()); });
1162
+ i0.ɵɵelementStart(0, "mj-empty-state", 222);
1163
+ i0.ɵɵlistener("Action", function MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_20_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r22); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.runTest()); });
1164
1164
  i0.ɵɵelementEnd();
1165
1165
  } }
1166
- function MJTestFormComponentExtended_Conditional_67_Conditional_2_Template(rf, ctx) { if (rf & 1) {
1166
+ function MJTestFormComponentExtended_Conditional_68_Conditional_2_Template(rf, ctx) { if (rf & 1) {
1167
1167
  const _r17 = i0.ɵɵgetCurrentView();
1168
- i0.ɵɵelementStart(0, "div", 172)(1, "div", 174)(2, "div", 175)(3, "span", 176);
1168
+ i0.ɵɵelementStart(0, "div", 173)(1, "div", 175)(2, "div", 176)(3, "span", 177);
1169
1169
  i0.ɵɵtext(4, "Time Range:");
1170
1170
  i0.ɵɵelementEnd();
1171
- i0.ɵɵelementStart(5, "button", 177);
1172
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_67_Conditional_2_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r17); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setHistoryTimeRange("7d")); });
1171
+ i0.ɵɵelementStart(5, "button", 178);
1172
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_68_Conditional_2_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r17); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setHistoryTimeRange("7d")); });
1173
1173
  i0.ɵɵtext(6, "7 Days");
1174
1174
  i0.ɵɵelementEnd();
1175
- i0.ɵɵelementStart(7, "button", 177);
1176
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_67_Conditional_2_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r17); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setHistoryTimeRange("30d")); });
1175
+ i0.ɵɵelementStart(7, "button", 178);
1176
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_68_Conditional_2_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r17); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setHistoryTimeRange("30d")); });
1177
1177
  i0.ɵɵtext(8, "30 Days");
1178
1178
  i0.ɵɵelementEnd();
1179
- i0.ɵɵelementStart(9, "button", 177);
1180
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_67_Conditional_2_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r17); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setHistoryTimeRange("90d")); });
1179
+ i0.ɵɵelementStart(9, "button", 178);
1180
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_68_Conditional_2_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r17); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setHistoryTimeRange("90d")); });
1181
1181
  i0.ɵɵtext(10, "90 Days");
1182
1182
  i0.ɵɵelementEnd();
1183
- i0.ɵɵelementStart(11, "button", 177);
1184
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_67_Conditional_2_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r17); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setHistoryTimeRange("all")); });
1183
+ i0.ɵɵelementStart(11, "button", 178);
1184
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_68_Conditional_2_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r17); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setHistoryTimeRange("all")); });
1185
1185
  i0.ɵɵtext(12, "All Time");
1186
1186
  i0.ɵɵelementEnd()();
1187
- i0.ɵɵelementStart(13, "div", 178)(14, "button", 23);
1188
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_67_Conditional_2_Template_button_click_14_listener() { i0.ɵɵrestoreView(_r17); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.exportHistoryToCSV()); });
1189
- i0.ɵɵelement(15, "i", 179);
1187
+ i0.ɵɵelementStart(13, "div", 179)(14, "button", 23);
1188
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_68_Conditional_2_Template_button_click_14_listener() { i0.ɵɵrestoreView(_r17); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.exportHistoryToCSV()); });
1189
+ i0.ɵɵelement(15, "i", 180);
1190
1190
  i0.ɵɵtext(16, " Export CSV ");
1191
1191
  i0.ɵɵelementEnd()()();
1192
- i0.ɵɵconditionalCreate(17, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_17_Template, 27, 5, "div", 180);
1193
- i0.ɵɵconditionalCreate(18, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_Template, 23, 4, "div", 181);
1194
- i0.ɵɵconditionalCreate(19, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_Template, 7, 0, "div", 181);
1195
- i0.ɵɵconditionalCreate(20, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_20_Template, 1, 0, "mj-empty-state", 182);
1192
+ i0.ɵɵconditionalCreate(17, MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_17_Template, 27, 5, "div", 181);
1193
+ i0.ɵɵconditionalCreate(18, MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_18_Template, 23, 4, "div", 182);
1194
+ i0.ɵɵconditionalCreate(19, MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_19_Template, 7, 0, "div", 182);
1195
+ i0.ɵɵconditionalCreate(20, MJTestFormComponentExtended_Conditional_68_Conditional_2_Conditional_20_Template, 1, 0, "mj-empty-state", 183);
1196
1196
  i0.ɵɵelementEnd();
1197
1197
  } if (rf & 2) {
1198
1198
  const ctx_r0 = i0.ɵɵnextContext(2);
@@ -1215,10 +1215,10 @@ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Template(rf, c
1215
1215
  i0.ɵɵadvance();
1216
1216
  i0.ɵɵconditional(ctx_r0.historyData.length === 0 ? 20 : -1);
1217
1217
  } }
1218
- function MJTestFormComponentExtended_Conditional_67_Template(rf, ctx) { if (rf & 1) {
1219
- i0.ɵɵelementStart(0, "div", 40);
1220
- i0.ɵɵconditionalCreate(1, MJTestFormComponentExtended_Conditional_67_Conditional_1_Template, 2, 0, "div", 125);
1221
- i0.ɵɵconditionalCreate(2, MJTestFormComponentExtended_Conditional_67_Conditional_2_Template, 21, 13, "div", 172);
1218
+ function MJTestFormComponentExtended_Conditional_68_Template(rf, ctx) { if (rf & 1) {
1219
+ i0.ɵɵelementStart(0, "div", 41);
1220
+ i0.ɵɵconditionalCreate(1, MJTestFormComponentExtended_Conditional_68_Conditional_1_Template, 2, 0, "div", 126);
1221
+ i0.ɵɵconditionalCreate(2, MJTestFormComponentExtended_Conditional_68_Conditional_2_Template, 21, 13, "div", 173);
1222
1222
  i0.ɵɵelementEnd();
1223
1223
  } if (rf & 2) {
1224
1224
  const ctx_r0 = i0.ɵɵnextContext();
@@ -1227,46 +1227,46 @@ function MJTestFormComponentExtended_Conditional_67_Template(rf, ctx) { if (rf &
1227
1227
  i0.ɵɵadvance();
1228
1228
  i0.ɵɵconditional(!ctx_r0.loadingHistory && ctx_r0.historyLoaded ? 2 : -1);
1229
1229
  } }
1230
- function MJTestFormComponentExtended_Conditional_70_Template(rf, ctx) { if (rf & 1) {
1230
+ function MJTestFormComponentExtended_Conditional_71_Template(rf, ctx) { if (rf & 1) {
1231
1231
  const _r23 = i0.ɵɵgetCurrentView();
1232
- i0.ɵɵelementStart(0, "div", 43)(1, "div", 222);
1233
- i0.ɵɵelement(2, "i", 42);
1232
+ i0.ɵɵelementStart(0, "div", 44)(1, "div", 223);
1233
+ i0.ɵɵelement(2, "i", 43);
1234
1234
  i0.ɵɵtext(3, " Shortcuts ");
1235
- i0.ɵɵelementStart(4, "button", 223);
1236
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_70_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.toggleShortcuts()); });
1237
- i0.ɵɵelement(5, "i", 124);
1235
+ i0.ɵɵelementStart(4, "button", 224);
1236
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_71_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.toggleShortcuts()); });
1237
+ i0.ɵɵelement(5, "i", 125);
1238
1238
  i0.ɵɵelementEnd()();
1239
- i0.ɵɵelementStart(6, "div", 224)(7, "div", 225)(8, "span");
1239
+ i0.ɵɵelementStart(6, "div", 225)(7, "div", 226)(8, "span");
1240
1240
  i0.ɵɵtext(9, "Save changes");
1241
1241
  i0.ɵɵelementEnd();
1242
- i0.ɵɵelementStart(10, "span", 226)(11, "kbd");
1242
+ i0.ɵɵelementStart(10, "span", 227)(11, "kbd");
1243
1243
  i0.ɵɵtext(12, "Cmd");
1244
1244
  i0.ɵɵelementEnd();
1245
1245
  i0.ɵɵelementStart(13, "kbd");
1246
1246
  i0.ɵɵtext(14, "S");
1247
1247
  i0.ɵɵelementEnd()()();
1248
- i0.ɵɵelementStart(15, "div", 225)(16, "span");
1248
+ i0.ɵɵelementStart(15, "div", 226)(16, "span");
1249
1249
  i0.ɵɵtext(17, "Refresh");
1250
1250
  i0.ɵɵelementEnd();
1251
- i0.ɵɵelementStart(18, "span", 226)(19, "kbd");
1251
+ i0.ɵɵelementStart(18, "span", 227)(19, "kbd");
1252
1252
  i0.ɵɵtext(20, "Cmd");
1253
1253
  i0.ɵɵelementEnd();
1254
1254
  i0.ɵɵelementStart(21, "kbd");
1255
1255
  i0.ɵɵtext(22, "R");
1256
1256
  i0.ɵɵelementEnd()()();
1257
- i0.ɵɵelementStart(23, "div", 225)(24, "span");
1257
+ i0.ɵɵelementStart(23, "div", 226)(24, "span");
1258
1258
  i0.ɵɵtext(25, "Run Test");
1259
1259
  i0.ɵɵelementEnd();
1260
- i0.ɵɵelementStart(26, "span", 226)(27, "kbd");
1260
+ i0.ɵɵelementStart(26, "span", 227)(27, "kbd");
1261
1261
  i0.ɵɵtext(28, "Cmd");
1262
1262
  i0.ɵɵelementEnd();
1263
1263
  i0.ɵɵelementStart(29, "kbd");
1264
1264
  i0.ɵɵtext(30, "Enter");
1265
1265
  i0.ɵɵelementEnd()()();
1266
- i0.ɵɵelementStart(31, "div", 225)(32, "span");
1266
+ i0.ɵɵelementStart(31, "div", 226)(32, "span");
1267
1267
  i0.ɵɵtext(33, "Switch Tabs");
1268
1268
  i0.ɵɵelementEnd();
1269
- i0.ɵɵelementStart(34, "span", 226)(35, "kbd");
1269
+ i0.ɵɵelementStart(34, "span", 227)(35, "kbd");
1270
1270
  i0.ɵɵtext(36, "1");
1271
1271
  i0.ɵɵelementEnd();
1272
1272
  i0.ɵɵtext(37, "-");
@@ -1274,12 +1274,12 @@ function MJTestFormComponentExtended_Conditional_70_Template(rf, ctx) { if (rf &
1274
1274
  i0.ɵɵtext(39, "5");
1275
1275
  i0.ɵɵelementEnd()()()()();
1276
1276
  } }
1277
- function MJTestFormComponentExtended_Conditional_71_Template(rf, ctx) { if (rf & 1) {
1277
+ function MJTestFormComponentExtended_Conditional_72_Template(rf, ctx) { if (rf & 1) {
1278
1278
  const _r24 = i0.ɵɵgetCurrentView();
1279
- i0.ɵɵelementStart(0, "mj-slide-panel", 227);
1280
- i0.ɵɵlistener("Closed", function MJTestFormComponentExtended_Conditional_71_Template_mj_slide_panel_Closed_0_listener() { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnPanelClosed()); });
1281
- i0.ɵɵelementStart(1, "app-test-run-dialog", 228);
1282
- i0.ɵɵlistener("PanelClose", function MJTestFormComponentExtended_Conditional_71_Template_app_test_run_dialog_PanelClose_1_listener() { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnPanelClosed()); });
1279
+ i0.ɵɵelementStart(0, "mj-slide-panel", 228);
1280
+ i0.ɵɵlistener("Closed", function MJTestFormComponentExtended_Conditional_72_Template_mj_slide_panel_Closed_0_listener() { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnPanelClosed()); });
1281
+ i0.ɵɵelementStart(1, "app-test-run-dialog", 229);
1282
+ i0.ɵɵlistener("PanelClose", function MJTestFormComponentExtended_Conditional_72_Template_app_test_run_dialog_PanelClose_1_listener() { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnPanelClosed()); });
1283
1283
  i0.ɵɵelementEnd()();
1284
1284
  } if (rf & 2) {
1285
1285
  const ctx_r0 = i0.ɵɵnextContext();
@@ -1287,26 +1287,26 @@ function MJTestFormComponentExtended_Conditional_71_Template(rf, ctx) { if (rf &
1287
1287
  i0.ɵɵadvance();
1288
1288
  i0.ɵɵproperty("PanelMode", true)("selectedTestId", (ctx_r0.testingDialogService.PanelOptions == null ? null : ctx_r0.testingDialogService.PanelOptions.testId) ?? null)("selectedSuiteId", (ctx_r0.testingDialogService.PanelOptions == null ? null : ctx_r0.testingDialogService.PanelOptions.suiteId) ?? null)("runMode", (ctx_r0.testingDialogService.PanelOptions == null ? null : ctx_r0.testingDialogService.PanelOptions.mode) ?? "test");
1289
1289
  } }
1290
- function MJTestFormComponentExtended_Conditional_80_Template(rf, ctx) { if (rf & 1) {
1290
+ function MJTestFormComponentExtended_Conditional_81_Template(rf, ctx) { if (rf & 1) {
1291
1291
  i0.ɵɵtext(0);
1292
1292
  } if (rf & 2) {
1293
1293
  const ctx_r0 = i0.ɵɵnextContext();
1294
1294
  i0.ɵɵtextInterpolate1(" ", ctx_r0.dirtyFieldNames[0], " edited ");
1295
1295
  } }
1296
- function MJTestFormComponentExtended_Conditional_81_Template(rf, ctx) { if (rf & 1) {
1296
+ function MJTestFormComponentExtended_Conditional_82_Template(rf, ctx) { if (rf & 1) {
1297
1297
  i0.ɵɵtext(0);
1298
1298
  } if (rf & 2) {
1299
1299
  const ctx_r0 = i0.ɵɵnextContext();
1300
1300
  i0.ɵɵtextInterpolate1(" ", ctx_r0.dirtyFieldNames.length, " fields edited ");
1301
1301
  } }
1302
- function MJTestFormComponentExtended_Conditional_84_Template(rf, ctx) { if (rf & 1) {
1303
- i0.ɵɵelement(0, "i", 229);
1304
- i0.ɵɵtext(1, " Saving\u2026 ");
1305
- } }
1306
1302
  function MJTestFormComponentExtended_Conditional_85_Template(rf, ctx) { if (rf & 1) {
1307
1303
  i0.ɵɵelement(0, "i", 230);
1304
+ i0.ɵɵtext(1, " Saving\u2026 ");
1305
+ } }
1306
+ function MJTestFormComponentExtended_Conditional_86_Template(rf, ctx) { if (rf & 1) {
1307
+ i0.ɵɵelement(0, "i", 231);
1308
1308
  i0.ɵɵtext(1, " Save changes ");
1309
- i0.ɵɵelementStart(2, "span", 231)(3, "kbd");
1309
+ i0.ɵɵelementStart(2, "span", 232)(3, "kbd");
1310
1310
  i0.ɵɵtext(4, "\u2318");
1311
1311
  i0.ɵɵelementEnd();
1312
1312
  i0.ɵɵelementStart(5, "kbd");
@@ -1817,6 +1817,21 @@ let MJTestFormComponentExtended = class MJTestFormComponentExtended extends MJTe
1817
1817
  console.error('Error parsing JSON fields:', error);
1818
1818
  }
1819
1819
  }
1820
+ /** The tab strip as `mj-section-picker` items: strip order, a count once that tab's data has loaded. */
1821
+ get SectionPickerItems() {
1822
+ return [
1823
+ { Key: 'overview', Title: 'Overview', Icon: 'fas fa-th-large' },
1824
+ { Key: 'config', Title: 'Configuration', Icon: 'fas fa-sliders-h' },
1825
+ { Key: 'runs', Title: 'Runs', Icon: 'fas fa-history', Count: this.TestRunsLoaded ? this.TestRuns.length : null },
1826
+ { Key: 'suites', Title: 'Test Suites', Icon: 'fas fa-layer-group', Count: this.SuiteTestsLoaded ? this.SuiteTests.length : null },
1827
+ { Key: 'analytics', Title: 'Analytics', Icon: 'fas fa-chart-line' },
1828
+ ];
1829
+ }
1830
+ /** A pick from the phone section sheet; goes through ChangeTab so lazy loads fire. An unknown key is ignored. */
1831
+ OnSectionPicked(key) {
1832
+ if (this.SectionPickerItems.some((i) => i.Key === key))
1833
+ this.ChangeTab(key);
1834
+ }
1820
1835
  ChangeTab(tab) {
1821
1836
  this.ActiveTab = tab;
1822
1837
  // Lazy load tabs
@@ -2577,7 +2592,7 @@ let MJTestFormComponentExtended = class MJTestFormComponentExtended extends MJTe
2577
2592
  static { this.ɵfac = /*@__PURE__*/ (() => { let ɵMJTestFormComponentExtended_BaseFactory; return function MJTestFormComponentExtended_Factory(__ngFactoryType__) { return (ɵMJTestFormComponentExtended_BaseFactory || (ɵMJTestFormComponentExtended_BaseFactory = i0.ɵɵgetInheritedFactory(MJTestFormComponentExtended)))(__ngFactoryType__ || MJTestFormComponentExtended); }; })(); }
2578
2593
  static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJTestFormComponentExtended, selectors: [["mj-test-form"]], hostBindings: function MJTestFormComponentExtended_HostBindings(rf, ctx) { if (rf & 1) {
2579
2594
  i0.ɵɵlistener("keydown", function MJTestFormComponentExtended_keydown_HostBindingHandler($event) { return ctx.handleKeyboardShortcut($event); }, i0.ɵɵresolveDocument)("beforeunload", function MJTestFormComponentExtended_beforeunload_HostBindingHandler($event) { return ctx.handleBeforeUnload($event); }, i0.ɵɵresolveWindow);
2580
- } }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 89, vars: 51, consts: [["tagInput", ""], [1, "test-form"], [1, "test-header"], ["aria-label", "Breadcrumb", 1, "breadcrumb"], ["href", "javascript:void(0)", 3, "click"], [1, "fas", "fa-vial"], [1, "breadcrumb-text"], [1, "current"], [1, "fas", "fa-chevron-right", "separator"], [1, "fas", "fa-flask"], [1, "header-content"], [1, "header-left"], [1, "test-icon"], [1, "test-info"], ["title", "You have unsaved changes", "aria-label", "Unsaved changes", 1, "dirty-indicator"], [1, "test-meta"], [1, "status-badge", 3, "ngClass"], [1, "fas", 3, "ngClass"], [1, "test-type"], ["title", "You have unsaved changes", 1, "unsaved-pill"], [1, "header-actions"], ["mjButton", "", "variant", "primary", 3, "click"], [1, "fas", "fa-play"], ["mjButton", "", 3, "click", "disabled"], [1, "test-description"], [1, "metrics-bar"], [1, "tabs-container"], ["role", "tablist", 1, "tabs"], ["role", "tab", 1, "tab", 3, "click"], [1, "fas", "fa-th-large"], [1, "fas", "fa-sliders-h"], [1, "fas", "fa-history"], [1, "tab-badge"], [1, "fas", "fa-layer-group"], [1, "fas", "fa-chart-line"], [1, "tab-content"], [1, "overview-tab"], [1, "config-tab"], [1, "runs-tab"], [1, "suites-tab"], [1, "history-tab"], [1, "shortcuts-toggle", 3, "click", "title"], [1, "fas", "fa-keyboard"], [1, "keyboard-shortcuts"], ["Mode", "slide", 3, "Title", "Resizable"], ["role", "region", "aria-label", "Unsaved changes", 1, "save-bar"], [1, "save-bar-message"], ["aria-hidden", "true", 1, "save-bar-dot"], [1, "save-bar-text"], [1, "save-bar-fields"], [1, "save-bar-actions"], ["type", "button", "title", "Save changes (\u2318S)", 1, "save-bar-btn", "save-bar-btn--primary", 3, "click", "disabled"], ["type", "button", "title", "Discard changes", 1, "save-bar-btn", "save-bar-btn--ghost", 3, "click", "disabled"], [1, "fas", "fa-undo"], [1, "fas", "fa-tag"], [1, "fas", "fa-circle"], [1, "metric-card"], [1, "metric-label"], [1, "metric-value"], [1, "metric-progress"], [1, "metric-progress-fill"], [1, "info-section"], [1, "fas", "fa-info-circle"], [1, "info-grid"], [1, "info-item"], [1, "info-label"], [1, "info-value"], [1, "status-badge-inline", 3, "ngClass"], [1, "json-section"], [1, "fas", "fa-code"], [1, "json-tabs"], [1, "json-tab", 3, "click"], [1, "fas", "fa-sign-in-alt"], [1, "fas", "fa-check-double"], [1, "fas", "fa-cog"], [1, "fas", "fa-tags"], [1, "code-editor-container"], ["language", "json", 3, "value", "readonly", "toolbar", "lineWrapping"], [1, "edit-section"], [1, "edit-section-header"], [1, "fas", "fa-pen-to-square"], [1, "edit-section-sub"], [1, "edit-grid"], [1, "edit-field", "edit-field--full"], ["for", "test-name"], [1, "required"], ["id", "test-name", "type", "text", "placeholder", "e.g., Agent Response Quality Test", 1, "config-input", 3, "ngModelChange", "ngModel"], ["for", "test-description"], ["id", "test-description", "rows", "3", "placeholder", "What does this test evaluate?", 1, "config-input", "config-textarea", 3, "ngModelChange", "ngModel"], [1, "edit-field"], ["for", "test-status"], [1, "select-wrapper"], ["id", "test-status", 1, "config-input", 3, "ngModelChange", "ngModel"], [3, "ngValue"], ["for", "test-rubric"], ["id", "test-rubric", 1, "config-input", 3, "ngModelChange", "ngModel"], ["for", "test-type"], ["id", "test-type", 1, "config-input", 3, "ngModelChange", "ngModel"], ["for", "test-tags"], [1, "tag-editor", 3, "click"], [1, "tag-chip-editable"], ["id", "test-tags", "type", "text", 1, "tag-input-inline", 3, "ngModelChange", "keydown", "blur", "placeholder", "ngModel"], [1, "config-hint"], [1, "fas", "fa-cogs"], ["for", "test-priority"], ["id", "test-priority", "type", "number", "placeholder", "0 (lower runs first)", 1, "config-input", 3, "ngModelChange", "ngModel"], ["for", "test-repeat"], ["id", "test-repeat", "type", "number", "min", "1", "placeholder", "1", 1, "config-input", 3, "ngModelChange", "ngModel"], ["for", "test-duration"], ["id", "test-duration", "type", "number", "placeholder", "0", 1, "config-input", 3, "ngModelChange", "ngModel"], ["for", "test-cost"], ["id", "test-cost", "type", "number", "step", "0.000001", "placeholder", "0.00", 1, "config-input", 3, "ngModelChange", "ngModel"], ["for", "test-timeout"], ["id", "test-timeout", "type", "number", "placeholder", "Default: 300000 (5 min)", 1, "config-input", 3, "ngModelChange", "ngModel"], [1, "config-section"], [1, "config-editor-container"], ["language", "json", 3, "change", "value", "readonly", "lineWrapping"], [1, "meta-section"], [1, "meta-grid"], [1, "meta-item"], [1, "meta-label"], [1, "meta-value"], [1, "meta-value", "meta-mono"], ["type", "button", 1, "tag-remove", 3, "click"], [1, "fas", "fa-times"], [1, "loading-state"], [1, "runs-list"], ["Icon", "fa-solid fa-circle-play", "Title", "No Test Runs Yet", "Message", "Run this test to see execution history and results here.", "ActionText", "Run Test Now", "ActionIcon", "fa-solid fa-play"], [1, "skeleton-list"], [1, "skeleton-card"], [1, "skeleton-icon"], [1, "skeleton-content"], [1, "skeleton-line", "wide"], [1, "skeleton-line", "narrow"], [1, "run-item"], [1, "run-item", 3, "click"], [1, "run-icon"], [1, "fas"], [1, "run-content"], [1, "run-header"], [1, "run-id"], [1, "run-status"], [1, "run-meta"], [1, "fas", "fa-calendar"], [3, "entityName", "recordId"], [1, "run-eval-stack"], [1, "eval-pill", "status-pill", 3, "ngClass", "title"], [1, "run-tags"], [1, "fas", "fa-chevron-right"], [1, "fas", "fa-clock"], [1, "fas", "fa-dollar-sign"], ["title", "Human Review: No rating submitted yet", 1, "eval-pill", "human-pill", "no-feedback"], [1, "eval-pill", "human-pill", "has-feedback", 3, "rating-low", "rating-medium", "rating-good", "rating-excellent", "title"], [1, "fas", "fa-user-slash"], [1, "eval-pill", "human-pill", "has-feedback", 3, "title"], [1, "fas", "fa-user"], ["title", "Auto Score: No automated score available", 1, "eval-pill", "auto-pill", "no-score"], [1, "eval-pill", "auto-pill", "has-score", 3, "score-low", "score-medium", "score-good", "score-excellent", "title"], [1, "fas", "fa-robot"], [1, "eval-pill", "auto-pill", "has-score", 3, "title"], [1, "run-tag"], [1, "run-tag-more"], ["Icon", "fa-solid fa-circle-play", "Title", "No Test Runs Yet", "Message", "Run this test to see execution history and results here.", "ActionText", "Run Test Now", "ActionIcon", "fa-solid fa-play", 3, "Action"], [1, "suites-list"], ["Icon", "fa-solid fa-folder-open", "Title", "Not Part of Any Suite", "Message", "This test is not included in any test suites. Add it to a suite to run it with other tests."], [1, "suite-item"], [1, "suite-item", 3, "click"], [1, "suite-icon"], [1, "suite-content"], [1, "suite-name"], [1, "suite-meta"], [1, "fas", "fa-sort-numeric-up"], [1, "history-content"], ["text", "Loading history..."], [1, "history-filters"], [1, "time-range-filters"], [1, "filter-label"], [1, "filter-btn", 3, "click"], [1, "history-actions"], [1, "fas", "fa-download"], [1, "history-kpi-cards"], [1, "history-section"], ["Icon", "fa-solid fa-chart-line", "Title", "No History Available", "Message", "Run this test to start building history and analytics data.", "ActionText", "Run Test Now", "ActionIcon", "fa-solid fa-play"], [1, "kpi-card"], [1, "kpi-icon"], [1, "fas", "fa-play-circle"], [1, "kpi-content"], [1, "kpi-value"], [1, "kpi-label"], [1, "kpi-icon", "pass-rate"], [1, "fas", "fa-percentage"], [1, "fas", "trend-icon"], [1, "fas", "fa-star"], [1, "fas", "fa-calendar-alt"], [1, "history-table-container"], [1, "history-table"], [1, "date-cell"], [1, "runs-cell"], [1, "passed-cell"], [1, "failed-cell"], [1, "pass-rate-cell"], [1, "score-cell"], [1, "duration-cell"], [1, "cost-cell"], [1, "pass-rate-bar"], [1, "pass-rate-fill"], [1, "pass-rate-text"], [1, "suite-performance-list"], [1, "suite-perf-card"], [1, "suite-perf-card", 3, "click"], [1, "suite-perf-header"], [1, "suite-perf-name"], [1, "suite-perf-tags"], [1, "suite-perf-stats"], [1, "suite-stat"], [1, "stat-value"], [1, "stat-label"], [1, "fas", "fa-chevron-right", "suite-perf-arrow"], [1, "tag-mini"], [1, "tag-more"], [1, "stat-value", "pass-rate"], ["Icon", "fa-solid fa-chart-line", "Title", "No History Available", "Message", "Run this test to start building history and analytics data.", "ActionText", "Run Test Now", "ActionIcon", "fa-solid fa-play", 3, "Action"], [1, "shortcuts-header"], ["title", "Hide shortcuts", 1, "shortcuts-close", 3, "click"], [1, "shortcut-list"], [1, "shortcut-item"], [1, "shortcut-keys"], ["Mode", "slide", 3, "Closed", "Title", "Resizable"], [3, "PanelClose", "PanelMode", "selectedTestId", "selectedSuiteId", "runMode"], [1, "fas", "fa-spinner", "fa-spin"], [1, "fas", "fa-check"], [1, "save-bar-kbd"]], template: function MJTestFormComponentExtended_Template(rf, ctx) { if (rf & 1) {
2595
+ } }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 90, vars: 53, consts: [["tagInput", ""], [1, "test-form"], [1, "test-header"], ["aria-label", "Breadcrumb", 1, "breadcrumb"], ["href", "javascript:void(0)", 3, "click"], [1, "fas", "fa-vial"], [1, "breadcrumb-text"], [1, "current"], [1, "fas", "fa-chevron-right", "separator"], [1, "fas", "fa-flask"], [1, "header-content"], [1, "header-left"], [1, "test-icon"], [1, "test-info"], ["title", "You have unsaved changes", "aria-label", "Unsaved changes", 1, "dirty-indicator"], [1, "test-meta"], [1, "status-badge", 3, "ngClass"], [1, "fas", 3, "ngClass"], [1, "test-type"], ["title", "You have unsaved changes", 1, "unsaved-pill"], [1, "header-actions"], ["mjButton", "", "variant", "primary", 3, "click"], [1, "fas", "fa-play"], ["mjButton", "", 3, "click", "disabled"], [1, "test-description"], [1, "metrics-bar"], [1, "tabs-container"], [1, "phone-section-picker", 3, "ActiveKeyChange", "Items", "ActiveKey"], ["role", "tablist", 1, "tabs"], ["role", "tab", 1, "tab", 3, "click"], [1, "fas", "fa-th-large"], [1, "fas", "fa-sliders-h"], [1, "fas", "fa-history"], [1, "tab-badge"], [1, "fas", "fa-layer-group"], [1, "fas", "fa-chart-line"], [1, "tab-content"], [1, "overview-tab"], [1, "config-tab"], [1, "runs-tab"], [1, "suites-tab"], [1, "history-tab"], [1, "shortcuts-toggle", 3, "click", "title"], [1, "fas", "fa-keyboard"], [1, "keyboard-shortcuts"], ["Mode", "slide", 3, "Title", "Resizable"], ["role", "region", "aria-label", "Unsaved changes", 1, "save-bar"], [1, "save-bar-message"], ["aria-hidden", "true", 1, "save-bar-dot"], [1, "save-bar-text"], [1, "save-bar-fields"], [1, "save-bar-actions"], ["type", "button", "title", "Save changes (\u2318S)", 1, "save-bar-btn", "save-bar-btn--primary", 3, "click", "disabled"], ["type", "button", "title", "Discard changes", 1, "save-bar-btn", "save-bar-btn--ghost", 3, "click", "disabled"], [1, "fas", "fa-undo"], [1, "fas", "fa-tag"], [1, "fas", "fa-circle"], [1, "metric-card"], [1, "metric-label"], [1, "metric-value"], [1, "metric-progress"], [1, "metric-progress-fill"], [1, "info-section"], [1, "fas", "fa-info-circle"], [1, "info-grid"], [1, "info-item"], [1, "info-label"], [1, "info-value"], [1, "status-badge-inline", 3, "ngClass"], [1, "json-section"], [1, "fas", "fa-code"], [1, "json-tabs"], [1, "json-tab", 3, "click"], [1, "fas", "fa-sign-in-alt"], [1, "fas", "fa-check-double"], [1, "fas", "fa-cog"], [1, "fas", "fa-tags"], [1, "code-editor-container"], ["language", "json", 3, "value", "readonly", "toolbar", "lineWrapping"], [1, "edit-section"], [1, "edit-section-header"], [1, "fas", "fa-pen-to-square"], [1, "edit-section-sub"], [1, "edit-grid"], [1, "edit-field", "edit-field--full"], ["for", "test-name"], [1, "required"], ["id", "test-name", "type", "text", "placeholder", "e.g., Agent Response Quality Test", 1, "config-input", 3, "ngModelChange", "ngModel"], ["for", "test-description"], ["id", "test-description", "rows", "3", "placeholder", "What does this test evaluate?", 1, "config-input", "config-textarea", 3, "ngModelChange", "ngModel"], [1, "edit-field"], ["for", "test-status"], [1, "select-wrapper"], ["id", "test-status", 1, "config-input", 3, "ngModelChange", "ngModel"], [3, "ngValue"], ["for", "test-rubric"], ["id", "test-rubric", 1, "config-input", 3, "ngModelChange", "ngModel"], ["for", "test-type"], ["id", "test-type", 1, "config-input", 3, "ngModelChange", "ngModel"], ["for", "test-tags"], [1, "tag-editor", 3, "click"], [1, "tag-chip-editable"], ["id", "test-tags", "type", "text", 1, "tag-input-inline", 3, "ngModelChange", "keydown", "blur", "placeholder", "ngModel"], [1, "config-hint"], [1, "fas", "fa-cogs"], ["for", "test-priority"], ["id", "test-priority", "type", "number", "placeholder", "0 (lower runs first)", 1, "config-input", 3, "ngModelChange", "ngModel"], ["for", "test-repeat"], ["id", "test-repeat", "type", "number", "min", "1", "placeholder", "1", 1, "config-input", 3, "ngModelChange", "ngModel"], ["for", "test-duration"], ["id", "test-duration", "type", "number", "placeholder", "0", 1, "config-input", 3, "ngModelChange", "ngModel"], ["for", "test-cost"], ["id", "test-cost", "type", "number", "step", "0.000001", "placeholder", "0.00", 1, "config-input", 3, "ngModelChange", "ngModel"], ["for", "test-timeout"], ["id", "test-timeout", "type", "number", "placeholder", "Default: 300000 (5 min)", 1, "config-input", 3, "ngModelChange", "ngModel"], [1, "config-section"], [1, "config-editor-container"], ["language", "json", 3, "change", "value", "readonly", "lineWrapping"], [1, "meta-section"], [1, "meta-grid"], [1, "meta-item"], [1, "meta-label"], [1, "meta-value"], [1, "meta-value", "meta-mono"], ["type", "button", 1, "tag-remove", 3, "click"], [1, "fas", "fa-times"], [1, "loading-state"], [1, "runs-list"], ["Icon", "fa-solid fa-circle-play", "Title", "No Test Runs Yet", "Message", "Run this test to see execution history and results here.", "ActionText", "Run Test Now", "ActionIcon", "fa-solid fa-play"], [1, "skeleton-list"], [1, "skeleton-card"], [1, "skeleton-icon"], [1, "skeleton-content"], [1, "skeleton-line", "wide"], [1, "skeleton-line", "narrow"], [1, "run-item"], [1, "run-item", 3, "click"], [1, "run-icon"], [1, "fas"], [1, "run-content"], [1, "run-header"], [1, "run-id"], [1, "run-status"], [1, "run-meta"], [1, "fas", "fa-calendar"], [3, "entityName", "recordId"], [1, "run-eval-stack"], [1, "eval-pill", "status-pill", 3, "ngClass", "title"], [1, "run-tags"], [1, "fas", "fa-chevron-right"], [1, "fas", "fa-clock"], [1, "fas", "fa-dollar-sign"], ["title", "Human Review: No rating submitted yet", 1, "eval-pill", "human-pill", "no-feedback"], [1, "eval-pill", "human-pill", "has-feedback", 3, "rating-low", "rating-medium", "rating-good", "rating-excellent", "title"], [1, "fas", "fa-user-slash"], [1, "eval-pill", "human-pill", "has-feedback", 3, "title"], [1, "fas", "fa-user"], ["title", "Auto Score: No automated score available", 1, "eval-pill", "auto-pill", "no-score"], [1, "eval-pill", "auto-pill", "has-score", 3, "score-low", "score-medium", "score-good", "score-excellent", "title"], [1, "fas", "fa-robot"], [1, "eval-pill", "auto-pill", "has-score", 3, "title"], [1, "run-tag"], [1, "run-tag-more"], ["Icon", "fa-solid fa-circle-play", "Title", "No Test Runs Yet", "Message", "Run this test to see execution history and results here.", "ActionText", "Run Test Now", "ActionIcon", "fa-solid fa-play", 3, "Action"], [1, "suites-list"], ["Icon", "fa-solid fa-folder-open", "Title", "Not Part of Any Suite", "Message", "This test is not included in any test suites. Add it to a suite to run it with other tests."], [1, "suite-item"], [1, "suite-item", 3, "click"], [1, "suite-icon"], [1, "suite-content"], [1, "suite-name"], [1, "suite-meta"], [1, "fas", "fa-sort-numeric-up"], [1, "history-content"], ["text", "Loading history..."], [1, "history-filters"], [1, "time-range-filters"], [1, "filter-label"], [1, "filter-btn", 3, "click"], [1, "history-actions"], [1, "fas", "fa-download"], [1, "history-kpi-cards"], [1, "history-section"], ["Icon", "fa-solid fa-chart-line", "Title", "No History Available", "Message", "Run this test to start building history and analytics data.", "ActionText", "Run Test Now", "ActionIcon", "fa-solid fa-play"], [1, "kpi-card"], [1, "kpi-icon"], [1, "fas", "fa-play-circle"], [1, "kpi-content"], [1, "kpi-value"], [1, "kpi-label"], [1, "kpi-icon", "pass-rate"], [1, "fas", "fa-percentage"], [1, "fas", "trend-icon"], [1, "fas", "fa-star"], [1, "fas", "fa-calendar-alt"], [1, "history-table-container"], [1, "history-table"], [1, "date-cell"], [1, "runs-cell"], [1, "passed-cell"], [1, "failed-cell"], [1, "pass-rate-cell"], [1, "score-cell"], [1, "duration-cell"], [1, "cost-cell"], [1, "pass-rate-bar"], [1, "pass-rate-fill"], [1, "pass-rate-text"], [1, "suite-performance-list"], [1, "suite-perf-card"], [1, "suite-perf-card", 3, "click"], [1, "suite-perf-header"], [1, "suite-perf-name"], [1, "suite-perf-tags"], [1, "suite-perf-stats"], [1, "suite-stat"], [1, "stat-value"], [1, "stat-label"], [1, "fas", "fa-chevron-right", "suite-perf-arrow"], [1, "tag-mini"], [1, "tag-more"], [1, "stat-value", "pass-rate"], ["Icon", "fa-solid fa-chart-line", "Title", "No History Available", "Message", "Run this test to start building history and analytics data.", "ActionText", "Run Test Now", "ActionIcon", "fa-solid fa-play", 3, "Action"], [1, "shortcuts-header"], ["title", "Hide shortcuts", 1, "shortcuts-close", 3, "click"], [1, "shortcut-list"], [1, "shortcut-item"], [1, "shortcut-keys"], ["Mode", "slide", 3, "Closed", "Title", "Resizable"], [3, "PanelClose", "PanelMode", "selectedTestId", "selectedSuiteId", "runMode"], [1, "fas", "fa-spinner", "fa-spin"], [1, "fas", "fa-check"], [1, "save-bar-kbd"]], template: function MJTestFormComponentExtended_Template(rf, ctx) { if (rf & 1) {
2581
2596
  i0.ɵɵelementStart(0, "div", 1)(1, "div", 2)(2, "nav", 3)(3, "ol")(4, "li")(5, "a", 4);
2582
2597
  i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_a_click_5_listener() { return ctx.navigateToTestingDashboard(); });
2583
2598
  i0.ɵɵelement(6, "i", 5);
@@ -2618,70 +2633,73 @@ let MJTestFormComponentExtended = class MJTestFormComponentExtended extends MJTe
2618
2633
  i0.ɵɵconditionalCreate(36, MJTestFormComponentExtended_Conditional_36_Template, 3, 1, "div", 24);
2619
2634
  i0.ɵɵconditionalCreate(37, MJTestFormComponentExtended_Conditional_37_Template, 23, 6, "div", 25);
2620
2635
  i0.ɵɵelementEnd();
2621
- i0.ɵɵelementStart(38, "div", 26)(39, "div", 27)(40, "button", 28);
2622
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_40_listener() { return ctx.changeTab("overview"); });
2623
- i0.ɵɵelement(41, "i", 29);
2624
- i0.ɵɵelementStart(42, "span");
2625
- i0.ɵɵtext(43, "Overview");
2636
+ i0.ɵɵelementStart(38, "div", 26)(39, "mj-section-picker", 27);
2637
+ i0.ɵɵlistener("ActiveKeyChange", function MJTestFormComponentExtended_Template_mj_section_picker_ActiveKeyChange_39_listener($event) { return ctx.OnSectionPicked($event); });
2638
+ i0.ɵɵelementEnd();
2639
+ i0.ɵɵelementStart(40, "div", 28)(41, "button", 29);
2640
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_41_listener() { return ctx.changeTab("overview"); });
2641
+ i0.ɵɵelement(42, "i", 30);
2642
+ i0.ɵɵelementStart(43, "span");
2643
+ i0.ɵɵtext(44, "Overview");
2626
2644
  i0.ɵɵelementEnd()();
2627
- i0.ɵɵelementStart(44, "button", 28);
2628
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_44_listener() { return ctx.changeTab("config"); });
2629
- i0.ɵɵelement(45, "i", 30);
2630
- i0.ɵɵelementStart(46, "span");
2631
- i0.ɵɵtext(47, "Configuration");
2645
+ i0.ɵɵelementStart(45, "button", 29);
2646
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_45_listener() { return ctx.changeTab("config"); });
2647
+ i0.ɵɵelement(46, "i", 31);
2648
+ i0.ɵɵelementStart(47, "span");
2649
+ i0.ɵɵtext(48, "Configuration");
2632
2650
  i0.ɵɵelementEnd()();
2633
- i0.ɵɵelementStart(48, "button", 28);
2634
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_48_listener() { return ctx.changeTab("runs"); });
2635
- i0.ɵɵelement(49, "i", 31);
2636
- i0.ɵɵelementStart(50, "span");
2637
- i0.ɵɵtext(51, "Runs");
2651
+ i0.ɵɵelementStart(49, "button", 29);
2652
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_49_listener() { return ctx.changeTab("runs"); });
2653
+ i0.ɵɵelement(50, "i", 32);
2654
+ i0.ɵɵelementStart(51, "span");
2655
+ i0.ɵɵtext(52, "Runs");
2638
2656
  i0.ɵɵelementEnd();
2639
- i0.ɵɵconditionalCreate(52, MJTestFormComponentExtended_Conditional_52_Template, 2, 1, "span", 32);
2657
+ i0.ɵɵconditionalCreate(53, MJTestFormComponentExtended_Conditional_53_Template, 2, 1, "span", 33);
2640
2658
  i0.ɵɵelementEnd();
2641
- i0.ɵɵelementStart(53, "button", 28);
2642
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_53_listener() { return ctx.changeTab("suites"); });
2643
- i0.ɵɵelement(54, "i", 33);
2644
- i0.ɵɵelementStart(55, "span");
2645
- i0.ɵɵtext(56, "Test Suites");
2659
+ i0.ɵɵelementStart(54, "button", 29);
2660
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_54_listener() { return ctx.changeTab("suites"); });
2661
+ i0.ɵɵelement(55, "i", 34);
2662
+ i0.ɵɵelementStart(56, "span");
2663
+ i0.ɵɵtext(57, "Test Suites");
2646
2664
  i0.ɵɵelementEnd();
2647
- i0.ɵɵconditionalCreate(57, MJTestFormComponentExtended_Conditional_57_Template, 2, 1, "span", 32);
2665
+ i0.ɵɵconditionalCreate(58, MJTestFormComponentExtended_Conditional_58_Template, 2, 1, "span", 33);
2648
2666
  i0.ɵɵelementEnd();
2649
- i0.ɵɵelementStart(58, "button", 28);
2650
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_58_listener() { return ctx.changeTab("analytics"); });
2651
- i0.ɵɵelement(59, "i", 34);
2652
- i0.ɵɵelementStart(60, "span");
2653
- i0.ɵɵtext(61, "Analytics");
2667
+ i0.ɵɵelementStart(59, "button", 29);
2668
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_59_listener() { return ctx.changeTab("analytics"); });
2669
+ i0.ɵɵelement(60, "i", 35);
2670
+ i0.ɵɵelementStart(61, "span");
2671
+ i0.ɵɵtext(62, "Analytics");
2654
2672
  i0.ɵɵelementEnd()()()();
2655
- i0.ɵɵelementStart(62, "div", 35);
2656
- i0.ɵɵconditionalCreate(63, MJTestFormComponentExtended_Conditional_63_Template, 78, 29, "div", 36);
2657
- i0.ɵɵconditionalCreate(64, MJTestFormComponentExtended_Conditional_64_Template, 119, 32, "div", 37);
2658
- i0.ɵɵconditionalCreate(65, MJTestFormComponentExtended_Conditional_65_Template, 4, 3, "div", 38);
2673
+ i0.ɵɵelementStart(63, "div", 36);
2674
+ i0.ɵɵconditionalCreate(64, MJTestFormComponentExtended_Conditional_64_Template, 78, 29, "div", 37);
2675
+ i0.ɵɵconditionalCreate(65, MJTestFormComponentExtended_Conditional_65_Template, 119, 32, "div", 38);
2659
2676
  i0.ɵɵconditionalCreate(66, MJTestFormComponentExtended_Conditional_66_Template, 4, 3, "div", 39);
2660
- i0.ɵɵconditionalCreate(67, MJTestFormComponentExtended_Conditional_67_Template, 3, 2, "div", 40);
2677
+ i0.ɵɵconditionalCreate(67, MJTestFormComponentExtended_Conditional_67_Template, 4, 3, "div", 40);
2678
+ i0.ɵɵconditionalCreate(68, MJTestFormComponentExtended_Conditional_68_Template, 3, 2, "div", 41);
2661
2679
  i0.ɵɵelementEnd();
2662
- i0.ɵɵelementStart(68, "button", 41);
2663
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_68_listener() { return ctx.toggleShortcuts(); });
2664
- i0.ɵɵelement(69, "i", 42);
2680
+ i0.ɵɵelementStart(69, "button", 42);
2681
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_69_listener() { return ctx.toggleShortcuts(); });
2682
+ i0.ɵɵelement(70, "i", 43);
2665
2683
  i0.ɵɵelementEnd();
2666
- i0.ɵɵconditionalCreate(70, MJTestFormComponentExtended_Conditional_70_Template, 40, 0, "div", 43);
2667
- i0.ɵɵconditionalCreate(71, MJTestFormComponentExtended_Conditional_71_Template, 2, 6, "mj-slide-panel", 44);
2668
- i0.ɵɵelementStart(72, "div", 45)(73, "div", 46)(74, "span", 47);
2669
- i0.ɵɵtext(75, "\u25CF");
2684
+ i0.ɵɵconditionalCreate(71, MJTestFormComponentExtended_Conditional_71_Template, 40, 0, "div", 44);
2685
+ i0.ɵɵconditionalCreate(72, MJTestFormComponentExtended_Conditional_72_Template, 2, 6, "mj-slide-panel", 45);
2686
+ i0.ɵɵelementStart(73, "div", 46)(74, "div", 47)(75, "span", 48);
2687
+ i0.ɵɵtext(76, "\u25CF");
2670
2688
  i0.ɵɵelementEnd();
2671
- i0.ɵɵelementStart(76, "span", 48)(77, "strong");
2672
- i0.ɵɵtext(78, "Unsaved changes");
2689
+ i0.ɵɵelementStart(77, "span", 49)(78, "strong");
2690
+ i0.ɵɵtext(79, "Unsaved changes");
2673
2691
  i0.ɵɵelementEnd();
2674
- i0.ɵɵelementStart(79, "span", 49);
2675
- i0.ɵɵconditionalCreate(80, MJTestFormComponentExtended_Conditional_80_Template, 1, 1)(81, MJTestFormComponentExtended_Conditional_81_Template, 1, 1);
2692
+ i0.ɵɵelementStart(80, "span", 50);
2693
+ i0.ɵɵconditionalCreate(81, MJTestFormComponentExtended_Conditional_81_Template, 1, 1)(82, MJTestFormComponentExtended_Conditional_82_Template, 1, 1);
2676
2694
  i0.ɵɵelementEnd()()();
2677
- i0.ɵɵelementStart(82, "div", 50)(83, "button", 51);
2678
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_83_listener() { return ctx.saveChanges(); });
2679
- i0.ɵɵconditionalCreate(84, MJTestFormComponentExtended_Conditional_84_Template, 2, 0)(85, MJTestFormComponentExtended_Conditional_85_Template, 7, 0);
2695
+ i0.ɵɵelementStart(83, "div", 51)(84, "button", 52);
2696
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_84_listener() { return ctx.saveChanges(); });
2697
+ i0.ɵɵconditionalCreate(85, MJTestFormComponentExtended_Conditional_85_Template, 2, 0)(86, MJTestFormComponentExtended_Conditional_86_Template, 7, 0);
2680
2698
  i0.ɵɵelementEnd();
2681
- i0.ɵɵelementStart(86, "button", 52);
2682
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_86_listener() { return ctx.discardChanges(); });
2683
- i0.ɵɵelement(87, "i", 53);
2684
- i0.ɵɵtext(88, " Discard ");
2699
+ i0.ɵɵelementStart(87, "button", 53);
2700
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_87_listener() { return ctx.discardChanges(); });
2701
+ i0.ɵɵelement(88, "i", 54);
2702
+ i0.ɵɵtext(89, " Discard ");
2685
2703
  i0.ɵɵelementEnd()()()();
2686
2704
  } if (rf & 2) {
2687
2705
  i0.ɵɵadvance(13);
@@ -2712,7 +2730,9 @@ let MJTestFormComponentExtended = class MJTestFormComponentExtended extends MJTe
2712
2730
  i0.ɵɵconditional(ctx.record.Description ? 36 : -1);
2713
2731
  i0.ɵɵadvance();
2714
2732
  i0.ɵɵconditional(ctx.testRunsLoaded && ctx.testRuns.length > 0 ? 37 : -1);
2715
- i0.ɵɵadvance(3);
2733
+ i0.ɵɵadvance(2);
2734
+ i0.ɵɵproperty("Items", ctx.SectionPickerItems)("ActiveKey", ctx.ActiveTab);
2735
+ i0.ɵɵadvance(2);
2716
2736
  i0.ɵɵclassProp("active", ctx.activeTab === "overview");
2717
2737
  i0.ɵɵattribute("aria-selected", ctx.activeTab === "overview");
2718
2738
  i0.ɵɵadvance(4);
@@ -2722,47 +2742,47 @@ let MJTestFormComponentExtended = class MJTestFormComponentExtended extends MJTe
2722
2742
  i0.ɵɵclassProp("active", ctx.activeTab === "runs");
2723
2743
  i0.ɵɵattribute("aria-selected", ctx.activeTab === "runs");
2724
2744
  i0.ɵɵadvance(4);
2725
- i0.ɵɵconditional(ctx.testRunsLoaded ? 52 : -1);
2745
+ i0.ɵɵconditional(ctx.testRunsLoaded ? 53 : -1);
2726
2746
  i0.ɵɵadvance();
2727
2747
  i0.ɵɵclassProp("active", ctx.activeTab === "suites");
2728
2748
  i0.ɵɵattribute("aria-selected", ctx.activeTab === "suites");
2729
2749
  i0.ɵɵadvance(4);
2730
- i0.ɵɵconditional(ctx.suiteTestsLoaded ? 57 : -1);
2750
+ i0.ɵɵconditional(ctx.suiteTestsLoaded ? 58 : -1);
2731
2751
  i0.ɵɵadvance();
2732
2752
  i0.ɵɵclassProp("active", ctx.activeTab === "analytics");
2733
2753
  i0.ɵɵattribute("aria-selected", ctx.activeTab === "analytics");
2734
2754
  i0.ɵɵadvance(4);
2735
2755
  i0.ɵɵclassProp("has-savebar", ctx.isDirty);
2736
2756
  i0.ɵɵadvance();
2737
- i0.ɵɵconditional(ctx.activeTab === "overview" ? 63 : -1);
2757
+ i0.ɵɵconditional(ctx.activeTab === "overview" ? 64 : -1);
2738
2758
  i0.ɵɵadvance();
2739
- i0.ɵɵconditional(ctx.activeTab === "config" ? 64 : -1);
2759
+ i0.ɵɵconditional(ctx.activeTab === "config" ? 65 : -1);
2740
2760
  i0.ɵɵadvance();
2741
- i0.ɵɵconditional(ctx.activeTab === "runs" ? 65 : -1);
2761
+ i0.ɵɵconditional(ctx.activeTab === "runs" ? 66 : -1);
2742
2762
  i0.ɵɵadvance();
2743
- i0.ɵɵconditional(ctx.activeTab === "suites" ? 66 : -1);
2763
+ i0.ɵɵconditional(ctx.activeTab === "suites" ? 67 : -1);
2744
2764
  i0.ɵɵadvance();
2745
- i0.ɵɵconditional(ctx.activeTab === "analytics" ? 67 : -1);
2765
+ i0.ɵɵconditional(ctx.activeTab === "analytics" ? 68 : -1);
2746
2766
  i0.ɵɵadvance();
2747
2767
  i0.ɵɵproperty("title", ctx.showShortcuts ? "Hide keyboard shortcuts" : "Show keyboard shortcuts");
2748
2768
  i0.ɵɵadvance(2);
2749
- i0.ɵɵconditional(ctx.showShortcuts ? 70 : -1);
2769
+ i0.ɵɵconditional(ctx.showShortcuts ? 71 : -1);
2750
2770
  i0.ɵɵadvance();
2751
- i0.ɵɵconditional(ctx.testingDialogService.IsPanelOpen ? 71 : -1);
2771
+ i0.ɵɵconditional(ctx.testingDialogService.IsPanelOpen ? 72 : -1);
2752
2772
  i0.ɵɵadvance();
2753
2773
  i0.ɵɵclassProp("save-bar--visible", ctx.isDirty);
2754
2774
  i0.ɵɵattribute("aria-hidden", !ctx.isDirty);
2755
2775
  i0.ɵɵadvance(8);
2756
- i0.ɵɵconditional(ctx.dirtyFieldNames.length === 1 ? 80 : ctx.dirtyFieldNames.length > 1 ? 81 : -1);
2776
+ i0.ɵɵconditional(ctx.dirtyFieldNames.length === 1 ? 81 : ctx.dirtyFieldNames.length > 1 ? 82 : -1);
2757
2777
  i0.ɵɵadvance(3);
2758
2778
  i0.ɵɵproperty("disabled", ctx.isSaving || !ctx.isDirty);
2759
2779
  i0.ɵɵattribute("tabindex", ctx.isDirty ? 0 : -1);
2760
2780
  i0.ɵɵadvance();
2761
- i0.ɵɵconditional(ctx.isSaving ? 84 : 85);
2781
+ i0.ɵɵconditional(ctx.isSaving ? 85 : 86);
2762
2782
  i0.ɵɵadvance(2);
2763
2783
  i0.ɵɵproperty("disabled", ctx.isSaving || !ctx.isDirty);
2764
2784
  i0.ɵɵattribute("tabindex", ctx.isDirty ? 0 : -1);
2765
- } }, dependencies: [i1.NgClass, i2.NgSelectOption, i2.ɵNgSelectMultipleOption, i2.DefaultValueAccessor, i2.NumberValueAccessor, i2.SelectControlValueAccessor, i2.NgControlStatus, i2.MinValidator, i2.NgModel, i3.MJEmptyStateComponent, i3.MJButtonDirective, i4.CodeEditorComponent, i5.TestRunDialogComponent, i5.EvaluationModeToggleComponent, i6.LoadingComponent, i3.MjSlidePanelComponent, i7.EntityLinkPillComponent, i1.DatePipe], styles: ["\n\n\n\n\n\n[_nghost-%COMP%] {\n --test-primary: var(--mj-brand-primary);\n --test-primary-light: var(--mj-brand-primary);\n --test-primary-dark: var(--mj-brand-primary-hover);\n --test-success: var(--mj-status-success);\n --test-success-light: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n --test-error: var(--mj-status-error);\n --test-error-light: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n --test-warning: var(--mj-status-warning);\n --test-warning-light: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n --test-disabled: var(--mj-text-muted);\n --test-bg: var(--mj-bg-surface-card);\n --test-surface: var(--mj-bg-surface);\n --test-border: var(--mj-border-default);\n --test-text: var(--mj-text-primary);\n --test-text-secondary: var(--mj-text-muted);\n --test-text-muted: var(--mj-text-disabled);\n --test-radius-sm: 6px;\n --test-radius-md: 10px;\n --test-radius-lg: 16px;\n --test-shadow-sm: var(--mj-shadow-sm);\n --test-shadow-md: var(--mj-shadow-md);\n --test-shadow-lg: var(--mj-shadow-lg);\n --test-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n display: block;\n height: 100%;\n}\n\n\n.breadcrumb[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] ol[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n list-style: none;\n margin: 0;\n padding: 0;\n font-size: 13px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] li[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] a[_ngcontent-%COMP%] {\n color: var(--test-primary);\n text-decoration: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n border-radius: 6px;\n transition: background 0.15s;\n}\n\n.breadcrumb[_ngcontent-%COMP%] a[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n text-decoration: none;\n}\n\n.breadcrumb[_ngcontent-%COMP%] .separator[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--test-text-muted);\n margin: 0 4px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] .current[_ngcontent-%COMP%] {\n color: var(--test-text-secondary);\n font-weight: 500;\n}\n\n.breadcrumb-text[_ngcontent-%COMP%] {\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n\n.test-form[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--test-bg);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n\n\n\n.test-header[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n padding: 20px;\n}\n\n.header-content[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 16px;\n gap: 16px;\n}\n\n.header-left[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n flex: 1;\n min-width: 0;\n}\n\n\n.test-icon[_ngcontent-%COMP%] {\n width: 56px;\n height: 56px;\n border-radius: var(--test-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-inverse);\n font-size: 24px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-md);\n transition: var(--test-transition);\n}\n\n.test-icon[_ngcontent-%COMP%]:hover {\n transform: scale(1.05);\n}\n\n\n.test-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.test-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: clamp(18px, 4vw, 24px);\n font-weight: 700;\n color: var(--test-text);\n line-height: 1.2;\n word-wrap: break-word;\n}\n\n.test-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n color: var(--mj-text-inverse);\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.status-badge.status-active[_ngcontent-%COMP%] { background: var(--mj-status-success); }\n.status-badge.status-disabled[_ngcontent-%COMP%] { background: var(--mj-text-secondary); }\n.status-badge.status-pending[_ngcontent-%COMP%] { background: var(--mj-status-warning); }\n\n.status-badge-inline[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 2px 10px;\n border-radius: 10px;\n color: var(--mj-text-inverse);\n font-size: 11px;\n font-weight: 600;\n}\n\n.status-badge-inline.status-active[_ngcontent-%COMP%] { background: var(--test-success); }\n.status-badge-inline.status-disabled[_ngcontent-%COMP%] { background: var(--test-disabled); }\n.status-badge-inline.status-pending[_ngcontent-%COMP%] { background: var(--test-warning); }\n\n.test-type[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 14px;\n color: var(--test-text-secondary);\n padding: 4px 10px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.header-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n white-space: nowrap;\n}\n\n\n.test-description[_ngcontent-%COMP%] {\n padding: 16px;\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--test-radius-md);\n margin-bottom: 16px;\n border: 1px solid var(--test-border);\n}\n\n.test-description[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n color: var(--test-text-secondary);\n line-height: 1.6;\n font-size: 14px;\n}\n\n\n\n\n.metrics-bar[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));\n gap: 12px;\n}\n\n.metric-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 14px;\n text-align: center;\n transition: var(--test-transition);\n}\n\n.metric-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.metric-label[_ngcontent-%COMP%] {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n margin-bottom: 6px;\n}\n\n.metric-value[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n\n.metric-progress[_ngcontent-%COMP%] {\n margin-top: 8px;\n height: 4px;\n background: var(--test-border);\n border-radius: 2px;\n overflow: hidden;\n}\n\n.metric-progress-fill[_ngcontent-%COMP%] {\n height: 100%;\n background: var(--mj-status-success);\n border-radius: 2px;\n transition: width 0.5s ease-out;\n}\n\n\n\n\n.tabs-container[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n position: sticky;\n top: 0;\n z-index: 10;\n}\n\n.tabs[_ngcontent-%COMP%] {\n display: flex;\n padding: 0 20px;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n -ms-overflow-style: none;\n}\n\n.tabs[_ngcontent-%COMP%]::-webkit-scrollbar {\n display: none;\n}\n\n.tab[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 14px 18px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: var(--test-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n white-space: nowrap;\n}\n\n.tab[_ngcontent-%COMP%]:hover {\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.tab.active[_ngcontent-%COMP%] {\n color: var(--test-primary);\n border-bottom-color: var(--test-primary);\n font-weight: 600;\n}\n\n.tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 15px;\n}\n\n.tab-badge[_ngcontent-%COMP%] {\n background: var(--test-border);\n color: var(--test-text-secondary);\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n transition: var(--test-transition);\n}\n\n.tab.active[_ngcontent-%COMP%] .tab-badge[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n color: var(--test-primary);\n}\n\n.tab-shortcut[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n margin-left: 4px;\n}\n\n\n\n\n.tab-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n scroll-behavior: smooth;\n}\n\n\n\n\n.overview-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n\n.info-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.info-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.info-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.info-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n}\n\n.info-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.info-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.info-value[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--test-text);\n word-wrap: break-word;\n font-weight: 500;\n}\n\n\n.json-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.json-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.json-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.json-tabs[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n margin-bottom: 16px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n padding: 4px;\n flex-wrap: wrap;\n}\n\n.json-tab[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 100px;\n padding: 10px 14px;\n border: none;\n background: transparent;\n color: var(--test-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n border-radius: var(--test-radius-sm);\n transition: var(--test-transition);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n}\n\n.json-tab[_ngcontent-%COMP%]:hover {\n color: var(--test-text);\n background: var(--mj-bg-overlay);\n}\n\n.json-tab.active[_ngcontent-%COMP%] {\n background: var(--test-surface);\n color: var(--test-primary);\n font-weight: 600;\n box-shadow: var(--test-shadow-sm);\n}\n\n.json-tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.code-editor-container[_ngcontent-%COMP%] {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid var(--test-border);\n min-height: 200px;\n max-height: 400px;\n}\n\n\n\n\n.config-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.config-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.config-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.config-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.config-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\n gap: 20px;\n}\n\n.config-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.config-item.full-width[_ngcontent-%COMP%] {\n grid-column: 1 / -1;\n}\n\n.config-item[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.config-input[_ngcontent-%COMP%] {\n padding: 10px 14px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n font-size: 14px;\n transition: var(--test-transition);\n background: var(--test-surface);\n}\n\n.config-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.config-input[_ngcontent-%COMP%]::placeholder {\n color: var(--test-text-muted);\n}\n\n.config-hint[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--test-text-muted);\n margin-top: 4px;\n}\n\n.config-editor-container[_ngcontent-%COMP%] {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid var(--test-border);\n min-height: 200px;\n}\n\n.config-editor-container.small[_ngcontent-%COMP%] {\n min-height: 100px;\n max-height: 150px;\n}\n\n\n\n\n.runs-tab[_ngcontent-%COMP%], \n.suites-tab[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n\n.loading-state[_ngcontent-%COMP%] {\n padding: 0;\n}\n\n.skeleton-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.skeleton-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.skeleton-icon[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n border-radius: var(--test-radius-md);\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n flex-shrink: 0;\n}\n\n.skeleton-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.skeleton-line[_ngcontent-%COMP%] {\n height: 14px;\n border-radius: 4px;\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n}\n\n.skeleton-line.wide[_ngcontent-%COMP%] { width: 70%; }\n.skeleton-line.narrow[_ngcontent-%COMP%] { width: 40%; }\n\n@keyframes _ngcontent-%COMP%_shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n\n.runs-list[_ngcontent-%COMP%], \n.suites-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.run-item[_ngcontent-%COMP%], \n.suite-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.run-item[_ngcontent-%COMP%]:hover, \n.suite-item[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n box-shadow: var(--test-shadow-sm);\n}\n\n.run-icon[_ngcontent-%COMP%], \n.suite-icon[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--test-radius-md);\n color: var(--mj-text-inverse);\n font-size: 18px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-sm);\n}\n\n.suite-icon[_ngcontent-%COMP%] {\n background: var(--mj-status-warning);\n}\n\n.run-content[_ngcontent-%COMP%], \n.suite-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.run-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 4px;\n}\n\n.run-id[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.run-status[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.suite-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 4px;\n}\n\n.run-meta[_ngcontent-%COMP%], \n.suite-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n font-size: 12px;\n color: var(--test-text-secondary);\n flex-wrap: wrap;\n}\n\n.run-meta[_ngcontent-%COMP%] span[_ngcontent-%COMP%], \n.suite-meta[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.run-meta[_ngcontent-%COMP%] span[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n.suite-meta[_ngcontent-%COMP%] span[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n font-size: 11px;\n}\n\n.run-item[_ngcontent-%COMP%] > i.fa-chevron-right[_ngcontent-%COMP%], \n.suite-item[_ngcontent-%COMP%] > i.fa-chevron-right[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.run-item[_ngcontent-%COMP%]:hover > i.fa-chevron-right[_ngcontent-%COMP%], \n.suite-item[_ngcontent-%COMP%]:hover > i.fa-chevron-right[_ngcontent-%COMP%] {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n\n.run-eval-stack[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n flex-wrap: wrap;\n}\n\n\n.eval-pill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n transition: var(--test-transition);\n}\n\n.eval-pill[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n\n.eval-pill.status-pill.status-passed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.eval-pill.status-pill.status-failed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.eval-pill.status-pill.status-error[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.eval-pill.status-pill.status-timeout[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.eval-pill.status-pill.status-skipped[_ngcontent-%COMP%], \n.eval-pill.status-pill.status-pending[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.eval-pill.status-pill.status-running[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n\n.eval-pill.human-pill.no-feedback[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n padding: 4px 8px;\n}\n\n.eval-pill.human-pill.has-feedback.rating-low[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.eval-pill.human-pill.has-feedback.rating-medium[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.eval-pill.human-pill.has-feedback.rating-good[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.eval-pill.human-pill.has-feedback.rating-excellent[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n\n.eval-pill.auto-pill.no-score[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n padding: 4px 8px;\n}\n\n.eval-pill.auto-pill.has-score.score-low[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.eval-pill.auto-pill.has-score.score-medium[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.eval-pill.auto-pill.has-score.score-good[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.eval-pill.auto-pill.has-score.score-excellent[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n\n.run-tags[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 8px;\n flex-wrap: wrap;\n}\n\n.run-tag[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--test-primary);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n}\n\n.run-tag-more[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n background: var(--test-border);\n color: var(--test-text-muted);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n}\n\n\n\n\n\n.shortcuts-toggle[_ngcontent-%COMP%] {\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n box-shadow: var(--test-shadow-md);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--test-text-secondary);\n font-size: 14px;\n z-index: 99;\n transition: var(--test-transition);\n opacity: 0.7;\n}\n\n.shortcuts-toggle[_ngcontent-%COMP%]:hover {\n opacity: 1;\n transform: scale(1.1);\n color: var(--test-primary);\n border-color: var(--test-primary);\n}\n\n.keyboard-shortcuts[_ngcontent-%COMP%] {\n position: fixed;\n bottom: 20px;\n right: 20px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 12px 16px;\n box-shadow: var(--test-shadow-lg);\n font-size: 12px;\n color: var(--test-text-secondary);\n z-index: 100;\n max-width: 260px;\n}\n\n.shortcuts-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-bottom: 10px;\n padding-bottom: 8px;\n border-bottom: 1px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text);\n}\n\n.shortcuts-close[_ngcontent-%COMP%] {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--test-text-muted);\n font-size: 12px;\n padding: 2px 4px;\n border-radius: 4px;\n transition: var(--test-transition);\n}\n\n.shortcuts-close[_ngcontent-%COMP%]:hover {\n color: var(--test-text);\n background: var(--test-border);\n}\n\n.shortcut-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.shortcut-item[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.shortcut-keys[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.shortcut-keys[_ngcontent-%COMP%] kbd[_ngcontent-%COMP%] {\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: 4px;\n padding: 2px 6px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n font-size: 11px;\n color: var(--test-text);\n}\n\n\n\n\n@media (max-width: 1024px) {\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .info-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .config-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .keyboard-shortcuts[_ngcontent-%COMP%], .shortcuts-toggle[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n\n\n\n@media (max-width: 768px) {\n .test-form[_ngcontent-%COMP%] {\n height: auto;\n min-height: 100%;\n }\n\n .test-header[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .header-content[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-left[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .test-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n font-size: 20px;\n }\n\n .test-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 18px;\n }\n\n .test-meta[_ngcontent-%COMP%] {\n gap: 8px;\n }\n\n .status-badge[_ngcontent-%COMP%] {\n padding: 4px 10px;\n font-size: 11px;\n }\n\n .header-actions[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n flex: 1;\n }\n\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n gap: 10px;\n }\n\n .metric-card[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .metric-value[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .tabs[_ngcontent-%COMP%] {\n padding: 0 12px;\n }\n\n .tab[_ngcontent-%COMP%] {\n padding: 12px 14px;\n font-size: 13px;\n gap: 6px;\n }\n\n .tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .tab-shortcut[_ngcontent-%COMP%] {\n display: none;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .info-section[_ngcontent-%COMP%], \n .json-section[_ngcontent-%COMP%], \n .config-section[_ngcontent-%COMP%] {\n padding: 18px;\n }\n\n .info-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .json-tabs[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .json-tab[_ngcontent-%COMP%] {\n min-width: 0;\n justify-content: flex-start;\n }\n\n .run-item[_ngcontent-%COMP%], \n .suite-item[_ngcontent-%COMP%] {\n padding: 14px;\n }\n\n .run-icon[_ngcontent-%COMP%], \n .suite-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 16px;\n }\n\n .run-meta[_ngcontent-%COMP%], \n .suite-meta[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 4px;\n }\n\n}\n\n\n\n\n@media (max-width: 480px) {\n .test-header[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .header-left[_ngcontent-%COMP%] {\n gap: 12px;\n }\n\n .test-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 18px;\n border-radius: 8px;\n }\n\n .test-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: 1fr 1fr;\n }\n\n .tabs[_ngcontent-%COMP%] {\n padding: 0 8px;\n }\n\n .tab[_ngcontent-%COMP%] {\n padding: 10px 12px;\n font-size: 12px;\n }\n\n .tab-badge[_ngcontent-%COMP%] {\n display: none;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .run-header[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: flex-start;\n gap: 4px;\n }\n}\n\n\n\n\n@media (hover: none) and (pointer: coarse) {\n .tab[_ngcontent-%COMP%], \n .json-tab[_ngcontent-%COMP%], \n .run-item[_ngcontent-%COMP%], \n .suite-item[_ngcontent-%COMP%] {\n -webkit-tap-highlight-color: transparent;\n }\n\n .run-item[_ngcontent-%COMP%]:active, \n .suite-item[_ngcontent-%COMP%]:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n transform: scale(0.98);\n }\n\n .tab[_ngcontent-%COMP%]:active, \n .json-tab[_ngcontent-%COMP%]:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n }\n\n \n .tab[_ngcontent-%COMP%] {\n min-height: 48px;\n }\n\n .run-item[_ngcontent-%COMP%], \n .suite-item[_ngcontent-%COMP%] {\n min-height: 64px;\n }\n}\n\n\n\n\n@media (prefers-reduced-motion: reduce) {\n *[_ngcontent-%COMP%], \n *[_ngcontent-%COMP%]::before, \n *[_ngcontent-%COMP%]::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n\n .skeleton-icon[_ngcontent-%COMP%], \n .skeleton-line[_ngcontent-%COMP%] {\n animation: none;\n background: var(--mj-border-default);\n }\n}\n\n\n\n\n.history-tab[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.history-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 24px;\n}\n\n\n.history-filters[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 16px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n box-shadow: var(--test-shadow-sm);\n}\n\n.time-range-filters[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.filter-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--test-text-secondary);\n margin-right: 4px;\n}\n\n.filter-btn[_ngcontent-%COMP%] {\n padding: 8px 16px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.filter-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--test-primary-light);\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.filter-btn.active[_ngcontent-%COMP%] {\n background: var(--test-primary);\n color: var(--mj-text-inverse);\n border-color: var(--test-primary);\n}\n\n.history-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n\n.history-kpi-cards[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 16px;\n}\n\n.kpi-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 18px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n box-shadow: var(--test-shadow-sm);\n transition: var(--test-transition);\n}\n\n.kpi-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.kpi-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-brand-primary);\n border-radius: var(--test-radius-md);\n color: var(--mj-text-inverse);\n font-size: 20px;\n flex-shrink: 0;\n}\n\n.kpi-icon.pass-rate[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n}\n\n.kpi-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.kpi-value[_ngcontent-%COMP%] {\n font-size: 22px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.kpi-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-top: 2px;\n}\n\n.trend-icon[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.trend-icon.trend-up[_ngcontent-%COMP%] {\n color: var(--test-success);\n}\n\n.trend-icon.trend-down[_ngcontent-%COMP%] {\n color: var(--test-error);\n}\n\n\n.history-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.history-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.history-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n\n.history-table-container[_ngcontent-%COMP%] {\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.history-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 14px;\n}\n\n.history-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%], \n.history-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 12px 16px;\n text-align: left;\n border-bottom: 1px solid var(--test-border);\n}\n\n.history-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n}\n\n.history-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 3%, transparent);\n}\n\n.date-cell[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--test-text);\n}\n\n.passed-cell[_ngcontent-%COMP%] {\n color: var(--test-success);\n font-weight: 600;\n}\n\n.failed-cell[_ngcontent-%COMP%] {\n color: var(--test-error);\n font-weight: 600;\n}\n\n.pass-rate-cell[_ngcontent-%COMP%] {\n min-width: 120px;\n}\n\n.pass-rate-bar[_ngcontent-%COMP%] {\n position: relative;\n height: 24px;\n background: var(--test-bg);\n border-radius: 12px;\n overflow: hidden;\n}\n\n.pass-rate-fill[_ngcontent-%COMP%] {\n position: absolute;\n left: 0;\n top: 0;\n height: 100%;\n background: var(--mj-status-success);\n border-radius: 12px;\n transition: width 0.5s ease-out;\n}\n\n.pass-rate-text[_ngcontent-%COMP%] {\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n font-size: 11px;\n font-weight: 700;\n color: var(--test-text);\n z-index: 1;\n}\n\n\n.suite-performance-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.suite-perf-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 18px;\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.suite-perf-card[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n}\n\n.suite-perf-header[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.suite-perf-name[_ngcontent-%COMP%] {\n font-size: 15px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 6px;\n}\n\n.suite-perf-tags[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.tag-mini[_ngcontent-%COMP%] {\n display: inline-flex;\n padding: 2px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--test-primary);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n}\n\n.tag-more[_ngcontent-%COMP%] {\n display: inline-flex;\n padding: 2px 8px;\n background: var(--test-border);\n color: var(--test-text-muted);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n}\n\n.suite-perf-stats[_ngcontent-%COMP%] {\n display: flex;\n gap: 24px;\n flex-wrap: wrap;\n}\n\n.suite-stat[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 2px;\n}\n\n.suite-stat[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n.suite-stat[_ngcontent-%COMP%] .stat-value.pass-rate.high[_ngcontent-%COMP%] {\n color: var(--test-success);\n}\n\n.suite-stat[_ngcontent-%COMP%] .stat-value.pass-rate.low[_ngcontent-%COMP%] {\n color: var(--test-error);\n}\n\n.suite-stat[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--test-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.suite-perf-arrow[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.suite-perf-card[_ngcontent-%COMP%]:hover .suite-perf-arrow[_ngcontent-%COMP%] {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n\n\n\n@media print {\n .test-form[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n height: auto;\n }\n\n .header-actions[_ngcontent-%COMP%], \n .tabs-container[_ngcontent-%COMP%], \n .keyboard-shortcuts[_ngcontent-%COMP%] {\n display: none !important;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n overflow: visible;\n padding: 0;\n }\n\n .info-section[_ngcontent-%COMP%], \n .json-section[_ngcontent-%COMP%], \n .config-section[_ngcontent-%COMP%] {\n break-inside: avoid;\n box-shadow: none;\n border: 1px solid var(--mj-border-default);\n }\n}\n\n\n\n\n\n.edit-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.edit-section-header[_ngcontent-%COMP%] {\n margin: 0 0 18px 0;\n}\n\n.edit-section-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 4px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.edit-section-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.edit-section-sub[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.edit-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 18px;\n}\n\n@media (max-width: 720px) {\n .edit-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n}\n\n.edit-field[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n min-width: 0;\n}\n\n.edit-field--full[_ngcontent-%COMP%] {\n grid-column: 1 / -1;\n}\n\n.edit-field[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.edit-field[_ngcontent-%COMP%] .required[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n margin-left: 2px;\n}\n\n.config-textarea[_ngcontent-%COMP%] {\n resize: vertical;\n min-height: 72px;\n font-family: inherit;\n line-height: 1.5;\n}\n\n.select-wrapper[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.select-wrapper[_ngcontent-%COMP%] select.config-input[_ngcontent-%COMP%] {\n padding-right: 36px;\n appearance: none;\n background-color: var(--test-surface);\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%2364748b' d='M1.41 0L6 4.59 10.59 0 12 1.41l-6 6-6-6z'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 14px center;\n background-size: 10px 7px;\n}\n\n\n.tag-editor[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 8px 10px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n transition: var(--test-transition);\n cursor: text;\n min-height: 42px;\n align-items: center;\n}\n\n.tag-editor[_ngcontent-%COMP%]:focus-within {\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.tag-chip-editable[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 4px 3px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n border-radius: 999px;\n font-size: 12px;\n font-weight: 600;\n line-height: 1;\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n}\n\n.tag-chip-editable[_ngcontent-%COMP%] .tag-remove[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n border: none;\n background: transparent;\n color: var(--mj-brand-primary);\n cursor: pointer;\n font-size: 10px;\n transition: background 0.15s;\n}\n\n.tag-chip-editable[_ngcontent-%COMP%] .tag-remove[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n color: var(--mj-brand-primary-hover);\n}\n\n.tag-input-inline[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 140px;\n border: none;\n background: transparent;\n outline: none;\n font-size: 13px;\n color: var(--test-text);\n padding: 4px 2px;\n}\n\n.tag-input-inline[_ngcontent-%COMP%]::placeholder {\n color: var(--test-text-muted);\n}\n\n\n.meta-section[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--test-radius-md);\n padding: 14px 18px;\n border: 1px solid var(--test-border);\n}\n\n.meta-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 14px;\n}\n\n.meta-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.meta-label[_ngcontent-%COMP%] {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.meta-value[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-secondary);\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.meta-mono[_ngcontent-%COMP%] {\n font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;\n font-size: 11px;\n}\n\n\n.dirty-indicator[_ngcontent-%COMP%] {\n display: inline-block;\n margin-left: 8px;\n font-size: 14px;\n color: var(--mj-status-warning);\n line-height: 1;\n animation: _ngcontent-%COMP%_pulseDot 1.8s ease-in-out infinite;\n vertical-align: middle;\n}\n\n@keyframes _ngcontent-%COMP%_pulseDot {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.5; transform: scale(0.85); }\n}\n\n.unsaved-pill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n border-radius: 999px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.4px;\n}\n\n.unsaved-pill[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 6px;\n animation: _ngcontent-%COMP%_pulseDot 1.8s ease-in-out infinite;\n}\n\n\n\n.tab-content.has-savebar[_ngcontent-%COMP%] {\n padding-bottom: 84px;\n}\n\n\n\n\n\n.save-bar[_ngcontent-%COMP%] {\n position: absolute;\n left: 16px;\n right: 96px; \n bottom: 16px;\n z-index: 50;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n padding: 12px 16px 12px 20px;\n background: var(--mj-bg-surface-elevated, var(--test-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 25%, var(--test-border));\n border-radius: 14px;\n box-shadow: 0 12px 32px color-mix(in srgb, var(--mj-status-warning) 10%, rgba(0, 0, 0, 0.18));\n backdrop-filter: blur(8px);\n \n\n\n opacity: 0;\n transform: translateY(calc(100% + 32px));\n pointer-events: none;\n transition:\n transform 420ms cubic-bezier(0.16, 1, 0.3, 1),\n opacity 260ms cubic-bezier(0.16, 1, 0.3, 1);\n will-change: transform, opacity;\n}\n\n.save-bar--visible[_ngcontent-%COMP%] {\n opacity: 1;\n transform: translateY(0);\n pointer-events: auto;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .save-bar[_ngcontent-%COMP%] {\n transition: opacity 180ms ease-out;\n transform: none;\n }\n .save-bar--visible[_ngcontent-%COMP%] {\n transform: none;\n }\n}\n\n.save-bar-message[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n min-width: 0;\n}\n\n.save-bar-dot[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n font-size: 12px;\n line-height: 1;\n animation: _ngcontent-%COMP%_pulseDot 1.8s ease-in-out infinite;\n}\n\n.save-bar-text[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.save-bar-text[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--test-text);\n font-weight: 700;\n}\n\n.save-bar-fields[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.save-bar-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.save-bar-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 9px 16px;\n font-size: 13px;\n font-weight: 600;\n border-radius: 8px;\n border: 1px solid transparent;\n cursor: pointer;\n transition: var(--test-transition);\n font-family: inherit;\n}\n\n.save-bar-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.save-bar-btn--primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, white);\n border-color: var(--mj-brand-primary);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n}\n\n.save-bar-btn--primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n transform: translateY(-1px);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 45%, transparent);\n}\n\n.save-bar-btn--primary[_ngcontent-%COMP%]:active:not(:disabled) {\n transform: translateY(0);\n}\n\n.save-bar-btn--ghost[_ngcontent-%COMP%] {\n background: transparent;\n color: var(--test-text-secondary);\n border-color: var(--test-border);\n}\n\n.save-bar-btn--ghost[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n border-color: var(--test-text-muted);\n}\n\n.save-bar-kbd[_ngcontent-%COMP%] {\n display: inline-flex;\n gap: 3px;\n margin-left: 6px;\n opacity: 0.85;\n}\n\n.save-bar-kbd[_ngcontent-%COMP%] kbd[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 4px;\n font-size: 10px;\n font-weight: 600;\n font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;\n background: color-mix(in srgb, white 18%, transparent);\n border: 1px solid color-mix(in srgb, white 35%, transparent);\n border-radius: 4px;\n color: inherit;\n}\n\n@media (max-width: 640px) {\n .save-bar[_ngcontent-%COMP%] {\n left: 8px;\n right: 8px;\n bottom: 88px; \n flex-direction: column;\n align-items: stretch;\n padding: 12px;\n }\n .save-bar-actions[_ngcontent-%COMP%] {\n justify-content: space-between;\n }\n .save-bar-kbd[_ngcontent-%COMP%] {\n display: none;\n }\n}"], changeDetection: 0 }); }
2785
+ } }, dependencies: [i1.NgClass, i2.NgSelectOption, i2.ɵNgSelectMultipleOption, i2.DefaultValueAccessor, i2.NumberValueAccessor, i2.SelectControlValueAccessor, i2.NgControlStatus, i2.MinValidator, i2.NgModel, i3.MJEmptyStateComponent, i3.MJSectionPickerComponent, i3.MJButtonDirective, i4.CodeEditorComponent, i5.TestRunDialogComponent, i5.EvaluationModeToggleComponent, i6.LoadingComponent, i3.MjSlidePanelComponent, i7.EntityLinkPillComponent, i1.DatePipe], styles: ["\n\n\n\n\n\n[_nghost-%COMP%] {\n --test-primary: var(--mj-brand-primary);\n --test-primary-light: var(--mj-brand-primary);\n --test-primary-dark: var(--mj-brand-primary-hover);\n --test-success: var(--mj-status-success);\n --test-success-light: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n --test-error: var(--mj-status-error);\n --test-error-light: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n --test-warning: var(--mj-status-warning);\n --test-warning-light: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n --test-disabled: var(--mj-text-muted);\n --test-bg: var(--mj-bg-surface-card);\n --test-surface: var(--mj-bg-surface);\n --test-border: var(--mj-border-default);\n --test-text: var(--mj-text-primary);\n --test-text-secondary: var(--mj-text-muted);\n --test-text-muted: var(--mj-text-disabled);\n --test-radius-sm: 6px;\n --test-radius-md: 10px;\n --test-radius-lg: 16px;\n --test-shadow-sm: var(--mj-shadow-sm);\n --test-shadow-md: var(--mj-shadow-md);\n --test-shadow-lg: var(--mj-shadow-lg);\n --test-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n display: block;\n height: 100%;\n}\n\n\n.breadcrumb[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] ol[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n list-style: none;\n margin: 0;\n padding: 0;\n font-size: 13px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] li[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] a[_ngcontent-%COMP%] {\n color: var(--test-primary);\n text-decoration: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n border-radius: 6px;\n transition: background 0.15s;\n}\n\n.breadcrumb[_ngcontent-%COMP%] a[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n text-decoration: none;\n}\n\n.breadcrumb[_ngcontent-%COMP%] .separator[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--test-text-muted);\n margin: 0 4px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] .current[_ngcontent-%COMP%] {\n color: var(--test-text-secondary);\n font-weight: 500;\n}\n\n.breadcrumb-text[_ngcontent-%COMP%] {\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n\n.test-form[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--test-bg);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n\n\n\n.test-header[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n padding: 20px;\n}\n\n.header-content[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 16px;\n gap: 16px;\n}\n\n.header-left[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n flex: 1;\n min-width: 0;\n}\n\n\n.test-icon[_ngcontent-%COMP%] {\n width: 56px;\n height: 56px;\n border-radius: var(--test-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-inverse);\n font-size: 24px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-md);\n transition: var(--test-transition);\n}\n\n.test-icon[_ngcontent-%COMP%]:hover {\n transform: scale(1.05);\n}\n\n\n.test-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.test-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: clamp(18px, 4vw, 24px);\n font-weight: 700;\n color: var(--test-text);\n line-height: 1.2;\n word-wrap: break-word;\n}\n\n.test-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n color: var(--mj-text-inverse);\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.status-badge.status-active[_ngcontent-%COMP%] { background: var(--mj-status-success); }\n.status-badge.status-disabled[_ngcontent-%COMP%] { background: var(--mj-text-secondary); }\n.status-badge.status-pending[_ngcontent-%COMP%] { background: var(--mj-status-warning); }\n\n.status-badge-inline[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 2px 10px;\n border-radius: 10px;\n color: var(--mj-text-inverse);\n font-size: 11px;\n font-weight: 600;\n}\n\n.status-badge-inline.status-active[_ngcontent-%COMP%] { background: var(--test-success); }\n.status-badge-inline.status-disabled[_ngcontent-%COMP%] { background: var(--test-disabled); }\n.status-badge-inline.status-pending[_ngcontent-%COMP%] { background: var(--test-warning); }\n\n.test-type[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 14px;\n color: var(--test-text-secondary);\n padding: 4px 10px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.header-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n white-space: nowrap;\n}\n\n\n.test-description[_ngcontent-%COMP%] {\n padding: 16px;\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--test-radius-md);\n margin-bottom: 16px;\n border: 1px solid var(--test-border);\n}\n\n.test-description[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n color: var(--test-text-secondary);\n line-height: 1.6;\n font-size: 14px;\n}\n\n\n\n\n.metrics-bar[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));\n gap: 12px;\n}\n\n.metric-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 14px;\n text-align: center;\n transition: var(--test-transition);\n}\n\n.metric-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.metric-label[_ngcontent-%COMP%] {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n margin-bottom: 6px;\n}\n\n.metric-value[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n\n.metric-progress[_ngcontent-%COMP%] {\n margin-top: 8px;\n height: 4px;\n background: var(--test-border);\n border-radius: 2px;\n overflow: hidden;\n}\n\n.metric-progress-fill[_ngcontent-%COMP%] {\n height: 100%;\n background: var(--mj-status-success);\n border-radius: 2px;\n transition: width 0.5s ease-out;\n}\n\n\n\n\n.tabs-container[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n position: sticky;\n top: 0;\n z-index: 10;\n}\n\n\n.phone-section-picker[_ngcontent-%COMP%] {\n display: none;\n}\n\n.tabs[_ngcontent-%COMP%] {\n display: flex;\n padding: 0 20px;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n -ms-overflow-style: none;\n}\n\n.tabs[_ngcontent-%COMP%]::-webkit-scrollbar {\n display: none;\n}\n\n.tab[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 14px 18px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: var(--test-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n white-space: nowrap;\n}\n\n.tab[_ngcontent-%COMP%]:hover {\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.tab.active[_ngcontent-%COMP%] {\n color: var(--test-primary);\n border-bottom-color: var(--test-primary);\n font-weight: 600;\n}\n\n.tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 15px;\n}\n\n.tab-badge[_ngcontent-%COMP%] {\n background: var(--test-border);\n color: var(--test-text-secondary);\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n transition: var(--test-transition);\n}\n\n.tab.active[_ngcontent-%COMP%] .tab-badge[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n color: var(--test-primary);\n}\n\n.tab-shortcut[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n margin-left: 4px;\n}\n\n\n\n\n.tab-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n scroll-behavior: smooth;\n}\n\n\n\n\n.overview-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n\n.info-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.info-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.info-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.info-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n}\n\n.info-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.info-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.info-value[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--test-text);\n word-wrap: break-word;\n font-weight: 500;\n}\n\n\n.json-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.json-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.json-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.json-tabs[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n margin-bottom: 16px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n padding: 4px;\n flex-wrap: wrap;\n}\n\n.json-tab[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 100px;\n padding: 10px 14px;\n border: none;\n background: transparent;\n color: var(--test-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n border-radius: var(--test-radius-sm);\n transition: var(--test-transition);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n}\n\n.json-tab[_ngcontent-%COMP%]:hover {\n color: var(--test-text);\n background: var(--mj-bg-overlay);\n}\n\n.json-tab.active[_ngcontent-%COMP%] {\n background: var(--test-surface);\n color: var(--test-primary);\n font-weight: 600;\n box-shadow: var(--test-shadow-sm);\n}\n\n.json-tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.code-editor-container[_ngcontent-%COMP%] {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid var(--test-border);\n min-height: 200px;\n max-height: 400px;\n}\n\n\n\n\n.config-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.config-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.config-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.config-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.config-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\n gap: 20px;\n}\n\n.config-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.config-item.full-width[_ngcontent-%COMP%] {\n grid-column: 1 / -1;\n}\n\n.config-item[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.config-input[_ngcontent-%COMP%] {\n padding: 10px 14px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n font-size: 14px;\n transition: var(--test-transition);\n background: var(--test-surface);\n}\n\n.config-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.config-input[_ngcontent-%COMP%]::placeholder {\n color: var(--test-text-muted);\n}\n\n.config-hint[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--test-text-muted);\n margin-top: 4px;\n}\n\n.config-editor-container[_ngcontent-%COMP%] {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid var(--test-border);\n min-height: 200px;\n}\n\n.config-editor-container.small[_ngcontent-%COMP%] {\n min-height: 100px;\n max-height: 150px;\n}\n\n\n\n\n.runs-tab[_ngcontent-%COMP%], \n.suites-tab[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n\n.loading-state[_ngcontent-%COMP%] {\n padding: 0;\n}\n\n.skeleton-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.skeleton-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.skeleton-icon[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n border-radius: var(--test-radius-md);\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n flex-shrink: 0;\n}\n\n.skeleton-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.skeleton-line[_ngcontent-%COMP%] {\n height: 14px;\n border-radius: 4px;\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n}\n\n.skeleton-line.wide[_ngcontent-%COMP%] { width: 70%; }\n.skeleton-line.narrow[_ngcontent-%COMP%] { width: 40%; }\n\n@keyframes _ngcontent-%COMP%_shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n\n.runs-list[_ngcontent-%COMP%], \n.suites-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.run-item[_ngcontent-%COMP%], \n.suite-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.run-item[_ngcontent-%COMP%]:hover, \n.suite-item[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n box-shadow: var(--test-shadow-sm);\n}\n\n.run-icon[_ngcontent-%COMP%], \n.suite-icon[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--test-radius-md);\n color: var(--mj-text-inverse);\n font-size: 18px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-sm);\n}\n\n.suite-icon[_ngcontent-%COMP%] {\n background: var(--mj-status-warning);\n}\n\n.run-content[_ngcontent-%COMP%], \n.suite-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.run-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 4px;\n}\n\n.run-id[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.run-status[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.suite-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 4px;\n}\n\n.run-meta[_ngcontent-%COMP%], \n.suite-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n font-size: 12px;\n color: var(--test-text-secondary);\n flex-wrap: wrap;\n}\n\n.run-meta[_ngcontent-%COMP%] span[_ngcontent-%COMP%], \n.suite-meta[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.run-meta[_ngcontent-%COMP%] span[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n.suite-meta[_ngcontent-%COMP%] span[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n font-size: 11px;\n}\n\n.run-item[_ngcontent-%COMP%] > i.fa-chevron-right[_ngcontent-%COMP%], \n.suite-item[_ngcontent-%COMP%] > i.fa-chevron-right[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.run-item[_ngcontent-%COMP%]:hover > i.fa-chevron-right[_ngcontent-%COMP%], \n.suite-item[_ngcontent-%COMP%]:hover > i.fa-chevron-right[_ngcontent-%COMP%] {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n\n.run-eval-stack[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n flex-wrap: wrap;\n}\n\n\n.eval-pill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n transition: var(--test-transition);\n}\n\n.eval-pill[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n\n.eval-pill.status-pill.status-passed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.eval-pill.status-pill.status-failed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.eval-pill.status-pill.status-error[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.eval-pill.status-pill.status-timeout[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.eval-pill.status-pill.status-skipped[_ngcontent-%COMP%], \n.eval-pill.status-pill.status-pending[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.eval-pill.status-pill.status-running[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n\n.eval-pill.human-pill.no-feedback[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n padding: 4px 8px;\n}\n\n.eval-pill.human-pill.has-feedback.rating-low[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.eval-pill.human-pill.has-feedback.rating-medium[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.eval-pill.human-pill.has-feedback.rating-good[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.eval-pill.human-pill.has-feedback.rating-excellent[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n\n.eval-pill.auto-pill.no-score[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n padding: 4px 8px;\n}\n\n.eval-pill.auto-pill.has-score.score-low[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.eval-pill.auto-pill.has-score.score-medium[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.eval-pill.auto-pill.has-score.score-good[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.eval-pill.auto-pill.has-score.score-excellent[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n\n.run-tags[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 8px;\n flex-wrap: wrap;\n}\n\n.run-tag[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--test-primary);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n}\n\n.run-tag-more[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n background: var(--test-border);\n color: var(--test-text-muted);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n}\n\n\n\n\n\n.shortcuts-toggle[_ngcontent-%COMP%] {\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n box-shadow: var(--test-shadow-md);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--test-text-secondary);\n font-size: 14px;\n z-index: 99;\n transition: var(--test-transition);\n opacity: 0.7;\n}\n\n.shortcuts-toggle[_ngcontent-%COMP%]:hover {\n opacity: 1;\n transform: scale(1.1);\n color: var(--test-primary);\n border-color: var(--test-primary);\n}\n\n.keyboard-shortcuts[_ngcontent-%COMP%] {\n position: fixed;\n bottom: 20px;\n right: 20px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 12px 16px;\n box-shadow: var(--test-shadow-lg);\n font-size: 12px;\n color: var(--test-text-secondary);\n z-index: 100;\n max-width: 260px;\n}\n\n.shortcuts-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-bottom: 10px;\n padding-bottom: 8px;\n border-bottom: 1px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text);\n}\n\n.shortcuts-close[_ngcontent-%COMP%] {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--test-text-muted);\n font-size: 12px;\n padding: 2px 4px;\n border-radius: 4px;\n transition: var(--test-transition);\n}\n\n.shortcuts-close[_ngcontent-%COMP%]:hover {\n color: var(--test-text);\n background: var(--test-border);\n}\n\n.shortcut-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.shortcut-item[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.shortcut-keys[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.shortcut-keys[_ngcontent-%COMP%] kbd[_ngcontent-%COMP%] {\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: 4px;\n padding: 2px 6px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n font-size: 11px;\n color: var(--test-text);\n}\n\n\n\n\n@media (max-width: 1024px) {\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .info-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .config-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .keyboard-shortcuts[_ngcontent-%COMP%], .shortcuts-toggle[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n\n\n\n@media (max-width: 768px) {\n \n .tabs[_ngcontent-%COMP%] {\n display: none;\n }\n\n .phone-section-picker[_ngcontent-%COMP%] {\n display: block;\n padding: 4px 8px;\n }\n\n .test-form[_ngcontent-%COMP%] {\n height: auto;\n min-height: 100%;\n }\n\n .test-header[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .header-content[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-left[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .test-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n font-size: 20px;\n }\n\n .test-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 18px;\n }\n\n .test-meta[_ngcontent-%COMP%] {\n gap: 8px;\n }\n\n .status-badge[_ngcontent-%COMP%] {\n padding: 4px 10px;\n font-size: 11px;\n }\n\n .header-actions[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n flex: 1;\n }\n\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n gap: 10px;\n }\n\n .metric-card[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .metric-value[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .tabs[_ngcontent-%COMP%] {\n padding: 0 12px;\n }\n\n .tab[_ngcontent-%COMP%] {\n padding: 12px 14px;\n font-size: 13px;\n gap: 6px;\n }\n\n .tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .tab-shortcut[_ngcontent-%COMP%] {\n display: none;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .info-section[_ngcontent-%COMP%], \n .json-section[_ngcontent-%COMP%], \n .config-section[_ngcontent-%COMP%] {\n padding: 18px;\n }\n\n .info-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .json-tabs[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .json-tab[_ngcontent-%COMP%] {\n min-width: 0;\n justify-content: flex-start;\n }\n\n .run-item[_ngcontent-%COMP%], \n .suite-item[_ngcontent-%COMP%] {\n padding: 14px;\n }\n\n .run-icon[_ngcontent-%COMP%], \n .suite-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 16px;\n }\n\n .run-meta[_ngcontent-%COMP%], \n .suite-meta[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 4px;\n }\n\n}\n\n\n\n\n@media (max-width: 480px) {\n .test-header[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .header-left[_ngcontent-%COMP%] {\n gap: 12px;\n }\n\n .test-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 18px;\n border-radius: 8px;\n }\n\n .test-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: 1fr 1fr;\n }\n\n .tabs[_ngcontent-%COMP%] {\n padding: 0 8px;\n }\n\n .tab[_ngcontent-%COMP%] {\n padding: 10px 12px;\n font-size: 12px;\n }\n\n .tab-badge[_ngcontent-%COMP%] {\n display: none;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .run-header[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: flex-start;\n gap: 4px;\n }\n}\n\n\n\n\n@media (hover: none) and (pointer: coarse) {\n .tab[_ngcontent-%COMP%], \n .json-tab[_ngcontent-%COMP%], \n .run-item[_ngcontent-%COMP%], \n .suite-item[_ngcontent-%COMP%] {\n -webkit-tap-highlight-color: transparent;\n }\n\n .run-item[_ngcontent-%COMP%]:active, \n .suite-item[_ngcontent-%COMP%]:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n transform: scale(0.98);\n }\n\n .tab[_ngcontent-%COMP%]:active, \n .json-tab[_ngcontent-%COMP%]:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n }\n\n \n .tab[_ngcontent-%COMP%] {\n min-height: 48px;\n }\n\n .run-item[_ngcontent-%COMP%], \n .suite-item[_ngcontent-%COMP%] {\n min-height: 64px;\n }\n}\n\n\n\n\n@media (prefers-reduced-motion: reduce) {\n *[_ngcontent-%COMP%], \n *[_ngcontent-%COMP%]::before, \n *[_ngcontent-%COMP%]::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n\n .skeleton-icon[_ngcontent-%COMP%], \n .skeleton-line[_ngcontent-%COMP%] {\n animation: none;\n background: var(--mj-border-default);\n }\n}\n\n\n\n\n.history-tab[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.history-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 24px;\n}\n\n\n.history-filters[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 16px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n box-shadow: var(--test-shadow-sm);\n}\n\n.time-range-filters[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.filter-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--test-text-secondary);\n margin-right: 4px;\n}\n\n.filter-btn[_ngcontent-%COMP%] {\n padding: 8px 16px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.filter-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--test-primary-light);\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.filter-btn.active[_ngcontent-%COMP%] {\n background: var(--test-primary);\n color: var(--mj-text-inverse);\n border-color: var(--test-primary);\n}\n\n.history-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n\n.history-kpi-cards[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 16px;\n}\n\n.kpi-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 18px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n box-shadow: var(--test-shadow-sm);\n transition: var(--test-transition);\n}\n\n.kpi-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.kpi-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-brand-primary);\n border-radius: var(--test-radius-md);\n color: var(--mj-text-inverse);\n font-size: 20px;\n flex-shrink: 0;\n}\n\n.kpi-icon.pass-rate[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n}\n\n.kpi-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.kpi-value[_ngcontent-%COMP%] {\n font-size: 22px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.kpi-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-top: 2px;\n}\n\n.trend-icon[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.trend-icon.trend-up[_ngcontent-%COMP%] {\n color: var(--test-success);\n}\n\n.trend-icon.trend-down[_ngcontent-%COMP%] {\n color: var(--test-error);\n}\n\n\n.history-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.history-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.history-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n\n.history-table-container[_ngcontent-%COMP%] {\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.history-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 14px;\n}\n\n.history-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%], \n.history-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 12px 16px;\n text-align: left;\n border-bottom: 1px solid var(--test-border);\n}\n\n.history-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n}\n\n.history-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 3%, transparent);\n}\n\n.date-cell[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--test-text);\n}\n\n.passed-cell[_ngcontent-%COMP%] {\n color: var(--test-success);\n font-weight: 600;\n}\n\n.failed-cell[_ngcontent-%COMP%] {\n color: var(--test-error);\n font-weight: 600;\n}\n\n.pass-rate-cell[_ngcontent-%COMP%] {\n min-width: 120px;\n}\n\n.pass-rate-bar[_ngcontent-%COMP%] {\n position: relative;\n height: 24px;\n background: var(--test-bg);\n border-radius: 12px;\n overflow: hidden;\n}\n\n.pass-rate-fill[_ngcontent-%COMP%] {\n position: absolute;\n left: 0;\n top: 0;\n height: 100%;\n background: var(--mj-status-success);\n border-radius: 12px;\n transition: width 0.5s ease-out;\n}\n\n.pass-rate-text[_ngcontent-%COMP%] {\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n font-size: 11px;\n font-weight: 700;\n color: var(--test-text);\n z-index: 1;\n}\n\n\n.suite-performance-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.suite-perf-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 18px;\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.suite-perf-card[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n}\n\n.suite-perf-header[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.suite-perf-name[_ngcontent-%COMP%] {\n font-size: 15px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 6px;\n}\n\n.suite-perf-tags[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.tag-mini[_ngcontent-%COMP%] {\n display: inline-flex;\n padding: 2px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--test-primary);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n}\n\n.tag-more[_ngcontent-%COMP%] {\n display: inline-flex;\n padding: 2px 8px;\n background: var(--test-border);\n color: var(--test-text-muted);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n}\n\n.suite-perf-stats[_ngcontent-%COMP%] {\n display: flex;\n gap: 24px;\n flex-wrap: wrap;\n}\n\n.suite-stat[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 2px;\n}\n\n.suite-stat[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n.suite-stat[_ngcontent-%COMP%] .stat-value.pass-rate.high[_ngcontent-%COMP%] {\n color: var(--test-success);\n}\n\n.suite-stat[_ngcontent-%COMP%] .stat-value.pass-rate.low[_ngcontent-%COMP%] {\n color: var(--test-error);\n}\n\n.suite-stat[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--test-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.suite-perf-arrow[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.suite-perf-card[_ngcontent-%COMP%]:hover .suite-perf-arrow[_ngcontent-%COMP%] {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n\n\n\n@media print {\n .test-form[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n height: auto;\n }\n\n .header-actions[_ngcontent-%COMP%], \n .tabs-container[_ngcontent-%COMP%], \n .keyboard-shortcuts[_ngcontent-%COMP%] {\n display: none !important;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n overflow: visible;\n padding: 0;\n }\n\n .info-section[_ngcontent-%COMP%], \n .json-section[_ngcontent-%COMP%], \n .config-section[_ngcontent-%COMP%] {\n break-inside: avoid;\n box-shadow: none;\n border: 1px solid var(--mj-border-default);\n }\n}\n\n\n\n\n\n.edit-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.edit-section-header[_ngcontent-%COMP%] {\n margin: 0 0 18px 0;\n}\n\n.edit-section-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 4px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.edit-section-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.edit-section-sub[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.edit-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 18px;\n}\n\n@media (max-width: 720px) {\n .edit-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n}\n\n.edit-field[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n min-width: 0;\n}\n\n.edit-field--full[_ngcontent-%COMP%] {\n grid-column: 1 / -1;\n}\n\n.edit-field[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.edit-field[_ngcontent-%COMP%] .required[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n margin-left: 2px;\n}\n\n.config-textarea[_ngcontent-%COMP%] {\n resize: vertical;\n min-height: 72px;\n font-family: inherit;\n line-height: 1.5;\n}\n\n.select-wrapper[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.select-wrapper[_ngcontent-%COMP%] select.config-input[_ngcontent-%COMP%] {\n padding-right: 36px;\n appearance: none;\n background-color: var(--test-surface);\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%2364748b' d='M1.41 0L6 4.59 10.59 0 12 1.41l-6 6-6-6z'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 14px center;\n background-size: 10px 7px;\n}\n\n\n.tag-editor[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 8px 10px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n transition: var(--test-transition);\n cursor: text;\n min-height: 42px;\n align-items: center;\n}\n\n.tag-editor[_ngcontent-%COMP%]:focus-within {\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.tag-chip-editable[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 4px 3px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n border-radius: 999px;\n font-size: 12px;\n font-weight: 600;\n line-height: 1;\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n}\n\n.tag-chip-editable[_ngcontent-%COMP%] .tag-remove[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n border: none;\n background: transparent;\n color: var(--mj-brand-primary);\n cursor: pointer;\n font-size: 10px;\n transition: background 0.15s;\n}\n\n.tag-chip-editable[_ngcontent-%COMP%] .tag-remove[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n color: var(--mj-brand-primary-hover);\n}\n\n.tag-input-inline[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 140px;\n border: none;\n background: transparent;\n outline: none;\n font-size: 13px;\n color: var(--test-text);\n padding: 4px 2px;\n}\n\n.tag-input-inline[_ngcontent-%COMP%]::placeholder {\n color: var(--test-text-muted);\n}\n\n\n.meta-section[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--test-radius-md);\n padding: 14px 18px;\n border: 1px solid var(--test-border);\n}\n\n.meta-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 14px;\n}\n\n.meta-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.meta-label[_ngcontent-%COMP%] {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.meta-value[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-secondary);\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.meta-mono[_ngcontent-%COMP%] {\n font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;\n font-size: 11px;\n}\n\n\n.dirty-indicator[_ngcontent-%COMP%] {\n display: inline-block;\n margin-left: 8px;\n font-size: 14px;\n color: var(--mj-status-warning);\n line-height: 1;\n animation: _ngcontent-%COMP%_pulseDot 1.8s ease-in-out infinite;\n vertical-align: middle;\n}\n\n@keyframes _ngcontent-%COMP%_pulseDot {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.5; transform: scale(0.85); }\n}\n\n.unsaved-pill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n border-radius: 999px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.4px;\n}\n\n.unsaved-pill[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 6px;\n animation: _ngcontent-%COMP%_pulseDot 1.8s ease-in-out infinite;\n}\n\n\n\n.tab-content.has-savebar[_ngcontent-%COMP%] {\n padding-bottom: 84px;\n}\n\n\n\n\n\n.save-bar[_ngcontent-%COMP%] {\n position: absolute;\n left: 16px;\n right: 96px; \n bottom: 16px;\n z-index: 50;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n padding: 12px 16px 12px 20px;\n background: var(--mj-bg-surface-elevated, var(--test-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 25%, var(--test-border));\n border-radius: 14px;\n box-shadow: 0 12px 32px color-mix(in srgb, var(--mj-status-warning) 10%, rgba(0, 0, 0, 0.18));\n backdrop-filter: blur(8px);\n \n\n\n opacity: 0;\n transform: translateY(calc(100% + 32px));\n pointer-events: none;\n transition:\n transform 420ms cubic-bezier(0.16, 1, 0.3, 1),\n opacity 260ms cubic-bezier(0.16, 1, 0.3, 1);\n will-change: transform, opacity;\n}\n\n.save-bar--visible[_ngcontent-%COMP%] {\n opacity: 1;\n transform: translateY(0);\n pointer-events: auto;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .save-bar[_ngcontent-%COMP%] {\n transition: opacity 180ms ease-out;\n transform: none;\n }\n .save-bar--visible[_ngcontent-%COMP%] {\n transform: none;\n }\n}\n\n.save-bar-message[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n min-width: 0;\n}\n\n.save-bar-dot[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n font-size: 12px;\n line-height: 1;\n animation: _ngcontent-%COMP%_pulseDot 1.8s ease-in-out infinite;\n}\n\n.save-bar-text[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.save-bar-text[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--test-text);\n font-weight: 700;\n}\n\n.save-bar-fields[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.save-bar-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.save-bar-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 9px 16px;\n font-size: 13px;\n font-weight: 600;\n border-radius: 8px;\n border: 1px solid transparent;\n cursor: pointer;\n transition: var(--test-transition);\n font-family: inherit;\n}\n\n.save-bar-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.save-bar-btn--primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, white);\n border-color: var(--mj-brand-primary);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n}\n\n.save-bar-btn--primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n transform: translateY(-1px);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 45%, transparent);\n}\n\n.save-bar-btn--primary[_ngcontent-%COMP%]:active:not(:disabled) {\n transform: translateY(0);\n}\n\n.save-bar-btn--ghost[_ngcontent-%COMP%] {\n background: transparent;\n color: var(--test-text-secondary);\n border-color: var(--test-border);\n}\n\n.save-bar-btn--ghost[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n border-color: var(--test-text-muted);\n}\n\n.save-bar-kbd[_ngcontent-%COMP%] {\n display: inline-flex;\n gap: 3px;\n margin-left: 6px;\n opacity: 0.85;\n}\n\n.save-bar-kbd[_ngcontent-%COMP%] kbd[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 4px;\n font-size: 10px;\n font-weight: 600;\n font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;\n background: color-mix(in srgb, white 18%, transparent);\n border: 1px solid color-mix(in srgb, white 35%, transparent);\n border-radius: 4px;\n color: inherit;\n}\n\n@media (max-width: 640px) {\n .save-bar[_ngcontent-%COMP%] {\n left: 8px;\n right: 8px;\n bottom: 88px; \n flex-direction: column;\n align-items: stretch;\n padding: 12px;\n }\n .save-bar-actions[_ngcontent-%COMP%] {\n justify-content: space-between;\n }\n .save-bar-kbd[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n\n\n\n@media (max-width: 768px) {\n .header-actions[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n }\n\n .header-actions[_ngcontent-%COMP%] app-evaluation-mode-toggle[_ngcontent-%COMP%] {\n flex-basis: 100%;\n }\n\n .breadcrumb[_ngcontent-%COMP%] ol[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n }\n\n .breadcrumb[_ngcontent-%COMP%] li[_ngcontent-%COMP%] {\n min-width: 0;\n }\n}"], changeDetection: 0 }); }
2766
2786
  };
2767
2787
  MJTestFormComponentExtended = __decorate([
2768
2788
  RegisterClass(BaseFormComponent, 'MJ: Tests')
@@ -2770,7 +2790,7 @@ MJTestFormComponentExtended = __decorate([
2770
2790
  export { MJTestFormComponentExtended };
2771
2791
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJTestFormComponentExtended, [{
2772
2792
  type: Component,
2773
- args: [{ standalone: false, selector: 'mj-test-form', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"test-form\">\n <!-- Header Section -->\n <div class=\"test-header\">\n <!-- Breadcrumb Navigation -->\n <nav class=\"breadcrumb\" aria-label=\"Breadcrumb\">\n <ol>\n <li>\n <a href=\"javascript:void(0)\" (click)=\"navigateToTestingDashboard()\">\n <i class=\"fas fa-vial\"></i>\n <span class=\"breadcrumb-text\">Testing</span>\n </a>\n </li>\n <li class=\"current\">\n <i class=\"fas fa-chevron-right separator\"></i>\n <i class=\"fas fa-flask\"></i>\n <span>{{ record.Name }}</span>\n </li>\n </ol>\n </nav>\n\n <div class=\"header-content\">\n <div class=\"header-left\">\n <div class=\"test-icon\" [style.background-color]=\"getStatusColor()\">\n <i class=\"fas fa-flask\"></i>\n </div>\n <div class=\"test-info\">\n <h1>\n {{ record.Name }}\n @if (isDirty) {\n <span class=\"dirty-indicator\" title=\"You have unsaved changes\" aria-label=\"Unsaved changes\">\u25CF</span>\n }\n </h1>\n <div class=\"test-meta\">\n <span class=\"status-badge\" [ngClass]=\"getStatusClass()\">\n <i class=\"fas\" [ngClass]=\"getStatusIcon()\"></i>\n {{ record.Status }}\n </span>\n @if (record.Type) {\n <span class=\"test-type\">\n <i class=\"fas fa-tag\"></i>\n {{ record.Type }}\n </span>\n }\n @if (isDirty) {\n <span class=\"unsaved-pill\" title=\"You have unsaved changes\">\n <i class=\"fas fa-circle\"></i> Unsaved\n </span>\n }\n </div>\n </div>\n </div>\n <div class=\"header-actions\">\n <app-evaluation-mode-toggle></app-evaluation-mode-toggle>\n <button mjButton (click)=\"runTest()\" variant=\"primary\">\n <i class=\"fas fa-play\"></i> Run Test\n </button>\n <button mjButton (click)=\"refresh()\" [disabled]=\"isRefreshing\">\n <i class=\"fas\" [ngClass]=\"isRefreshing ? 'fa-sync fa-spin' : 'fa-sync'\"></i>\n {{ isRefreshing ? 'Refreshing...' : 'Refresh' }}\n </button>\n </div>\n </div>\n\n <!-- Test Description -->\n @if (record.Description) {\n <div class=\"test-description\">\n <p>{{ record.Description }}</p>\n </div>\n }\n\n <!-- Metrics Bar -->\n @if (testRunsLoaded && testRuns.length > 0) {\n <div class=\"metrics-bar\">\n <div class=\"metric-card\">\n <div class=\"metric-label\">Total Runs</div>\n <div class=\"metric-value\">{{ testRuns.length }}</div>\n </div>\n <div class=\"metric-card\">\n <div class=\"metric-label\">Pass Rate</div>\n <div class=\"metric-value\">{{ getPassRate().toFixed(1) }}%</div>\n <div class=\"metric-progress\">\n <div class=\"metric-progress-fill\" [style.width.%]=\"getPassRate()\"></div>\n </div>\n </div>\n <div class=\"metric-card\">\n <div class=\"metric-label\">Avg Cost</div>\n <div class=\"metric-value\">{{ formatCost(getAverageCost()) }}</div>\n </div>\n <div class=\"metric-card\">\n <div class=\"metric-label\">Avg Duration</div>\n <div class=\"metric-value\">{{ formatDuration(getAverageDuration()) }}</div>\n </div>\n </div>\n }\n </div>\n\n <!-- Tabs -->\n <div class=\"tabs-container\">\n <div class=\"tabs\" role=\"tablist\">\n <button class=\"tab\"\n [class.active]=\"activeTab === 'overview'\"\n (click)=\"changeTab('overview')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'overview'\">\n <i class=\"fas fa-th-large\"></i>\n <span>Overview</span>\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'config'\"\n (click)=\"changeTab('config')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'config'\">\n <i class=\"fas fa-sliders-h\"></i>\n <span>Configuration</span>\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'runs'\"\n (click)=\"changeTab('runs')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'runs'\">\n <i class=\"fas fa-history\"></i>\n <span>Runs</span>\n @if (testRunsLoaded) {\n <span class=\"tab-badge\">{{ testRuns.length }}</span>\n }\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'suites'\"\n (click)=\"changeTab('suites')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'suites'\">\n <i class=\"fas fa-layer-group\"></i>\n <span>Test Suites</span>\n @if (suiteTestsLoaded) {\n <span class=\"tab-badge\">{{ suiteTests.length }}</span>\n }\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'analytics'\"\n (click)=\"changeTab('analytics')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'analytics'\">\n <i class=\"fas fa-chart-line\"></i>\n <span>Analytics</span>\n </button>\n </div>\n </div>\n\n <!-- Tab Content -->\n <div class=\"tab-content\" [class.has-savebar]=\"isDirty\">\n <!-- Overview Tab -->\n @if (activeTab === 'overview') {\n <div class=\"overview-tab\">\n <!-- Basic Information -->\n <div class=\"info-section\">\n <h3><i class=\"fas fa-info-circle\"></i> Test Information</h3>\n <div class=\"info-grid\">\n <div class=\"info-item\">\n <div class=\"info-label\">Name</div>\n <div class=\"info-value\">{{ record.Name }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Type</div>\n <div class=\"info-value\">{{ record.Type || 'N/A' }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Status</div>\n <div class=\"info-value\">\n <span class=\"status-badge-inline\" [ngClass]=\"getStatusClass()\">{{ record.Status }}</span>\n </div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Priority</div>\n <div class=\"info-value\">{{ record.Priority || 'N/A' }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Estimated Duration</div>\n <div class=\"info-value\">{{ record.EstimatedDurationSeconds ? formatDuration(record.EstimatedDurationSeconds) : 'N/A' }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Estimated Cost</div>\n <div class=\"info-value\">{{ record.EstimatedCostUSD ? formatCost(record.EstimatedCostUSD) : 'N/A' }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Repeat Count</div>\n <div class=\"info-value\">{{ record.RepeatCount || 1 }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Max Execution Time</div>\n <div class=\"info-value\">{{ formatTimeout(record.MaxExecutionTimeMS) }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Created</div>\n <div class=\"info-value\">{{ record.__mj_CreatedAt | date:'medium' }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Updated</div>\n <div class=\"info-value\">{{ record.__mj_UpdatedAt | date:'medium' }}</div>\n </div>\n </div>\n </div>\n <!-- JSON Data Views -->\n <div class=\"json-section\">\n <h3><i class=\"fas fa-code\"></i> Test Definition</h3>\n <div class=\"json-tabs\">\n <button class=\"json-tab\"\n [class.active]=\"activeJsonView === 'input'\"\n (click)=\"setJsonView('input')\">\n <i class=\"fas fa-sign-in-alt\"></i>\n Input Definition\n </button>\n <button class=\"json-tab\"\n [class.active]=\"activeJsonView === 'expected'\"\n (click)=\"setJsonView('expected')\">\n <i class=\"fas fa-check-double\"></i>\n Expected Outcomes\n </button>\n <button class=\"json-tab\"\n [class.active]=\"activeJsonView === 'config'\"\n (click)=\"setJsonView('config')\">\n <i class=\"fas fa-cog\"></i>\n Configuration\n </button>\n <button class=\"json-tab\"\n [class.active]=\"activeJsonView === 'tags'\"\n (click)=\"setJsonView('tags')\">\n <i class=\"fas fa-tags\"></i>\n Tags\n </button>\n </div>\n <div class=\"code-editor-container\">\n <mj-code-editor\n [value]=\"getJsonData()\"\n language=\"json\"\n [readonly]=\"true\"\n [toolbar]=\"jsonToolbar\"\n [lineWrapping]=\"true\">\n </mj-code-editor>\n </div>\n </div>\n </div>\n }\n\n <!-- Configuration Tab -->\n @if (activeTab === 'config') {\n <div class=\"config-tab\">\n <!-- Details -->\n <section class=\"edit-section\">\n <header class=\"edit-section-header\">\n <h3><i class=\"fas fa-pen-to-square\"></i> Details</h3>\n <p class=\"edit-section-sub\">Edit any field \u2014 changes are saved with the bar at the bottom.</p>\n </header>\n <div class=\"edit-grid\">\n <div class=\"edit-field edit-field--full\">\n <label for=\"test-name\">Name <span class=\"required\">*</span></label>\n <input\n id=\"test-name\"\n type=\"text\"\n class=\"config-input\"\n placeholder=\"e.g., Agent Response Quality Test\"\n [(ngModel)]=\"record.Name\"\n />\n </div>\n\n <div class=\"edit-field edit-field--full\">\n <label for=\"test-description\">Description</label>\n <textarea\n id=\"test-description\"\n class=\"config-input config-textarea\"\n rows=\"3\"\n placeholder=\"What does this test evaluate?\"\n [ngModel]=\"record.Description\"\n (ngModelChange)=\"record.Description = $event || null\"\n ></textarea>\n </div>\n\n <div class=\"edit-field\">\n <label for=\"test-status\">Status</label>\n <div class=\"select-wrapper\">\n <select\n id=\"test-status\"\n class=\"config-input\"\n [(ngModel)]=\"record.Status\"\n >\n @for (opt of statusOptions; track opt) {\n <option [ngValue]=\"opt\">{{ opt }}</option>\n }\n </select>\n </div>\n </div>\n\n <div class=\"edit-field\">\n <label for=\"test-rubric\">Rubric</label>\n <select\n id=\"test-rubric\"\n class=\"config-input\"\n [ngModel]=\"record.RubricID\"\n (ngModelChange)=\"record.RubricID = $event || null\"\n >\n <option [ngValue]=\"null\">\u2014 None \u2014</option>\n @for (rubric of RubricOptions; track rubric.id) {\n <option [ngValue]=\"rubric.id\">{{ rubric.name }}</option>\n }\n </select>\n </div>\n\n <div class=\"edit-field\">\n <label for=\"test-type\">Test Type</label>\n <select\n id=\"test-type\"\n class=\"config-input\"\n [(ngModel)]=\"record.TypeID\"\n >\n @for (t of testTypeOptions; track t.ID) {\n <option [ngValue]=\"t.ID\">{{ t.Name }}</option>\n }\n </select>\n </div>\n\n <div class=\"edit-field edit-field--full\">\n <label for=\"test-tags\">Tags</label>\n <div class=\"tag-editor\" (click)=\"tagInput.focus()\">\n @for (tag of tags; track tag) {\n <span class=\"tag-chip-editable\">\n {{ tag }}\n <button type=\"button\" class=\"tag-remove\" (click)=\"removeTag(tag); $event.stopPropagation()\" [attr.aria-label]=\"'Remove tag ' + tag\">\n <i class=\"fas fa-times\"></i>\n </button>\n </span>\n }\n <input\n #tagInput\n id=\"test-tags\"\n type=\"text\"\n class=\"tag-input-inline\"\n [placeholder]=\"tags.length === 0 ? 'Add tags, press Enter or comma...' : ''\"\n [(ngModel)]=\"tagDraft\"\n (keydown)=\"onTagInputKeydown($event)\"\n (blur)=\"addTagFromDraft()\"\n />\n </div>\n <span class=\"config-hint\">Press Enter or comma to add a tag. Backspace on empty input removes the last tag.</span>\n </div>\n </div>\n </section>\n\n <!-- Execution Settings -->\n <section class=\"edit-section\">\n <header class=\"edit-section-header\">\n <h3><i class=\"fas fa-cogs\"></i> Execution Settings</h3>\n </header>\n <div class=\"edit-grid\">\n <div class=\"edit-field\">\n <label for=\"test-priority\">Priority</label>\n <input\n id=\"test-priority\"\n type=\"number\"\n class=\"config-input\"\n placeholder=\"0 (lower runs first)\"\n [ngModel]=\"record.Priority\"\n (ngModelChange)=\"record.Priority = $event === '' || $event === null ? null : +$event\"\n />\n <span class=\"config-hint\">Lower numbers run first.</span>\n </div>\n <div class=\"edit-field\">\n <label for=\"test-repeat\">Repeat Count</label>\n <input\n id=\"test-repeat\"\n type=\"number\"\n class=\"config-input\"\n min=\"1\"\n placeholder=\"1\"\n [ngModel]=\"record.RepeatCount\"\n (ngModelChange)=\"record.RepeatCount = $event === '' || $event === null ? null : +$event\"\n />\n <span class=\"config-hint\">Number of times to repeat for statistical analysis.</span>\n </div>\n <div class=\"edit-field\">\n <label for=\"test-duration\">Estimated Duration (seconds)</label>\n <input\n id=\"test-duration\"\n type=\"number\"\n class=\"config-input\"\n placeholder=\"0\"\n [ngModel]=\"record.EstimatedDurationSeconds\"\n (ngModelChange)=\"record.EstimatedDurationSeconds = $event === '' || $event === null ? null : +$event\"\n />\n </div>\n <div class=\"edit-field\">\n <label for=\"test-cost\">Estimated Cost (USD)</label>\n <input\n id=\"test-cost\"\n type=\"number\"\n step=\"0.000001\"\n class=\"config-input\"\n placeholder=\"0.00\"\n [ngModel]=\"record.EstimatedCostUSD\"\n (ngModelChange)=\"record.EstimatedCostUSD = $event === '' || $event === null ? null : +$event\"\n />\n </div>\n <div class=\"edit-field edit-field--full\">\n <label for=\"test-timeout\">Max Execution Time (ms)</label>\n <input\n id=\"test-timeout\"\n type=\"number\"\n class=\"config-input\"\n placeholder=\"Default: 300000 (5 min)\"\n [ngModel]=\"record.MaxExecutionTimeMS\"\n (ngModelChange)=\"record.MaxExecutionTimeMS = $event === '' || $event === null ? null : +$event\"\n />\n <span class=\"config-hint\">Leave empty for the default 5 minute timeout. Currently: {{ formatTimeout(record.MaxExecutionTimeMS) }}</span>\n </div>\n </div>\n </section>\n\n <!-- JSON editors (preserved from original layout) -->\n <div class=\"config-section\">\n <h3><i class=\"fas fa-sign-in-alt\"></i> Input Definition (JSON)</h3>\n <div class=\"config-editor-container\">\n <mj-code-editor\n [value]=\"record.InputDefinition || ''\"\n language=\"json\"\n [readonly]=\"false\"\n [lineWrapping]=\"true\"\n (change)=\"record.InputDefinition = $event\">\n </mj-code-editor>\n </div>\n </div>\n <div class=\"config-section\">\n <h3><i class=\"fas fa-check-double\"></i> Expected Outcomes (JSON)</h3>\n <div class=\"config-editor-container\">\n <mj-code-editor\n [value]=\"record.ExpectedOutcomes || ''\"\n language=\"json\"\n [readonly]=\"false\"\n [lineWrapping]=\"true\"\n (change)=\"record.ExpectedOutcomes = $event\">\n </mj-code-editor>\n </div>\n </div>\n <div class=\"config-section\">\n <h3><i class=\"fas fa-cog\"></i> Configuration (JSON)</h3>\n <div class=\"config-editor-container\">\n <mj-code-editor\n [value]=\"record.Configuration || ''\"\n language=\"json\"\n [readonly]=\"false\"\n [lineWrapping]=\"true\"\n (change)=\"record.Configuration = $event\">\n </mj-code-editor>\n </div>\n </div>\n\n <!-- Metadata (read-only) -->\n <section class=\"meta-section\">\n <div class=\"meta-grid\">\n <div class=\"meta-item\">\n <div class=\"meta-label\">Created</div>\n <div class=\"meta-value\">{{ record.__mj_CreatedAt | date:'medium' }}</div>\n </div>\n <div class=\"meta-item\">\n <div class=\"meta-label\">Last updated</div>\n <div class=\"meta-value\">{{ record.__mj_UpdatedAt | date:'medium' }}</div>\n </div>\n <div class=\"meta-item\">\n <div class=\"meta-label\">Test ID</div>\n <div class=\"meta-value meta-mono\">{{ record.ID }}</div>\n </div>\n </div>\n </section>\n </div>\n }\n\n <!-- Test Runs Tab -->\n @if (activeTab === 'runs') {\n <div class=\"runs-tab\">\n <!-- Loading State -->\n @if (loadingRuns) {\n <div class=\"loading-state\">\n <div class=\"skeleton-list\">\n @for (i of [1,2,3,4,5]; track i) {\n <div class=\"skeleton-card\">\n <div class=\"skeleton-icon\"></div>\n <div class=\"skeleton-content\">\n <div class=\"skeleton-line wide\"></div>\n <div class=\"skeleton-line narrow\"></div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Runs List -->\n @if (!loadingRuns && testRuns.length > 0) {\n <div class=\"runs-list\">\n @for (run of testRuns; track run) {\n <div class=\"run-item\" (click)=\"openTestRun(run.ID)\">\n <div class=\"run-icon\" [style.background-color]=\"getRunStatusColor(run.Status)\">\n <i class=\"fas\"\n [class.fa-check]=\"run.Status === 'Passed'\"\n [class.fa-times]=\"run.Status === 'Failed'\"\n [class.fa-exclamation]=\"run.Status === 'Error'\"\n [class.fa-stopwatch]=\"run.Status === 'Timeout'\"\n [class.fa-spinner]=\"run.Status === 'Running'\"\n [class.fa-clock]=\"run.Status === 'Pending'\"></i>\n </div>\n <div class=\"run-content\">\n <div class=\"run-header\">\n <span class=\"run-id\">Run #{{ run.ID.substring(0, 8) }}</span>\n <span class=\"run-status\" [style.color]=\"getRunStatusColor(run.Status)\">{{ run.Status }}</span>\n </div>\n <div class=\"run-meta\">\n <span><i class=\"fas fa-calendar\"></i> {{ getRelativeTime(run.StartedAt) }}</span>\n @if (run.DurationSeconds) {\n <span><i class=\"fas fa-clock\"></i> {{ formatDuration(run.DurationSeconds) }}</span>\n }\n @if (run.CostUSD) {\n <span><i class=\"fas fa-dollar-sign\"></i> {{ formatCost(run.CostUSD) }}</span>\n }\n @if (run.TargetLogEntityID && run.TargetLogID) {\n <mj-entity-link-pill\n [entityName]=\"run.TargetLogEntity\"\n [recordId]=\"run.TargetLogID\">\n </mj-entity-link-pill>\n }\n </div>\n <!-- Evaluation indicators -->\n <div class=\"run-eval-stack\">\n <!-- Status indicator -->\n @if (evalPreferences.showExecution) {\n <span class=\"eval-pill status-pill\"\n [ngClass]=\"'status-' + run.Status.toLowerCase()\"\n [title]=\"getStatusTooltip(run.Status)\">\n <i class=\"fas\"\n [class.fa-check]=\"run.Status === 'Passed'\"\n [class.fa-times]=\"run.Status === 'Failed'\"\n [class.fa-exclamation]=\"run.Status === 'Error'\"\n [class.fa-hourglass-end]=\"run.Status === 'Timeout'\"\n [class.fa-forward]=\"run.Status === 'Skipped'\"\n [class.fa-spinner]=\"run.Status === 'Running'\"\n [class.fa-clock]=\"run.Status === 'Pending'\"></i>\n <span>{{ run.Status }}</span>\n </span>\n }\n <!-- Human feedback indicator -->\n @if (evalPreferences.showHuman) {\n @if (!getFeedbackForRun(run.ID)?.Rating) {\n <span class=\"eval-pill human-pill no-feedback\"\n title=\"Human Review: No rating submitted yet\">\n <i class=\"fas fa-user-slash\"></i>\n </span>\n }\n @if (getFeedbackForRun(run.ID)?.Rating; as rating) {\n <span class=\"eval-pill human-pill has-feedback\"\n [class.rating-low]=\"rating <= 4\"\n [class.rating-medium]=\"rating >= 5 && rating <= 6\"\n [class.rating-good]=\"rating >= 7 && rating <= 8\"\n [class.rating-excellent]=\"rating >= 9\"\n [title]=\"getHumanTooltip(rating, getFeedbackForRun(run.ID)?.CorrectionSummary || getFeedbackForRun(run.ID)?.Comments || null)\">\n <i class=\"fas fa-user\"></i>\n <span>{{ rating }}</span>\n </span>\n }\n }\n <!-- Auto score indicator -->\n @if (evalPreferences.showAuto) {\n @if (run.Score == null) {\n <span class=\"eval-pill auto-pill no-score\"\n title=\"Auto Score: No automated score available\">\n <i class=\"fas fa-robot\"></i>\n </span>\n }\n @if (run.Score != null) {\n <span class=\"eval-pill auto-pill has-score\"\n [class.score-low]=\"run.Score < 0.5\"\n [class.score-medium]=\"run.Score >= 0.5 && run.Score < 0.7\"\n [class.score-good]=\"run.Score >= 0.7 && run.Score < 0.85\"\n [class.score-excellent]=\"run.Score >= 0.85\"\n [title]=\"'Auto Score: ' + (run.Score * 100).toFixed(0) + '% automated evaluation'\">\n <i class=\"fas fa-robot\"></i>\n <span>{{ (run.Score * 100).toFixed(0) }}%</span>\n </span>\n }\n }\n </div>\n @if (getRunTags(run).length > 0) {\n <div class=\"run-tags\">\n @for (tag of getRunTags(run).slice(0, 3); track tag) {\n <span class=\"run-tag\">{{ tag }}</span>\n }\n @if (getRunTags(run).length > 3) {\n <span class=\"run-tag-more\">+{{ getRunTags(run).length - 3 }}</span>\n }\n </div>\n }\n </div>\n <i class=\"fas fa-chevron-right\"></i>\n </div>\n }\n </div>\n }\n <!-- Empty State -->\n @if (testRunsLoaded && !loadingRuns && testRuns.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-circle-play\"\n Title=\"No Test Runs Yet\"\n Message=\"Run this test to see execution history and results here.\"\n ActionText=\"Run Test Now\"\n ActionIcon=\"fa-solid fa-play\"\n (Action)=\"runTest()\" />\n }\n </div>\n }\n\n <!-- Test Suites Tab -->\n @if (activeTab === 'suites') {\n <div class=\"suites-tab\">\n <!-- Loading State -->\n @if (loadingSuites) {\n <div class=\"loading-state\">\n <div class=\"skeleton-list\">\n @for (i of [1,2,3]; track i) {\n <div class=\"skeleton-card\">\n <div class=\"skeleton-icon\"></div>\n <div class=\"skeleton-content\">\n <div class=\"skeleton-line wide\"></div>\n <div class=\"skeleton-line narrow\"></div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Suites List -->\n @if (!loadingSuites && suiteTests.length > 0) {\n <div class=\"suites-list\">\n @for (suiteTest of suiteTests; track suiteTest) {\n <div class=\"suite-item\" (click)=\"openTestSuite(suiteTest.SuiteID)\">\n <div class=\"suite-icon\">\n <i class=\"fas fa-layer-group\"></i>\n </div>\n <div class=\"suite-content\">\n <div class=\"suite-name\">{{ suiteTest.Suite }}</div>\n <div class=\"suite-meta\">\n <span><i class=\"fas fa-sort-numeric-up\"></i> Sequence: {{ suiteTest.Sequence }}</span>\n @if (suiteTest.Status) {\n <span><i class=\"fas fa-info-circle\"></i> {{ suiteTest.Status }}</span>\n }\n </div>\n </div>\n <i class=\"fas fa-chevron-right\"></i>\n </div>\n }\n </div>\n }\n <!-- Empty State -->\n @if (suiteTestsLoaded && !loadingSuites && suiteTests.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-folder-open\"\n Title=\"Not Part of Any Suite\"\n Message=\"This test is not included in any test suites. Add it to a suite to run it with other tests.\" />\n }\n </div>\n }\n\n <!-- Analytics Tab -->\n @if (activeTab === 'analytics') {\n <div class=\"history-tab\">\n <!-- Loading State -->\n @if (loadingHistory) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading history...\"></mj-loading>\n </div>\n }\n <!-- History Content -->\n @if (!loadingHistory && historyLoaded) {\n <div class=\"history-content\">\n <!-- Filters -->\n <div class=\"history-filters\">\n <div class=\"time-range-filters\">\n <span class=\"filter-label\">Time Range:</span>\n <button class=\"filter-btn\"\n [class.active]=\"historyTimeRange === '7d'\"\n (click)=\"setHistoryTimeRange('7d')\">7 Days</button>\n <button class=\"filter-btn\"\n [class.active]=\"historyTimeRange === '30d'\"\n (click)=\"setHistoryTimeRange('30d')\">30 Days</button>\n <button class=\"filter-btn\"\n [class.active]=\"historyTimeRange === '90d'\"\n (click)=\"setHistoryTimeRange('90d')\">90 Days</button>\n <button class=\"filter-btn\"\n [class.active]=\"historyTimeRange === 'all'\"\n (click)=\"setHistoryTimeRange('all')\">All Time</button>\n </div>\n <div class=\"history-actions\">\n <button mjButton (click)=\"exportHistoryToCSV()\" [disabled]=\"historyData.length === 0\">\n <i class=\"fas fa-download\"></i> Export CSV\n </button>\n </div>\n </div>\n <!-- KPI Cards -->\n @if (historyData.length > 0) {\n <div class=\"history-kpi-cards\">\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\">\n <i class=\"fas fa-play-circle\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ getTotalRuns() }}</div>\n <div class=\"kpi-label\">Total Runs</div>\n </div>\n </div>\n @if (evalPreferences.showExecution) {\n <div class=\"kpi-card\">\n <div class=\"kpi-icon pass-rate\">\n <i class=\"fas fa-percentage\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">\n {{ getOverallPassRate().toFixed(1) }}%\n <i class=\"fas trend-icon\"\n [class.fa-arrow-up]=\"getPassRateTrend() === 'up'\"\n [class.fa-arrow-down]=\"getPassRateTrend() === 'down'\"\n [class.fa-minus]=\"getPassRateTrend() === 'stable'\"\n [class.trend-up]=\"getPassRateTrend() === 'up'\"\n [class.trend-down]=\"getPassRateTrend() === 'down'\"></i>\n </div>\n <div class=\"kpi-label\">Pass Rate</div>\n </div>\n </div>\n }\n @if (evalPreferences.showAuto) {\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\">\n <i class=\"fas fa-star\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ (getOverallAvgScore() * 100).toFixed(1) }}%</div>\n <div class=\"kpi-label\">Avg Score</div>\n </div>\n </div>\n }\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\">\n <i class=\"fas fa-clock\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ formatDuration(getOverallAvgDuration()) }}</div>\n <div class=\"kpi-label\">Avg Duration</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\">\n <i class=\"fas fa-dollar-sign\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ formatCost(getOverallAvgCost()) }}</div>\n <div class=\"kpi-label\">Avg Cost</div>\n </div>\n </div>\n </div>\n }\n <!-- Daily History Table -->\n @if (historyData.length > 0) {\n <div class=\"history-section\">\n <h3><i class=\"fas fa-calendar-alt\"></i> Daily Performance</h3>\n <div class=\"history-table-container\">\n <table class=\"history-table\">\n <thead>\n <tr>\n <th>Date</th>\n <th>Runs</th>\n @if (evalPreferences.showExecution) {\n <th>Passed</th>\n }\n @if (evalPreferences.showExecution) {\n <th>Failed</th>\n }\n @if (evalPreferences.showExecution) {\n <th>Pass Rate</th>\n }\n @if (evalPreferences.showAuto) {\n <th>Avg Score</th>\n }\n <th>Avg Duration</th>\n <th>Avg Cost</th>\n </tr>\n </thead>\n <tbody>\n @for (day of historyData; track day) {\n <tr>\n <td class=\"date-cell\">{{ day.date | date:'mediumDate' }}</td>\n <td class=\"runs-cell\">{{ day.runCount }}</td>\n @if (evalPreferences.showExecution) {\n <td class=\"passed-cell\">{{ day.passCount }}</td>\n }\n @if (evalPreferences.showExecution) {\n <td class=\"failed-cell\">{{ day.failCount }}</td>\n }\n @if (evalPreferences.showExecution) {\n <td class=\"pass-rate-cell\">\n <div class=\"pass-rate-bar\">\n <div class=\"pass-rate-fill\" [style.width.%]=\"day.passRate\"></div>\n <span class=\"pass-rate-text\">{{ day.passRate.toFixed(1) }}%</span>\n </div>\n </td>\n }\n @if (evalPreferences.showAuto) {\n <td class=\"score-cell\">{{ (day.avgScore * 100).toFixed(1) }}%</td>\n }\n <td class=\"duration-cell\">{{ formatDuration(day.avgDuration) }}</td>\n <td class=\"cost-cell\">{{ formatCost(day.avgCost) }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n }\n <!-- Suite Performance -->\n @if (suitePerformance.length > 0) {\n <div class=\"history-section\">\n <h3><i class=\"fas fa-layer-group\"></i> Performance by Suite</h3>\n <div class=\"suite-performance-list\">\n @for (suite of suitePerformance; track suite) {\n <div class=\"suite-perf-card\" (click)=\"openSuiteFromHistory(suite.suiteId)\">\n <div class=\"suite-perf-header\">\n <div class=\"suite-perf-name\">{{ suite.suiteName }}</div>\n @if (suite.tags.length > 0) {\n <div class=\"suite-perf-tags\">\n @for (tag of suite.tags.slice(0, 3); track tag) {\n <span class=\"tag-mini\">{{ tag }}</span>\n }\n @if (suite.tags.length > 3) {\n <span class=\"tag-more\">+{{ suite.tags.length - 3 }}</span>\n }\n </div>\n }\n </div>\n <div class=\"suite-perf-stats\">\n <div class=\"suite-stat\">\n <span class=\"stat-value\">{{ suite.totalRuns }}</span>\n <span class=\"stat-label\">Runs</span>\n </div>\n @if (evalPreferences.showExecution) {\n <div class=\"suite-stat\">\n <span class=\"stat-value pass-rate\" [class.high]=\"suite.passRate >= 80\" [class.low]=\"suite.passRate < 50\">\n {{ suite.passRate.toFixed(1) }}%\n </span>\n <span class=\"stat-label\">Pass Rate</span>\n </div>\n }\n @if (evalPreferences.showAuto) {\n <div class=\"suite-stat\">\n <span class=\"stat-value\">{{ (suite.avgScore * 100).toFixed(1) }}%</span>\n <span class=\"stat-label\">Avg Score</span>\n </div>\n }\n <div class=\"suite-stat\">\n <span class=\"stat-value\">{{ formatDuration(suite.avgDuration) }}</span>\n <span class=\"stat-label\">Avg Duration</span>\n </div>\n <div class=\"suite-stat\">\n <span class=\"stat-value\">{{ formatCost(suite.avgCost) }}</span>\n <span class=\"stat-label\">Avg Cost</span>\n </div>\n @if (suite.lastRun) {\n <div class=\"suite-stat\">\n <span class=\"stat-value\">{{ getRelativeTime(suite.lastRun) }}</span>\n <span class=\"stat-label\">Last Run</span>\n </div>\n }\n </div>\n <i class=\"fas fa-chevron-right suite-perf-arrow\"></i>\n </div>\n }\n </div>\n </div>\n }\n <!-- Empty State -->\n @if (historyData.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-chart-line\"\n Title=\"No History Available\"\n Message=\"Run this test to start building history and analytics data.\"\n ActionText=\"Run Test Now\"\n ActionIcon=\"fa-solid fa-play\"\n (Action)=\"runTest()\" />\n }\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Keyboard Shortcuts Toggle Button -->\n <button class=\"shortcuts-toggle\" (click)=\"toggleShortcuts()\" [title]=\"showShortcuts ? 'Hide keyboard shortcuts' : 'Show keyboard shortcuts'\">\n <i class=\"fas fa-keyboard\"></i>\n </button>\n\n <!-- Keyboard Shortcuts Hint (Desktop Only) -->\n @if (showShortcuts) {\n <div class=\"keyboard-shortcuts\">\n <div class=\"shortcuts-header\">\n <i class=\"fas fa-keyboard\"></i>\n Shortcuts\n <button class=\"shortcuts-close\" (click)=\"toggleShortcuts()\" title=\"Hide shortcuts\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n <div class=\"shortcut-list\">\n <div class=\"shortcut-item\">\n <span>Save changes</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>S</kbd></span>\n </div>\n <div class=\"shortcut-item\">\n <span>Refresh</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>R</kbd></span>\n </div>\n <div class=\"shortcut-item\">\n <span>Run Test</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>Enter</kbd></span>\n </div>\n <div class=\"shortcut-item\">\n <span>Switch Tabs</span>\n <span class=\"shortcut-keys\"><kbd>1</kbd>-<kbd>5</kbd></span>\n </div>\n </div>\n </div>\n }\n\n <!-- Slide Panel for Test Execution -->\n @if (testingDialogService.IsPanelOpen) {\n <mj-slide-panel\n Mode=\"slide\"\n [Title]=\"testingDialogService.PanelOptions?.testId ? 'Test Execution' : 'Run Test'\"\n [Resizable]=\"true\"\n (Closed)=\"OnPanelClosed()\">\n <app-test-run-dialog\n [PanelMode]=\"true\"\n [selectedTestId]=\"testingDialogService.PanelOptions?.testId ?? null\"\n [selectedSuiteId]=\"testingDialogService.PanelOptions?.suiteId ?? null\"\n [runMode]=\"testingDialogService.PanelOptions?.mode ?? 'test'\"\n (PanelClose)=\"OnPanelClosed()\">\n </app-test-run-dialog>\n </mj-slide-panel>\n }\n\n <!-- Sticky Save Bar \u2014 always in the DOM so CSS transitions can fire reliably.\n Visibility is controlled by the .save-bar--visible class, driven by isDirty. -->\n <div\n class=\"save-bar\"\n [class.save-bar--visible]=\"isDirty\"\n [attr.aria-hidden]=\"!isDirty\"\n role=\"region\"\n aria-label=\"Unsaved changes\"\n >\n <div class=\"save-bar-message\">\n <span class=\"save-bar-dot\" aria-hidden=\"true\">\u25CF</span>\n <span class=\"save-bar-text\">\n <strong>Unsaved changes</strong>\n <span class=\"save-bar-fields\">\n @if (dirtyFieldNames.length === 1) {\n {{ dirtyFieldNames[0] }} edited\n } @else if (dirtyFieldNames.length > 1) {\n {{ dirtyFieldNames.length }} fields edited\n }\n </span>\n </span>\n </div>\n <div class=\"save-bar-actions\">\n <button\n type=\"button\"\n class=\"save-bar-btn save-bar-btn--primary\"\n (click)=\"saveChanges()\"\n [disabled]=\"isSaving || !isDirty\"\n [attr.tabindex]=\"isDirty ? 0 : -1\"\n title=\"Save changes (\u2318S)\"\n >\n @if (isSaving) {\n <i class=\"fas fa-spinner fa-spin\"></i> Saving\u2026\n } @else {\n <i class=\"fas fa-check\"></i> Save changes\n <span class=\"save-bar-kbd\"><kbd>\u2318</kbd><kbd>S</kbd></span>\n }\n </button>\n <button\n type=\"button\"\n class=\"save-bar-btn save-bar-btn--ghost\"\n (click)=\"discardChanges()\"\n [disabled]=\"isSaving || !isDirty\"\n [attr.tabindex]=\"isDirty ? 0 : -1\"\n title=\"Discard changes\"\n >\n <i class=\"fas fa-undo\"></i> Discard\n </button>\n </div>\n </div>\n</div>\n", styles: ["/* ===========================\n Test Form - World-Class UX\n Premium Test Definition Styles\n =========================== */\n\n/* CSS Custom Properties for Theming - using :host for Angular encapsulation */\n:host {\n --test-primary: var(--mj-brand-primary);\n --test-primary-light: var(--mj-brand-primary);\n --test-primary-dark: var(--mj-brand-primary-hover);\n --test-success: var(--mj-status-success);\n --test-success-light: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n --test-error: var(--mj-status-error);\n --test-error-light: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n --test-warning: var(--mj-status-warning);\n --test-warning-light: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n --test-disabled: var(--mj-text-muted);\n --test-bg: var(--mj-bg-surface-card);\n --test-surface: var(--mj-bg-surface);\n --test-border: var(--mj-border-default);\n --test-text: var(--mj-text-primary);\n --test-text-secondary: var(--mj-text-muted);\n --test-text-muted: var(--mj-text-disabled);\n --test-radius-sm: 6px;\n --test-radius-md: 10px;\n --test-radius-lg: 16px;\n --test-shadow-sm: var(--mj-shadow-sm);\n --test-shadow-md: var(--mj-shadow-md);\n --test-shadow-lg: var(--mj-shadow-lg);\n --test-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n display: block;\n height: 100%;\n}\n\n/* Breadcrumb */\n.breadcrumb {\n margin-bottom: 16px;\n}\n\n.breadcrumb ol {\n display: flex;\n align-items: center;\n gap: 4px;\n list-style: none;\n margin: 0;\n padding: 0;\n font-size: 13px;\n}\n\n.breadcrumb li {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.breadcrumb a {\n color: var(--test-primary);\n text-decoration: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n border-radius: 6px;\n transition: background 0.15s;\n}\n\n.breadcrumb a:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n text-decoration: none;\n}\n\n.breadcrumb .separator {\n font-size: 10px;\n color: var(--test-text-muted);\n margin: 0 4px;\n}\n\n.breadcrumb .current {\n color: var(--test-text-secondary);\n font-weight: 500;\n}\n\n.breadcrumb-text {\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Base Container */\n.test-form {\n position: relative;\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--test-bg);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n/* ===========================\n Header Section\n =========================== */\n.test-header {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n padding: 20px;\n}\n\n.header-content {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 16px;\n gap: 16px;\n}\n\n.header-left {\n display: flex;\n gap: 16px;\n flex: 1;\n min-width: 0;\n}\n\n/* Test Icon */\n.test-icon {\n width: 56px;\n height: 56px;\n border-radius: var(--test-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-inverse);\n font-size: 24px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-md);\n transition: var(--test-transition);\n}\n\n.test-icon:hover {\n transform: scale(1.05);\n}\n\n/* Test Info */\n.test-info {\n flex: 1;\n min-width: 0;\n}\n\n.test-info h1 {\n margin: 0 0 8px 0;\n font-size: clamp(18px, 4vw, 24px);\n font-weight: 700;\n color: var(--test-text);\n line-height: 1.2;\n word-wrap: break-word;\n}\n\n.test-meta {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n/* Status Badge */\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n color: var(--mj-text-inverse);\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.status-badge.status-active { background: var(--mj-status-success); }\n.status-badge.status-disabled { background: var(--mj-text-secondary); }\n.status-badge.status-pending { background: var(--mj-status-warning); }\n\n.status-badge-inline {\n display: inline-flex;\n align-items: center;\n padding: 2px 10px;\n border-radius: 10px;\n color: var(--mj-text-inverse);\n font-size: 11px;\n font-weight: 600;\n}\n\n.status-badge-inline.status-active { background: var(--test-success); }\n.status-badge-inline.status-disabled { background: var(--test-disabled); }\n.status-badge-inline.status-pending { background: var(--test-warning); }\n\n.test-type {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 14px;\n color: var(--test-text-secondary);\n padding: 4px 10px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n}\n\n.header-actions {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.header-actions button {\n white-space: nowrap;\n}\n\n/* Test Description */\n.test-description {\n padding: 16px;\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--test-radius-md);\n margin-bottom: 16px;\n border: 1px solid var(--test-border);\n}\n\n.test-description p {\n margin: 0;\n color: var(--test-text-secondary);\n line-height: 1.6;\n font-size: 14px;\n}\n\n/* ===========================\n Metrics Bar\n =========================== */\n.metrics-bar {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));\n gap: 12px;\n}\n\n.metric-card {\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 14px;\n text-align: center;\n transition: var(--test-transition);\n}\n\n.metric-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.metric-label {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n margin-bottom: 6px;\n}\n\n.metric-value {\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n/* Progress bar in metric card */\n.metric-progress {\n margin-top: 8px;\n height: 4px;\n background: var(--test-border);\n border-radius: 2px;\n overflow: hidden;\n}\n\n.metric-progress-fill {\n height: 100%;\n background: var(--mj-status-success);\n border-radius: 2px;\n transition: width 0.5s ease-out;\n}\n\n/* ===========================\n Tabs Navigation\n =========================== */\n.tabs-container {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n position: sticky;\n top: 0;\n z-index: 10;\n}\n\n.tabs {\n display: flex;\n padding: 0 20px;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n -ms-overflow-style: none;\n}\n\n.tabs::-webkit-scrollbar {\n display: none;\n}\n\n.tab {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 14px 18px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: var(--test-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n white-space: nowrap;\n}\n\n.tab:hover {\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.tab.active {\n color: var(--test-primary);\n border-bottom-color: var(--test-primary);\n font-weight: 600;\n}\n\n.tab i {\n font-size: 15px;\n}\n\n.tab-badge {\n background: var(--test-border);\n color: var(--test-text-secondary);\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n transition: var(--test-transition);\n}\n\n.tab.active .tab-badge {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n color: var(--test-primary);\n}\n\n.tab-shortcut {\n font-size: 10px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n margin-left: 4px;\n}\n\n/* ===========================\n Tab Content Area\n =========================== */\n.tab-content {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n scroll-behavior: smooth;\n}\n\n/* ===========================\n Overview Tab\n =========================== */\n.overview-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: fadeIn 0.3s ease-out;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* Info Section */\n.info-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.info-section h3 {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.info-section h3 i {\n color: var(--test-primary);\n}\n\n.info-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n}\n\n.info-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.info-label {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.info-value {\n font-size: 14px;\n color: var(--test-text);\n word-wrap: break-word;\n font-weight: 500;\n}\n\n/* JSON Section */\n.json-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.json-section h3 {\n margin: 0 0 16px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.json-section h3 i {\n color: var(--test-primary);\n}\n\n.json-tabs {\n display: flex;\n gap: 4px;\n margin-bottom: 16px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n padding: 4px;\n flex-wrap: wrap;\n}\n\n.json-tab {\n flex: 1;\n min-width: 100px;\n padding: 10px 14px;\n border: none;\n background: transparent;\n color: var(--test-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n border-radius: var(--test-radius-sm);\n transition: var(--test-transition);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n}\n\n.json-tab:hover {\n color: var(--test-text);\n background: var(--mj-bg-overlay);\n}\n\n.json-tab.active {\n background: var(--test-surface);\n color: var(--test-primary);\n font-weight: 600;\n box-shadow: var(--test-shadow-sm);\n}\n\n.json-tab i {\n font-size: 12px;\n}\n\n.code-editor-container {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid var(--test-border);\n min-height: 200px;\n max-height: 400px;\n}\n\n/* ===========================\n Configuration Tab\n =========================== */\n.config-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: fadeIn 0.3s ease-out;\n}\n\n.config-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.config-section h3 {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.config-section h3 i {\n color: var(--test-primary);\n}\n\n.config-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\n gap: 20px;\n}\n\n.config-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.config-item.full-width {\n grid-column: 1 / -1;\n}\n\n.config-item label {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.config-input {\n padding: 10px 14px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n font-size: 14px;\n transition: var(--test-transition);\n background: var(--test-surface);\n}\n\n.config-input:focus {\n outline: none;\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.config-input::placeholder {\n color: var(--test-text-muted);\n}\n\n.config-hint {\n font-size: 11px;\n color: var(--test-text-muted);\n margin-top: 4px;\n}\n\n.config-editor-container {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid var(--test-border);\n min-height: 200px;\n}\n\n.config-editor-container.small {\n min-height: 100px;\n max-height: 150px;\n}\n\n/* ===========================\n Runs Tab\n =========================== */\n.runs-tab,\n.suites-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n/* Loading States & Skeletons */\n.loading-state {\n padding: 0;\n}\n\n.skeleton-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.skeleton-card {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.skeleton-icon {\n width: 44px;\n height: 44px;\n border-radius: var(--test-radius-md);\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n flex-shrink: 0;\n}\n\n.skeleton-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.skeleton-line {\n height: 14px;\n border-radius: 4px;\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-line.wide { width: 70%; }\n.skeleton-line.narrow { width: 40%; }\n\n@keyframes shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n/* Runs List */\n.runs-list,\n.suites-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.run-item,\n.suite-item {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.run-item:hover,\n.suite-item:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n box-shadow: var(--test-shadow-sm);\n}\n\n.run-icon,\n.suite-icon {\n width: 44px;\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--test-radius-md);\n color: var(--mj-text-inverse);\n font-size: 18px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-sm);\n}\n\n.suite-icon {\n background: var(--mj-status-warning);\n}\n\n.run-content,\n.suite-content {\n flex: 1;\n min-width: 0;\n}\n\n.run-header {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 4px;\n}\n\n.run-id {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.run-status {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.suite-name {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 4px;\n}\n\n.run-meta,\n.suite-meta {\n display: flex;\n gap: 16px;\n font-size: 12px;\n color: var(--test-text-secondary);\n flex-wrap: wrap;\n}\n\n.run-meta span,\n.suite-meta span {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.run-meta span i,\n.suite-meta span i {\n color: var(--test-text-muted);\n font-size: 11px;\n}\n\n.run-item > i.fa-chevron-right,\n.suite-item > i.fa-chevron-right {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.run-item:hover > i.fa-chevron-right,\n.suite-item:hover > i.fa-chevron-right {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n/* Run Evaluation Stack */\n.run-eval-stack {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n flex-wrap: wrap;\n}\n\n/* Evaluation Pills */\n.eval-pill {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n transition: var(--test-transition);\n}\n\n.eval-pill i {\n font-size: 10px;\n}\n\n/* Status pill colors */\n.eval-pill.status-pill.status-passed {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.eval-pill.status-pill.status-failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.eval-pill.status-pill.status-error {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.eval-pill.status-pill.status-timeout {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.eval-pill.status-pill.status-skipped,\n.eval-pill.status-pill.status-pending {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.eval-pill.status-pill.status-running {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n/* Human feedback pills */\n.eval-pill.human-pill.no-feedback {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n padding: 4px 8px;\n}\n\n.eval-pill.human-pill.has-feedback.rating-low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.eval-pill.human-pill.has-feedback.rating-medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.eval-pill.human-pill.has-feedback.rating-good {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.eval-pill.human-pill.has-feedback.rating-excellent {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n/* Auto score pills */\n.eval-pill.auto-pill.no-score {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n padding: 4px 8px;\n}\n\n.eval-pill.auto-pill.has-score.score-low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.eval-pill.auto-pill.has-score.score-medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.eval-pill.auto-pill.has-score.score-good {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.eval-pill.auto-pill.has-score.score-excellent {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n/* Run Tags */\n.run-tags {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 8px;\n flex-wrap: wrap;\n}\n\n.run-tag {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--test-primary);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n}\n\n.run-tag-more {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n background: var(--test-border);\n color: var(--test-text-muted);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n}\n\n/* ===========================\n Keyboard Shortcuts Popup\n =========================== */\n/* Keyboard shortcuts toggle button */\n.shortcuts-toggle {\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n box-shadow: var(--test-shadow-md);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--test-text-secondary);\n font-size: 14px;\n z-index: 99;\n transition: var(--test-transition);\n opacity: 0.7;\n}\n\n.shortcuts-toggle:hover {\n opacity: 1;\n transform: scale(1.1);\n color: var(--test-primary);\n border-color: var(--test-primary);\n}\n\n.keyboard-shortcuts {\n position: fixed;\n bottom: 20px;\n right: 20px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 12px 16px;\n box-shadow: var(--test-shadow-lg);\n font-size: 12px;\n color: var(--test-text-secondary);\n z-index: 100;\n max-width: 260px;\n}\n\n.shortcuts-header {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-bottom: 10px;\n padding-bottom: 8px;\n border-bottom: 1px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text);\n}\n\n.shortcuts-close {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--test-text-muted);\n font-size: 12px;\n padding: 2px 4px;\n border-radius: 4px;\n transition: var(--test-transition);\n}\n\n.shortcuts-close:hover {\n color: var(--test-text);\n background: var(--test-border);\n}\n\n.shortcut-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.shortcut-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.shortcut-keys {\n display: flex;\n gap: 4px;\n}\n\n.shortcut-keys kbd {\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: 4px;\n padding: 2px 6px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n font-size: 11px;\n color: var(--test-text);\n}\n\n/* ===========================\n Responsive Design - Tablet\n =========================== */\n@media (max-width: 1024px) {\n .metrics-bar {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .info-grid {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .config-grid {\n grid-template-columns: 1fr;\n }\n\n .keyboard-shortcuts, .shortcuts-toggle {\n display: none;\n }\n}\n\n/* ===========================\n Responsive Design - Mobile\n =========================== */\n@media (max-width: 768px) {\n .test-form {\n height: auto;\n min-height: 100%;\n }\n\n .test-header {\n padding: 16px;\n }\n\n .header-content {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-left {\n width: 100%;\n }\n\n .test-icon {\n width: 48px;\n height: 48px;\n font-size: 20px;\n }\n\n .test-info h1 {\n font-size: 18px;\n }\n\n .test-meta {\n gap: 8px;\n }\n\n .status-badge {\n padding: 4px 10px;\n font-size: 11px;\n }\n\n .header-actions {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions button {\n flex: 1;\n }\n\n .metrics-bar {\n grid-template-columns: repeat(2, 1fr);\n gap: 10px;\n }\n\n .metric-card {\n padding: 12px;\n }\n\n .metric-value {\n font-size: 16px;\n }\n\n .tabs {\n padding: 0 12px;\n }\n\n .tab {\n padding: 12px 14px;\n font-size: 13px;\n gap: 6px;\n }\n\n .tab i {\n font-size: 14px;\n }\n\n .tab-shortcut {\n display: none;\n }\n\n .tab-content {\n padding: 16px;\n }\n\n .info-section,\n .json-section,\n .config-section {\n padding: 18px;\n }\n\n .info-grid {\n grid-template-columns: 1fr;\n }\n\n .json-tabs {\n flex-direction: column;\n }\n\n .json-tab {\n min-width: 0;\n justify-content: flex-start;\n }\n\n .run-item,\n .suite-item {\n padding: 14px;\n }\n\n .run-icon,\n .suite-icon {\n width: 40px;\n height: 40px;\n font-size: 16px;\n }\n\n .run-meta,\n .suite-meta {\n flex-direction: column;\n gap: 4px;\n }\n\n}\n\n/* ===========================\n Responsive Design - Small Mobile\n =========================== */\n@media (max-width: 480px) {\n .test-header {\n padding: 12px;\n }\n\n .header-left {\n gap: 12px;\n }\n\n .test-icon {\n width: 40px;\n height: 40px;\n font-size: 18px;\n border-radius: 8px;\n }\n\n .test-info h1 {\n font-size: 16px;\n }\n\n .metrics-bar {\n grid-template-columns: 1fr 1fr;\n }\n\n .tabs {\n padding: 0 8px;\n }\n\n .tab {\n padding: 10px 12px;\n font-size: 12px;\n }\n\n .tab-badge {\n display: none;\n }\n\n .tab-content {\n padding: 12px;\n }\n\n .run-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 4px;\n }\n}\n\n/* ===========================\n Touch Device Optimizations\n =========================== */\n@media (hover: none) and (pointer: coarse) {\n .tab,\n .json-tab,\n .run-item,\n .suite-item {\n -webkit-tap-highlight-color: transparent;\n }\n\n .run-item:active,\n .suite-item:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n transform: scale(0.98);\n }\n\n .tab:active,\n .json-tab:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n }\n\n /* Larger touch targets */\n .tab {\n min-height: 48px;\n }\n\n .run-item,\n .suite-item {\n min-height: 64px;\n }\n}\n\n/* ===========================\n Reduced Motion\n =========================== */\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n\n .skeleton-icon,\n .skeleton-line {\n animation: none;\n background: var(--mj-border-default);\n }\n}\n\n/* ===========================\n History Tab\n =========================== */\n.history-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n.history-content {\n display: flex;\n flex-direction: column;\n gap: 24px;\n}\n\n/* History Filters */\n.history-filters {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 16px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n box-shadow: var(--test-shadow-sm);\n}\n\n.time-range-filters {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.filter-label {\n font-size: 13px;\n font-weight: 600;\n color: var(--test-text-secondary);\n margin-right: 4px;\n}\n\n.filter-btn {\n padding: 8px 16px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.filter-btn:hover {\n border-color: var(--test-primary-light);\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.filter-btn.active {\n background: var(--test-primary);\n color: var(--mj-text-inverse);\n border-color: var(--test-primary);\n}\n\n.history-actions {\n display: flex;\n gap: 8px;\n}\n\n/* KPI Cards */\n.history-kpi-cards {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 16px;\n}\n\n.kpi-card {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 18px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n box-shadow: var(--test-shadow-sm);\n transition: var(--test-transition);\n}\n\n.kpi-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.kpi-icon {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-brand-primary);\n border-radius: var(--test-radius-md);\n color: var(--mj-text-inverse);\n font-size: 20px;\n flex-shrink: 0;\n}\n\n.kpi-icon.pass-rate {\n background: var(--mj-status-success);\n}\n\n.kpi-content {\n flex: 1;\n min-width: 0;\n}\n\n.kpi-value {\n font-size: 22px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.kpi-label {\n font-size: 12px;\n color: var(--test-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-top: 2px;\n}\n\n.trend-icon {\n font-size: 14px;\n}\n\n.trend-icon.trend-up {\n color: var(--test-success);\n}\n\n.trend-icon.trend-down {\n color: var(--test-error);\n}\n\n/* History Section */\n.history-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.history-section h3 {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.history-section h3 i {\n color: var(--test-primary);\n}\n\n/* History Table */\n.history-table-container {\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.history-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 14px;\n}\n\n.history-table th,\n.history-table td {\n padding: 12px 16px;\n text-align: left;\n border-bottom: 1px solid var(--test-border);\n}\n\n.history-table th {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n}\n\n.history-table tbody tr:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 3%, transparent);\n}\n\n.date-cell {\n font-weight: 600;\n color: var(--test-text);\n}\n\n.passed-cell {\n color: var(--test-success);\n font-weight: 600;\n}\n\n.failed-cell {\n color: var(--test-error);\n font-weight: 600;\n}\n\n.pass-rate-cell {\n min-width: 120px;\n}\n\n.pass-rate-bar {\n position: relative;\n height: 24px;\n background: var(--test-bg);\n border-radius: 12px;\n overflow: hidden;\n}\n\n.pass-rate-fill {\n position: absolute;\n left: 0;\n top: 0;\n height: 100%;\n background: var(--mj-status-success);\n border-radius: 12px;\n transition: width 0.5s ease-out;\n}\n\n.pass-rate-text {\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n font-size: 11px;\n font-weight: 700;\n color: var(--test-text);\n z-index: 1;\n}\n\n/* Suite Performance List */\n.suite-performance-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.suite-perf-card {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 18px;\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.suite-perf-card:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n}\n\n.suite-perf-header {\n flex: 1;\n min-width: 0;\n}\n\n.suite-perf-name {\n font-size: 15px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 6px;\n}\n\n.suite-perf-tags {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.tag-mini {\n display: inline-flex;\n padding: 2px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--test-primary);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n}\n\n.tag-more {\n display: inline-flex;\n padding: 2px 8px;\n background: var(--test-border);\n color: var(--test-text-muted);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n}\n\n.suite-perf-stats {\n display: flex;\n gap: 24px;\n flex-wrap: wrap;\n}\n\n.suite-stat {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 2px;\n}\n\n.suite-stat .stat-value {\n font-size: 16px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n.suite-stat .stat-value.pass-rate.high {\n color: var(--test-success);\n}\n\n.suite-stat .stat-value.pass-rate.low {\n color: var(--test-error);\n}\n\n.suite-stat .stat-label {\n font-size: 10px;\n color: var(--test-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.suite-perf-arrow {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.suite-perf-card:hover .suite-perf-arrow {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n/* ===========================\n Print Styles\n =========================== */\n@media print {\n .test-form {\n background: var(--mj-bg-surface);\n height: auto;\n }\n\n .header-actions,\n .tabs-container,\n .keyboard-shortcuts {\n display: none !important;\n }\n\n .tab-content {\n overflow: visible;\n padding: 0;\n }\n\n .info-section,\n .json-section,\n .config-section {\n break-inside: avoid;\n box-shadow: none;\n border: 1px solid var(--mj-border-default);\n }\n}\n\n/* ===========================\n Editable Form Sections (Config tab)\n =========================== */\n\n.edit-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.edit-section-header {\n margin: 0 0 18px 0;\n}\n\n.edit-section-header h3 {\n margin: 0 0 4px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.edit-section-header h3 i {\n color: var(--test-primary);\n}\n\n.edit-section-sub {\n margin: 0;\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.edit-grid {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 18px;\n}\n\n@media (max-width: 720px) {\n .edit-grid {\n grid-template-columns: 1fr;\n }\n}\n\n.edit-field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n min-width: 0;\n}\n\n.edit-field--full {\n grid-column: 1 / -1;\n}\n\n.edit-field label {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.edit-field .required {\n color: var(--mj-status-error);\n margin-left: 2px;\n}\n\n.config-textarea {\n resize: vertical;\n min-height: 72px;\n font-family: inherit;\n line-height: 1.5;\n}\n\n.select-wrapper {\n position: relative;\n}\n\n.select-wrapper select.config-input {\n padding-right: 36px;\n appearance: none;\n background-color: var(--test-surface);\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%2364748b' d='M1.41 0L6 4.59 10.59 0 12 1.41l-6 6-6-6z'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 14px center;\n background-size: 10px 7px;\n}\n\n/* Tag editor (chips + inline input) */\n.tag-editor {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 8px 10px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n transition: var(--test-transition);\n cursor: text;\n min-height: 42px;\n align-items: center;\n}\n\n.tag-editor:focus-within {\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.tag-chip-editable {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 4px 3px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n border-radius: 999px;\n font-size: 12px;\n font-weight: 600;\n line-height: 1;\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n}\n\n.tag-chip-editable .tag-remove {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n border: none;\n background: transparent;\n color: var(--mj-brand-primary);\n cursor: pointer;\n font-size: 10px;\n transition: background 0.15s;\n}\n\n.tag-chip-editable .tag-remove:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n color: var(--mj-brand-primary-hover);\n}\n\n.tag-input-inline {\n flex: 1;\n min-width: 140px;\n border: none;\n background: transparent;\n outline: none;\n font-size: 13px;\n color: var(--test-text);\n padding: 4px 2px;\n}\n\n.tag-input-inline::placeholder {\n color: var(--test-text-muted);\n}\n\n/* Read-only metadata block at bottom of Config tab */\n.meta-section {\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--test-radius-md);\n padding: 14px 18px;\n border: 1px solid var(--test-border);\n}\n\n.meta-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 14px;\n}\n\n.meta-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.meta-label {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.meta-value {\n font-size: 12px;\n color: var(--test-text-secondary);\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.meta-mono {\n font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;\n font-size: 11px;\n}\n\n/* Dirty indicator next to the title */\n.dirty-indicator {\n display: inline-block;\n margin-left: 8px;\n font-size: 14px;\n color: var(--mj-status-warning);\n line-height: 1;\n animation: pulseDot 1.8s ease-in-out infinite;\n vertical-align: middle;\n}\n\n@keyframes pulseDot {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.5; transform: scale(0.85); }\n}\n\n.unsaved-pill {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n border-radius: 999px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.4px;\n}\n\n.unsaved-pill i {\n font-size: 6px;\n animation: pulseDot 1.8s ease-in-out infinite;\n}\n\n/* Pad the bottom of the tab content when the save bar is visible\n so the bar doesn't cover the last form field. */\n.tab-content.has-savebar {\n padding-bottom: 84px;\n}\n\n/* ===========================\n Sticky Save Bar\n =========================== */\n\n.save-bar {\n position: absolute;\n left: 16px;\n right: 96px; /* leaves room for the bottom-right chat launcher */\n bottom: 16px;\n z-index: 50;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n padding: 12px 16px 12px 20px;\n background: var(--mj-bg-surface-elevated, var(--test-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 25%, var(--test-border));\n border-radius: 14px;\n box-shadow: 0 12px 32px color-mix(in srgb, var(--mj-status-warning) 10%, rgba(0, 0, 0, 0.18));\n backdrop-filter: blur(8px);\n /* Hidden / off-screen state by default. The .save-bar--visible class\n animates it up into view. Using `transition` (not `animation`)\n guarantees the change runs every time isDirty toggles. */\n opacity: 0;\n transform: translateY(calc(100% + 32px));\n pointer-events: none;\n transition:\n transform 420ms cubic-bezier(0.16, 1, 0.3, 1),\n opacity 260ms cubic-bezier(0.16, 1, 0.3, 1);\n will-change: transform, opacity;\n}\n\n.save-bar--visible {\n opacity: 1;\n transform: translateY(0);\n pointer-events: auto;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .save-bar {\n transition: opacity 180ms ease-out;\n transform: none;\n }\n .save-bar--visible {\n transform: none;\n }\n}\n\n.save-bar-message {\n display: flex;\n align-items: center;\n gap: 12px;\n min-width: 0;\n}\n\n.save-bar-dot {\n color: var(--mj-status-warning);\n font-size: 12px;\n line-height: 1;\n animation: pulseDot 1.8s ease-in-out infinite;\n}\n\n.save-bar-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.save-bar-text strong {\n font-size: 14px;\n color: var(--test-text);\n font-weight: 700;\n}\n\n.save-bar-fields {\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.save-bar-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.save-bar-btn {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 9px 16px;\n font-size: 13px;\n font-weight: 600;\n border-radius: 8px;\n border: 1px solid transparent;\n cursor: pointer;\n transition: var(--test-transition);\n font-family: inherit;\n}\n\n.save-bar-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.save-bar-btn--primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, white);\n border-color: var(--mj-brand-primary);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n}\n\n.save-bar-btn--primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n transform: translateY(-1px);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 45%, transparent);\n}\n\n.save-bar-btn--primary:active:not(:disabled) {\n transform: translateY(0);\n}\n\n.save-bar-btn--ghost {\n background: transparent;\n color: var(--test-text-secondary);\n border-color: var(--test-border);\n}\n\n.save-bar-btn--ghost:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n border-color: var(--test-text-muted);\n}\n\n.save-bar-kbd {\n display: inline-flex;\n gap: 3px;\n margin-left: 6px;\n opacity: 0.85;\n}\n\n.save-bar-kbd kbd {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 4px;\n font-size: 10px;\n font-weight: 600;\n font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;\n background: color-mix(in srgb, white 18%, transparent);\n border: 1px solid color-mix(in srgb, white 35%, transparent);\n border-radius: 4px;\n color: inherit;\n}\n\n@media (max-width: 640px) {\n .save-bar {\n left: 8px;\n right: 8px;\n bottom: 88px; /* push above the chat launcher on small screens */\n flex-direction: column;\n align-items: stretch;\n padding: 12px;\n }\n .save-bar-actions {\n justify-content: space-between;\n }\n .save-bar-kbd {\n display: none;\n }\n}\n\n"] }]
2793
+ args: [{ standalone: false, selector: 'mj-test-form', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"test-form\">\n <!-- Header Section -->\n <div class=\"test-header\">\n <!-- Breadcrumb Navigation -->\n <nav class=\"breadcrumb\" aria-label=\"Breadcrumb\">\n <ol>\n <li>\n <a href=\"javascript:void(0)\" (click)=\"navigateToTestingDashboard()\">\n <i class=\"fas fa-vial\"></i>\n <span class=\"breadcrumb-text\">Testing</span>\n </a>\n </li>\n <li class=\"current\">\n <i class=\"fas fa-chevron-right separator\"></i>\n <i class=\"fas fa-flask\"></i>\n <span>{{ record.Name }}</span>\n </li>\n </ol>\n </nav>\n\n <div class=\"header-content\">\n <div class=\"header-left\">\n <div class=\"test-icon\" [style.background-color]=\"getStatusColor()\">\n <i class=\"fas fa-flask\"></i>\n </div>\n <div class=\"test-info\">\n <h1>\n {{ record.Name }}\n @if (isDirty) {\n <span class=\"dirty-indicator\" title=\"You have unsaved changes\" aria-label=\"Unsaved changes\">\u25CF</span>\n }\n </h1>\n <div class=\"test-meta\">\n <span class=\"status-badge\" [ngClass]=\"getStatusClass()\">\n <i class=\"fas\" [ngClass]=\"getStatusIcon()\"></i>\n {{ record.Status }}\n </span>\n @if (record.Type) {\n <span class=\"test-type\">\n <i class=\"fas fa-tag\"></i>\n {{ record.Type }}\n </span>\n }\n @if (isDirty) {\n <span class=\"unsaved-pill\" title=\"You have unsaved changes\">\n <i class=\"fas fa-circle\"></i> Unsaved\n </span>\n }\n </div>\n </div>\n </div>\n <div class=\"header-actions\">\n <app-evaluation-mode-toggle></app-evaluation-mode-toggle>\n <button mjButton (click)=\"runTest()\" variant=\"primary\">\n <i class=\"fas fa-play\"></i> Run Test\n </button>\n <button mjButton (click)=\"refresh()\" [disabled]=\"isRefreshing\">\n <i class=\"fas\" [ngClass]=\"isRefreshing ? 'fa-sync fa-spin' : 'fa-sync'\"></i>\n {{ isRefreshing ? 'Refreshing...' : 'Refresh' }}\n </button>\n </div>\n </div>\n\n <!-- Test Description -->\n @if (record.Description) {\n <div class=\"test-description\">\n <p>{{ record.Description }}</p>\n </div>\n }\n\n <!-- Metrics Bar -->\n @if (testRunsLoaded && testRuns.length > 0) {\n <div class=\"metrics-bar\">\n <div class=\"metric-card\">\n <div class=\"metric-label\">Total Runs</div>\n <div class=\"metric-value\">{{ testRuns.length }}</div>\n </div>\n <div class=\"metric-card\">\n <div class=\"metric-label\">Pass Rate</div>\n <div class=\"metric-value\">{{ getPassRate().toFixed(1) }}%</div>\n <div class=\"metric-progress\">\n <div class=\"metric-progress-fill\" [style.width.%]=\"getPassRate()\"></div>\n </div>\n </div>\n <div class=\"metric-card\">\n <div class=\"metric-label\">Avg Cost</div>\n <div class=\"metric-value\">{{ formatCost(getAverageCost()) }}</div>\n </div>\n <div class=\"metric-card\">\n <div class=\"metric-label\">Avg Duration</div>\n <div class=\"metric-value\">{{ formatDuration(getAverageDuration()) }}</div>\n </div>\n </div>\n }\n </div>\n\n <!-- Tabs -->\n <div class=\"tabs-container\">\n <!-- Phone: the strip becomes one button that opens the Sections sheet -->\n <mj-section-picker class=\"phone-section-picker\"\n [Items]=\"SectionPickerItems\"\n [ActiveKey]=\"ActiveTab\"\n (ActiveKeyChange)=\"OnSectionPicked($event)\"></mj-section-picker>\n <div class=\"tabs\" role=\"tablist\">\n <button class=\"tab\"\n [class.active]=\"activeTab === 'overview'\"\n (click)=\"changeTab('overview')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'overview'\">\n <i class=\"fas fa-th-large\"></i>\n <span>Overview</span>\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'config'\"\n (click)=\"changeTab('config')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'config'\">\n <i class=\"fas fa-sliders-h\"></i>\n <span>Configuration</span>\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'runs'\"\n (click)=\"changeTab('runs')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'runs'\">\n <i class=\"fas fa-history\"></i>\n <span>Runs</span>\n @if (testRunsLoaded) {\n <span class=\"tab-badge\">{{ testRuns.length }}</span>\n }\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'suites'\"\n (click)=\"changeTab('suites')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'suites'\">\n <i class=\"fas fa-layer-group\"></i>\n <span>Test Suites</span>\n @if (suiteTestsLoaded) {\n <span class=\"tab-badge\">{{ suiteTests.length }}</span>\n }\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'analytics'\"\n (click)=\"changeTab('analytics')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'analytics'\">\n <i class=\"fas fa-chart-line\"></i>\n <span>Analytics</span>\n </button>\n </div>\n </div>\n\n <!-- Tab Content -->\n <div class=\"tab-content\" [class.has-savebar]=\"isDirty\">\n <!-- Overview Tab -->\n @if (activeTab === 'overview') {\n <div class=\"overview-tab\">\n <!-- Basic Information -->\n <div class=\"info-section\">\n <h3><i class=\"fas fa-info-circle\"></i> Test Information</h3>\n <div class=\"info-grid\">\n <div class=\"info-item\">\n <div class=\"info-label\">Name</div>\n <div class=\"info-value\">{{ record.Name }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Type</div>\n <div class=\"info-value\">{{ record.Type || 'N/A' }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Status</div>\n <div class=\"info-value\">\n <span class=\"status-badge-inline\" [ngClass]=\"getStatusClass()\">{{ record.Status }}</span>\n </div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Priority</div>\n <div class=\"info-value\">{{ record.Priority || 'N/A' }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Estimated Duration</div>\n <div class=\"info-value\">{{ record.EstimatedDurationSeconds ? formatDuration(record.EstimatedDurationSeconds) : 'N/A' }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Estimated Cost</div>\n <div class=\"info-value\">{{ record.EstimatedCostUSD ? formatCost(record.EstimatedCostUSD) : 'N/A' }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Repeat Count</div>\n <div class=\"info-value\">{{ record.RepeatCount || 1 }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Max Execution Time</div>\n <div class=\"info-value\">{{ formatTimeout(record.MaxExecutionTimeMS) }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Created</div>\n <div class=\"info-value\">{{ record.__mj_CreatedAt | date:'medium' }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Updated</div>\n <div class=\"info-value\">{{ record.__mj_UpdatedAt | date:'medium' }}</div>\n </div>\n </div>\n </div>\n <!-- JSON Data Views -->\n <div class=\"json-section\">\n <h3><i class=\"fas fa-code\"></i> Test Definition</h3>\n <div class=\"json-tabs\">\n <button class=\"json-tab\"\n [class.active]=\"activeJsonView === 'input'\"\n (click)=\"setJsonView('input')\">\n <i class=\"fas fa-sign-in-alt\"></i>\n Input Definition\n </button>\n <button class=\"json-tab\"\n [class.active]=\"activeJsonView === 'expected'\"\n (click)=\"setJsonView('expected')\">\n <i class=\"fas fa-check-double\"></i>\n Expected Outcomes\n </button>\n <button class=\"json-tab\"\n [class.active]=\"activeJsonView === 'config'\"\n (click)=\"setJsonView('config')\">\n <i class=\"fas fa-cog\"></i>\n Configuration\n </button>\n <button class=\"json-tab\"\n [class.active]=\"activeJsonView === 'tags'\"\n (click)=\"setJsonView('tags')\">\n <i class=\"fas fa-tags\"></i>\n Tags\n </button>\n </div>\n <div class=\"code-editor-container\">\n <mj-code-editor\n [value]=\"getJsonData()\"\n language=\"json\"\n [readonly]=\"true\"\n [toolbar]=\"jsonToolbar\"\n [lineWrapping]=\"true\">\n </mj-code-editor>\n </div>\n </div>\n </div>\n }\n\n <!-- Configuration Tab -->\n @if (activeTab === 'config') {\n <div class=\"config-tab\">\n <!-- Details -->\n <section class=\"edit-section\">\n <header class=\"edit-section-header\">\n <h3><i class=\"fas fa-pen-to-square\"></i> Details</h3>\n <p class=\"edit-section-sub\">Edit any field \u2014 changes are saved with the bar at the bottom.</p>\n </header>\n <div class=\"edit-grid\">\n <div class=\"edit-field edit-field--full\">\n <label for=\"test-name\">Name <span class=\"required\">*</span></label>\n <input\n id=\"test-name\"\n type=\"text\"\n class=\"config-input\"\n placeholder=\"e.g., Agent Response Quality Test\"\n [(ngModel)]=\"record.Name\"\n />\n </div>\n\n <div class=\"edit-field edit-field--full\">\n <label for=\"test-description\">Description</label>\n <textarea\n id=\"test-description\"\n class=\"config-input config-textarea\"\n rows=\"3\"\n placeholder=\"What does this test evaluate?\"\n [ngModel]=\"record.Description\"\n (ngModelChange)=\"record.Description = $event || null\"\n ></textarea>\n </div>\n\n <div class=\"edit-field\">\n <label for=\"test-status\">Status</label>\n <div class=\"select-wrapper\">\n <select\n id=\"test-status\"\n class=\"config-input\"\n [(ngModel)]=\"record.Status\"\n >\n @for (opt of statusOptions; track opt) {\n <option [ngValue]=\"opt\">{{ opt }}</option>\n }\n </select>\n </div>\n </div>\n\n <div class=\"edit-field\">\n <label for=\"test-rubric\">Rubric</label>\n <select\n id=\"test-rubric\"\n class=\"config-input\"\n [ngModel]=\"record.RubricID\"\n (ngModelChange)=\"record.RubricID = $event || null\"\n >\n <option [ngValue]=\"null\">\u2014 None \u2014</option>\n @for (rubric of RubricOptions; track rubric.id) {\n <option [ngValue]=\"rubric.id\">{{ rubric.name }}</option>\n }\n </select>\n </div>\n\n <div class=\"edit-field\">\n <label for=\"test-type\">Test Type</label>\n <select\n id=\"test-type\"\n class=\"config-input\"\n [(ngModel)]=\"record.TypeID\"\n >\n @for (t of testTypeOptions; track t.ID) {\n <option [ngValue]=\"t.ID\">{{ t.Name }}</option>\n }\n </select>\n </div>\n\n <div class=\"edit-field edit-field--full\">\n <label for=\"test-tags\">Tags</label>\n <div class=\"tag-editor\" (click)=\"tagInput.focus()\">\n @for (tag of tags; track tag) {\n <span class=\"tag-chip-editable\">\n {{ tag }}\n <button type=\"button\" class=\"tag-remove\" (click)=\"removeTag(tag); $event.stopPropagation()\" [attr.aria-label]=\"'Remove tag ' + tag\">\n <i class=\"fas fa-times\"></i>\n </button>\n </span>\n }\n <input\n #tagInput\n id=\"test-tags\"\n type=\"text\"\n class=\"tag-input-inline\"\n [placeholder]=\"tags.length === 0 ? 'Add tags, press Enter or comma...' : ''\"\n [(ngModel)]=\"tagDraft\"\n (keydown)=\"onTagInputKeydown($event)\"\n (blur)=\"addTagFromDraft()\"\n />\n </div>\n <span class=\"config-hint\">Press Enter or comma to add a tag. Backspace on empty input removes the last tag.</span>\n </div>\n </div>\n </section>\n\n <!-- Execution Settings -->\n <section class=\"edit-section\">\n <header class=\"edit-section-header\">\n <h3><i class=\"fas fa-cogs\"></i> Execution Settings</h3>\n </header>\n <div class=\"edit-grid\">\n <div class=\"edit-field\">\n <label for=\"test-priority\">Priority</label>\n <input\n id=\"test-priority\"\n type=\"number\"\n class=\"config-input\"\n placeholder=\"0 (lower runs first)\"\n [ngModel]=\"record.Priority\"\n (ngModelChange)=\"record.Priority = $event === '' || $event === null ? null : +$event\"\n />\n <span class=\"config-hint\">Lower numbers run first.</span>\n </div>\n <div class=\"edit-field\">\n <label for=\"test-repeat\">Repeat Count</label>\n <input\n id=\"test-repeat\"\n type=\"number\"\n class=\"config-input\"\n min=\"1\"\n placeholder=\"1\"\n [ngModel]=\"record.RepeatCount\"\n (ngModelChange)=\"record.RepeatCount = $event === '' || $event === null ? null : +$event\"\n />\n <span class=\"config-hint\">Number of times to repeat for statistical analysis.</span>\n </div>\n <div class=\"edit-field\">\n <label for=\"test-duration\">Estimated Duration (seconds)</label>\n <input\n id=\"test-duration\"\n type=\"number\"\n class=\"config-input\"\n placeholder=\"0\"\n [ngModel]=\"record.EstimatedDurationSeconds\"\n (ngModelChange)=\"record.EstimatedDurationSeconds = $event === '' || $event === null ? null : +$event\"\n />\n </div>\n <div class=\"edit-field\">\n <label for=\"test-cost\">Estimated Cost (USD)</label>\n <input\n id=\"test-cost\"\n type=\"number\"\n step=\"0.000001\"\n class=\"config-input\"\n placeholder=\"0.00\"\n [ngModel]=\"record.EstimatedCostUSD\"\n (ngModelChange)=\"record.EstimatedCostUSD = $event === '' || $event === null ? null : +$event\"\n />\n </div>\n <div class=\"edit-field edit-field--full\">\n <label for=\"test-timeout\">Max Execution Time (ms)</label>\n <input\n id=\"test-timeout\"\n type=\"number\"\n class=\"config-input\"\n placeholder=\"Default: 300000 (5 min)\"\n [ngModel]=\"record.MaxExecutionTimeMS\"\n (ngModelChange)=\"record.MaxExecutionTimeMS = $event === '' || $event === null ? null : +$event\"\n />\n <span class=\"config-hint\">Leave empty for the default 5 minute timeout. Currently: {{ formatTimeout(record.MaxExecutionTimeMS) }}</span>\n </div>\n </div>\n </section>\n\n <!-- JSON editors (preserved from original layout) -->\n <div class=\"config-section\">\n <h3><i class=\"fas fa-sign-in-alt\"></i> Input Definition (JSON)</h3>\n <div class=\"config-editor-container\">\n <mj-code-editor\n [value]=\"record.InputDefinition || ''\"\n language=\"json\"\n [readonly]=\"false\"\n [lineWrapping]=\"true\"\n (change)=\"record.InputDefinition = $event\">\n </mj-code-editor>\n </div>\n </div>\n <div class=\"config-section\">\n <h3><i class=\"fas fa-check-double\"></i> Expected Outcomes (JSON)</h3>\n <div class=\"config-editor-container\">\n <mj-code-editor\n [value]=\"record.ExpectedOutcomes || ''\"\n language=\"json\"\n [readonly]=\"false\"\n [lineWrapping]=\"true\"\n (change)=\"record.ExpectedOutcomes = $event\">\n </mj-code-editor>\n </div>\n </div>\n <div class=\"config-section\">\n <h3><i class=\"fas fa-cog\"></i> Configuration (JSON)</h3>\n <div class=\"config-editor-container\">\n <mj-code-editor\n [value]=\"record.Configuration || ''\"\n language=\"json\"\n [readonly]=\"false\"\n [lineWrapping]=\"true\"\n (change)=\"record.Configuration = $event\">\n </mj-code-editor>\n </div>\n </div>\n\n <!-- Metadata (read-only) -->\n <section class=\"meta-section\">\n <div class=\"meta-grid\">\n <div class=\"meta-item\">\n <div class=\"meta-label\">Created</div>\n <div class=\"meta-value\">{{ record.__mj_CreatedAt | date:'medium' }}</div>\n </div>\n <div class=\"meta-item\">\n <div class=\"meta-label\">Last updated</div>\n <div class=\"meta-value\">{{ record.__mj_UpdatedAt | date:'medium' }}</div>\n </div>\n <div class=\"meta-item\">\n <div class=\"meta-label\">Test ID</div>\n <div class=\"meta-value meta-mono\">{{ record.ID }}</div>\n </div>\n </div>\n </section>\n </div>\n }\n\n <!-- Test Runs Tab -->\n @if (activeTab === 'runs') {\n <div class=\"runs-tab\">\n <!-- Loading State -->\n @if (loadingRuns) {\n <div class=\"loading-state\">\n <div class=\"skeleton-list\">\n @for (i of [1,2,3,4,5]; track i) {\n <div class=\"skeleton-card\">\n <div class=\"skeleton-icon\"></div>\n <div class=\"skeleton-content\">\n <div class=\"skeleton-line wide\"></div>\n <div class=\"skeleton-line narrow\"></div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Runs List -->\n @if (!loadingRuns && testRuns.length > 0) {\n <div class=\"runs-list\">\n @for (run of testRuns; track run) {\n <div class=\"run-item\" (click)=\"openTestRun(run.ID)\">\n <div class=\"run-icon\" [style.background-color]=\"getRunStatusColor(run.Status)\">\n <i class=\"fas\"\n [class.fa-check]=\"run.Status === 'Passed'\"\n [class.fa-times]=\"run.Status === 'Failed'\"\n [class.fa-exclamation]=\"run.Status === 'Error'\"\n [class.fa-stopwatch]=\"run.Status === 'Timeout'\"\n [class.fa-spinner]=\"run.Status === 'Running'\"\n [class.fa-clock]=\"run.Status === 'Pending'\"></i>\n </div>\n <div class=\"run-content\">\n <div class=\"run-header\">\n <span class=\"run-id\">Run #{{ run.ID.substring(0, 8) }}</span>\n <span class=\"run-status\" [style.color]=\"getRunStatusColor(run.Status)\">{{ run.Status }}</span>\n </div>\n <div class=\"run-meta\">\n <span><i class=\"fas fa-calendar\"></i> {{ getRelativeTime(run.StartedAt) }}</span>\n @if (run.DurationSeconds) {\n <span><i class=\"fas fa-clock\"></i> {{ formatDuration(run.DurationSeconds) }}</span>\n }\n @if (run.CostUSD) {\n <span><i class=\"fas fa-dollar-sign\"></i> {{ formatCost(run.CostUSD) }}</span>\n }\n @if (run.TargetLogEntityID && run.TargetLogID) {\n <mj-entity-link-pill\n [entityName]=\"run.TargetLogEntity\"\n [recordId]=\"run.TargetLogID\">\n </mj-entity-link-pill>\n }\n </div>\n <!-- Evaluation indicators -->\n <div class=\"run-eval-stack\">\n <!-- Status indicator -->\n @if (evalPreferences.showExecution) {\n <span class=\"eval-pill status-pill\"\n [ngClass]=\"'status-' + run.Status.toLowerCase()\"\n [title]=\"getStatusTooltip(run.Status)\">\n <i class=\"fas\"\n [class.fa-check]=\"run.Status === 'Passed'\"\n [class.fa-times]=\"run.Status === 'Failed'\"\n [class.fa-exclamation]=\"run.Status === 'Error'\"\n [class.fa-hourglass-end]=\"run.Status === 'Timeout'\"\n [class.fa-forward]=\"run.Status === 'Skipped'\"\n [class.fa-spinner]=\"run.Status === 'Running'\"\n [class.fa-clock]=\"run.Status === 'Pending'\"></i>\n <span>{{ run.Status }}</span>\n </span>\n }\n <!-- Human feedback indicator -->\n @if (evalPreferences.showHuman) {\n @if (!getFeedbackForRun(run.ID)?.Rating) {\n <span class=\"eval-pill human-pill no-feedback\"\n title=\"Human Review: No rating submitted yet\">\n <i class=\"fas fa-user-slash\"></i>\n </span>\n }\n @if (getFeedbackForRun(run.ID)?.Rating; as rating) {\n <span class=\"eval-pill human-pill has-feedback\"\n [class.rating-low]=\"rating <= 4\"\n [class.rating-medium]=\"rating >= 5 && rating <= 6\"\n [class.rating-good]=\"rating >= 7 && rating <= 8\"\n [class.rating-excellent]=\"rating >= 9\"\n [title]=\"getHumanTooltip(rating, getFeedbackForRun(run.ID)?.CorrectionSummary || getFeedbackForRun(run.ID)?.Comments || null)\">\n <i class=\"fas fa-user\"></i>\n <span>{{ rating }}</span>\n </span>\n }\n }\n <!-- Auto score indicator -->\n @if (evalPreferences.showAuto) {\n @if (run.Score == null) {\n <span class=\"eval-pill auto-pill no-score\"\n title=\"Auto Score: No automated score available\">\n <i class=\"fas fa-robot\"></i>\n </span>\n }\n @if (run.Score != null) {\n <span class=\"eval-pill auto-pill has-score\"\n [class.score-low]=\"run.Score < 0.5\"\n [class.score-medium]=\"run.Score >= 0.5 && run.Score < 0.7\"\n [class.score-good]=\"run.Score >= 0.7 && run.Score < 0.85\"\n [class.score-excellent]=\"run.Score >= 0.85\"\n [title]=\"'Auto Score: ' + (run.Score * 100).toFixed(0) + '% automated evaluation'\">\n <i class=\"fas fa-robot\"></i>\n <span>{{ (run.Score * 100).toFixed(0) }}%</span>\n </span>\n }\n }\n </div>\n @if (getRunTags(run).length > 0) {\n <div class=\"run-tags\">\n @for (tag of getRunTags(run).slice(0, 3); track tag) {\n <span class=\"run-tag\">{{ tag }}</span>\n }\n @if (getRunTags(run).length > 3) {\n <span class=\"run-tag-more\">+{{ getRunTags(run).length - 3 }}</span>\n }\n </div>\n }\n </div>\n <i class=\"fas fa-chevron-right\"></i>\n </div>\n }\n </div>\n }\n <!-- Empty State -->\n @if (testRunsLoaded && !loadingRuns && testRuns.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-circle-play\"\n Title=\"No Test Runs Yet\"\n Message=\"Run this test to see execution history and results here.\"\n ActionText=\"Run Test Now\"\n ActionIcon=\"fa-solid fa-play\"\n (Action)=\"runTest()\" />\n }\n </div>\n }\n\n <!-- Test Suites Tab -->\n @if (activeTab === 'suites') {\n <div class=\"suites-tab\">\n <!-- Loading State -->\n @if (loadingSuites) {\n <div class=\"loading-state\">\n <div class=\"skeleton-list\">\n @for (i of [1,2,3]; track i) {\n <div class=\"skeleton-card\">\n <div class=\"skeleton-icon\"></div>\n <div class=\"skeleton-content\">\n <div class=\"skeleton-line wide\"></div>\n <div class=\"skeleton-line narrow\"></div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Suites List -->\n @if (!loadingSuites && suiteTests.length > 0) {\n <div class=\"suites-list\">\n @for (suiteTest of suiteTests; track suiteTest) {\n <div class=\"suite-item\" (click)=\"openTestSuite(suiteTest.SuiteID)\">\n <div class=\"suite-icon\">\n <i class=\"fas fa-layer-group\"></i>\n </div>\n <div class=\"suite-content\">\n <div class=\"suite-name\">{{ suiteTest.Suite }}</div>\n <div class=\"suite-meta\">\n <span><i class=\"fas fa-sort-numeric-up\"></i> Sequence: {{ suiteTest.Sequence }}</span>\n @if (suiteTest.Status) {\n <span><i class=\"fas fa-info-circle\"></i> {{ suiteTest.Status }}</span>\n }\n </div>\n </div>\n <i class=\"fas fa-chevron-right\"></i>\n </div>\n }\n </div>\n }\n <!-- Empty State -->\n @if (suiteTestsLoaded && !loadingSuites && suiteTests.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-folder-open\"\n Title=\"Not Part of Any Suite\"\n Message=\"This test is not included in any test suites. Add it to a suite to run it with other tests.\" />\n }\n </div>\n }\n\n <!-- Analytics Tab -->\n @if (activeTab === 'analytics') {\n <div class=\"history-tab\">\n <!-- Loading State -->\n @if (loadingHistory) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading history...\"></mj-loading>\n </div>\n }\n <!-- History Content -->\n @if (!loadingHistory && historyLoaded) {\n <div class=\"history-content\">\n <!-- Filters -->\n <div class=\"history-filters\">\n <div class=\"time-range-filters\">\n <span class=\"filter-label\">Time Range:</span>\n <button class=\"filter-btn\"\n [class.active]=\"historyTimeRange === '7d'\"\n (click)=\"setHistoryTimeRange('7d')\">7 Days</button>\n <button class=\"filter-btn\"\n [class.active]=\"historyTimeRange === '30d'\"\n (click)=\"setHistoryTimeRange('30d')\">30 Days</button>\n <button class=\"filter-btn\"\n [class.active]=\"historyTimeRange === '90d'\"\n (click)=\"setHistoryTimeRange('90d')\">90 Days</button>\n <button class=\"filter-btn\"\n [class.active]=\"historyTimeRange === 'all'\"\n (click)=\"setHistoryTimeRange('all')\">All Time</button>\n </div>\n <div class=\"history-actions\">\n <button mjButton (click)=\"exportHistoryToCSV()\" [disabled]=\"historyData.length === 0\">\n <i class=\"fas fa-download\"></i> Export CSV\n </button>\n </div>\n </div>\n <!-- KPI Cards -->\n @if (historyData.length > 0) {\n <div class=\"history-kpi-cards\">\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\">\n <i class=\"fas fa-play-circle\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ getTotalRuns() }}</div>\n <div class=\"kpi-label\">Total Runs</div>\n </div>\n </div>\n @if (evalPreferences.showExecution) {\n <div class=\"kpi-card\">\n <div class=\"kpi-icon pass-rate\">\n <i class=\"fas fa-percentage\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">\n {{ getOverallPassRate().toFixed(1) }}%\n <i class=\"fas trend-icon\"\n [class.fa-arrow-up]=\"getPassRateTrend() === 'up'\"\n [class.fa-arrow-down]=\"getPassRateTrend() === 'down'\"\n [class.fa-minus]=\"getPassRateTrend() === 'stable'\"\n [class.trend-up]=\"getPassRateTrend() === 'up'\"\n [class.trend-down]=\"getPassRateTrend() === 'down'\"></i>\n </div>\n <div class=\"kpi-label\">Pass Rate</div>\n </div>\n </div>\n }\n @if (evalPreferences.showAuto) {\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\">\n <i class=\"fas fa-star\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ (getOverallAvgScore() * 100).toFixed(1) }}%</div>\n <div class=\"kpi-label\">Avg Score</div>\n </div>\n </div>\n }\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\">\n <i class=\"fas fa-clock\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ formatDuration(getOverallAvgDuration()) }}</div>\n <div class=\"kpi-label\">Avg Duration</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\">\n <i class=\"fas fa-dollar-sign\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ formatCost(getOverallAvgCost()) }}</div>\n <div class=\"kpi-label\">Avg Cost</div>\n </div>\n </div>\n </div>\n }\n <!-- Daily History Table -->\n @if (historyData.length > 0) {\n <div class=\"history-section\">\n <h3><i class=\"fas fa-calendar-alt\"></i> Daily Performance</h3>\n <div class=\"history-table-container\">\n <table class=\"history-table\">\n <thead>\n <tr>\n <th>Date</th>\n <th>Runs</th>\n @if (evalPreferences.showExecution) {\n <th>Passed</th>\n }\n @if (evalPreferences.showExecution) {\n <th>Failed</th>\n }\n @if (evalPreferences.showExecution) {\n <th>Pass Rate</th>\n }\n @if (evalPreferences.showAuto) {\n <th>Avg Score</th>\n }\n <th>Avg Duration</th>\n <th>Avg Cost</th>\n </tr>\n </thead>\n <tbody>\n @for (day of historyData; track day) {\n <tr>\n <td class=\"date-cell\">{{ day.date | date:'mediumDate' }}</td>\n <td class=\"runs-cell\">{{ day.runCount }}</td>\n @if (evalPreferences.showExecution) {\n <td class=\"passed-cell\">{{ day.passCount }}</td>\n }\n @if (evalPreferences.showExecution) {\n <td class=\"failed-cell\">{{ day.failCount }}</td>\n }\n @if (evalPreferences.showExecution) {\n <td class=\"pass-rate-cell\">\n <div class=\"pass-rate-bar\">\n <div class=\"pass-rate-fill\" [style.width.%]=\"day.passRate\"></div>\n <span class=\"pass-rate-text\">{{ day.passRate.toFixed(1) }}%</span>\n </div>\n </td>\n }\n @if (evalPreferences.showAuto) {\n <td class=\"score-cell\">{{ (day.avgScore * 100).toFixed(1) }}%</td>\n }\n <td class=\"duration-cell\">{{ formatDuration(day.avgDuration) }}</td>\n <td class=\"cost-cell\">{{ formatCost(day.avgCost) }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n }\n <!-- Suite Performance -->\n @if (suitePerformance.length > 0) {\n <div class=\"history-section\">\n <h3><i class=\"fas fa-layer-group\"></i> Performance by Suite</h3>\n <div class=\"suite-performance-list\">\n @for (suite of suitePerformance; track suite) {\n <div class=\"suite-perf-card\" (click)=\"openSuiteFromHistory(suite.suiteId)\">\n <div class=\"suite-perf-header\">\n <div class=\"suite-perf-name\">{{ suite.suiteName }}</div>\n @if (suite.tags.length > 0) {\n <div class=\"suite-perf-tags\">\n @for (tag of suite.tags.slice(0, 3); track tag) {\n <span class=\"tag-mini\">{{ tag }}</span>\n }\n @if (suite.tags.length > 3) {\n <span class=\"tag-more\">+{{ suite.tags.length - 3 }}</span>\n }\n </div>\n }\n </div>\n <div class=\"suite-perf-stats\">\n <div class=\"suite-stat\">\n <span class=\"stat-value\">{{ suite.totalRuns }}</span>\n <span class=\"stat-label\">Runs</span>\n </div>\n @if (evalPreferences.showExecution) {\n <div class=\"suite-stat\">\n <span class=\"stat-value pass-rate\" [class.high]=\"suite.passRate >= 80\" [class.low]=\"suite.passRate < 50\">\n {{ suite.passRate.toFixed(1) }}%\n </span>\n <span class=\"stat-label\">Pass Rate</span>\n </div>\n }\n @if (evalPreferences.showAuto) {\n <div class=\"suite-stat\">\n <span class=\"stat-value\">{{ (suite.avgScore * 100).toFixed(1) }}%</span>\n <span class=\"stat-label\">Avg Score</span>\n </div>\n }\n <div class=\"suite-stat\">\n <span class=\"stat-value\">{{ formatDuration(suite.avgDuration) }}</span>\n <span class=\"stat-label\">Avg Duration</span>\n </div>\n <div class=\"suite-stat\">\n <span class=\"stat-value\">{{ formatCost(suite.avgCost) }}</span>\n <span class=\"stat-label\">Avg Cost</span>\n </div>\n @if (suite.lastRun) {\n <div class=\"suite-stat\">\n <span class=\"stat-value\">{{ getRelativeTime(suite.lastRun) }}</span>\n <span class=\"stat-label\">Last Run</span>\n </div>\n }\n </div>\n <i class=\"fas fa-chevron-right suite-perf-arrow\"></i>\n </div>\n }\n </div>\n </div>\n }\n <!-- Empty State -->\n @if (historyData.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-chart-line\"\n Title=\"No History Available\"\n Message=\"Run this test to start building history and analytics data.\"\n ActionText=\"Run Test Now\"\n ActionIcon=\"fa-solid fa-play\"\n (Action)=\"runTest()\" />\n }\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Keyboard Shortcuts Toggle Button -->\n <button class=\"shortcuts-toggle\" (click)=\"toggleShortcuts()\" [title]=\"showShortcuts ? 'Hide keyboard shortcuts' : 'Show keyboard shortcuts'\">\n <i class=\"fas fa-keyboard\"></i>\n </button>\n\n <!-- Keyboard Shortcuts Hint (Desktop Only) -->\n @if (showShortcuts) {\n <div class=\"keyboard-shortcuts\">\n <div class=\"shortcuts-header\">\n <i class=\"fas fa-keyboard\"></i>\n Shortcuts\n <button class=\"shortcuts-close\" (click)=\"toggleShortcuts()\" title=\"Hide shortcuts\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n <div class=\"shortcut-list\">\n <div class=\"shortcut-item\">\n <span>Save changes</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>S</kbd></span>\n </div>\n <div class=\"shortcut-item\">\n <span>Refresh</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>R</kbd></span>\n </div>\n <div class=\"shortcut-item\">\n <span>Run Test</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>Enter</kbd></span>\n </div>\n <div class=\"shortcut-item\">\n <span>Switch Tabs</span>\n <span class=\"shortcut-keys\"><kbd>1</kbd>-<kbd>5</kbd></span>\n </div>\n </div>\n </div>\n }\n\n <!-- Slide Panel for Test Execution -->\n @if (testingDialogService.IsPanelOpen) {\n <mj-slide-panel\n Mode=\"slide\"\n [Title]=\"testingDialogService.PanelOptions?.testId ? 'Test Execution' : 'Run Test'\"\n [Resizable]=\"true\"\n (Closed)=\"OnPanelClosed()\">\n <app-test-run-dialog\n [PanelMode]=\"true\"\n [selectedTestId]=\"testingDialogService.PanelOptions?.testId ?? null\"\n [selectedSuiteId]=\"testingDialogService.PanelOptions?.suiteId ?? null\"\n [runMode]=\"testingDialogService.PanelOptions?.mode ?? 'test'\"\n (PanelClose)=\"OnPanelClosed()\">\n </app-test-run-dialog>\n </mj-slide-panel>\n }\n\n <!-- Sticky Save Bar \u2014 always in the DOM so CSS transitions can fire reliably.\n Visibility is controlled by the .save-bar--visible class, driven by isDirty. -->\n <div\n class=\"save-bar\"\n [class.save-bar--visible]=\"isDirty\"\n [attr.aria-hidden]=\"!isDirty\"\n role=\"region\"\n aria-label=\"Unsaved changes\"\n >\n <div class=\"save-bar-message\">\n <span class=\"save-bar-dot\" aria-hidden=\"true\">\u25CF</span>\n <span class=\"save-bar-text\">\n <strong>Unsaved changes</strong>\n <span class=\"save-bar-fields\">\n @if (dirtyFieldNames.length === 1) {\n {{ dirtyFieldNames[0] }} edited\n } @else if (dirtyFieldNames.length > 1) {\n {{ dirtyFieldNames.length }} fields edited\n }\n </span>\n </span>\n </div>\n <div class=\"save-bar-actions\">\n <button\n type=\"button\"\n class=\"save-bar-btn save-bar-btn--primary\"\n (click)=\"saveChanges()\"\n [disabled]=\"isSaving || !isDirty\"\n [attr.tabindex]=\"isDirty ? 0 : -1\"\n title=\"Save changes (\u2318S)\"\n >\n @if (isSaving) {\n <i class=\"fas fa-spinner fa-spin\"></i> Saving\u2026\n } @else {\n <i class=\"fas fa-check\"></i> Save changes\n <span class=\"save-bar-kbd\"><kbd>\u2318</kbd><kbd>S</kbd></span>\n }\n </button>\n <button\n type=\"button\"\n class=\"save-bar-btn save-bar-btn--ghost\"\n (click)=\"discardChanges()\"\n [disabled]=\"isSaving || !isDirty\"\n [attr.tabindex]=\"isDirty ? 0 : -1\"\n title=\"Discard changes\"\n >\n <i class=\"fas fa-undo\"></i> Discard\n </button>\n </div>\n </div>\n</div>\n", styles: ["/* ===========================\n Test Form - World-Class UX\n Premium Test Definition Styles\n =========================== */\n\n/* CSS Custom Properties for Theming - using :host for Angular encapsulation */\n:host {\n --test-primary: var(--mj-brand-primary);\n --test-primary-light: var(--mj-brand-primary);\n --test-primary-dark: var(--mj-brand-primary-hover);\n --test-success: var(--mj-status-success);\n --test-success-light: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n --test-error: var(--mj-status-error);\n --test-error-light: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n --test-warning: var(--mj-status-warning);\n --test-warning-light: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n --test-disabled: var(--mj-text-muted);\n --test-bg: var(--mj-bg-surface-card);\n --test-surface: var(--mj-bg-surface);\n --test-border: var(--mj-border-default);\n --test-text: var(--mj-text-primary);\n --test-text-secondary: var(--mj-text-muted);\n --test-text-muted: var(--mj-text-disabled);\n --test-radius-sm: 6px;\n --test-radius-md: 10px;\n --test-radius-lg: 16px;\n --test-shadow-sm: var(--mj-shadow-sm);\n --test-shadow-md: var(--mj-shadow-md);\n --test-shadow-lg: var(--mj-shadow-lg);\n --test-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n display: block;\n height: 100%;\n}\n\n/* Breadcrumb */\n.breadcrumb {\n margin-bottom: 16px;\n}\n\n.breadcrumb ol {\n display: flex;\n align-items: center;\n gap: 4px;\n list-style: none;\n margin: 0;\n padding: 0;\n font-size: 13px;\n}\n\n.breadcrumb li {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.breadcrumb a {\n color: var(--test-primary);\n text-decoration: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n border-radius: 6px;\n transition: background 0.15s;\n}\n\n.breadcrumb a:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n text-decoration: none;\n}\n\n.breadcrumb .separator {\n font-size: 10px;\n color: var(--test-text-muted);\n margin: 0 4px;\n}\n\n.breadcrumb .current {\n color: var(--test-text-secondary);\n font-weight: 500;\n}\n\n.breadcrumb-text {\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Base Container */\n.test-form {\n position: relative;\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--test-bg);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n/* ===========================\n Header Section\n =========================== */\n.test-header {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n padding: 20px;\n}\n\n.header-content {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 16px;\n gap: 16px;\n}\n\n.header-left {\n display: flex;\n gap: 16px;\n flex: 1;\n min-width: 0;\n}\n\n/* Test Icon */\n.test-icon {\n width: 56px;\n height: 56px;\n border-radius: var(--test-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-inverse);\n font-size: 24px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-md);\n transition: var(--test-transition);\n}\n\n.test-icon:hover {\n transform: scale(1.05);\n}\n\n/* Test Info */\n.test-info {\n flex: 1;\n min-width: 0;\n}\n\n.test-info h1 {\n margin: 0 0 8px 0;\n font-size: clamp(18px, 4vw, 24px);\n font-weight: 700;\n color: var(--test-text);\n line-height: 1.2;\n word-wrap: break-word;\n}\n\n.test-meta {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n/* Status Badge */\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n color: var(--mj-text-inverse);\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.status-badge.status-active { background: var(--mj-status-success); }\n.status-badge.status-disabled { background: var(--mj-text-secondary); }\n.status-badge.status-pending { background: var(--mj-status-warning); }\n\n.status-badge-inline {\n display: inline-flex;\n align-items: center;\n padding: 2px 10px;\n border-radius: 10px;\n color: var(--mj-text-inverse);\n font-size: 11px;\n font-weight: 600;\n}\n\n.status-badge-inline.status-active { background: var(--test-success); }\n.status-badge-inline.status-disabled { background: var(--test-disabled); }\n.status-badge-inline.status-pending { background: var(--test-warning); }\n\n.test-type {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 14px;\n color: var(--test-text-secondary);\n padding: 4px 10px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n}\n\n.header-actions {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.header-actions button {\n white-space: nowrap;\n}\n\n/* Test Description */\n.test-description {\n padding: 16px;\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--test-radius-md);\n margin-bottom: 16px;\n border: 1px solid var(--test-border);\n}\n\n.test-description p {\n margin: 0;\n color: var(--test-text-secondary);\n line-height: 1.6;\n font-size: 14px;\n}\n\n/* ===========================\n Metrics Bar\n =========================== */\n.metrics-bar {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));\n gap: 12px;\n}\n\n.metric-card {\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 14px;\n text-align: center;\n transition: var(--test-transition);\n}\n\n.metric-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.metric-label {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n margin-bottom: 6px;\n}\n\n.metric-value {\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n/* Progress bar in metric card */\n.metric-progress {\n margin-top: 8px;\n height: 4px;\n background: var(--test-border);\n border-radius: 2px;\n overflow: hidden;\n}\n\n.metric-progress-fill {\n height: 100%;\n background: var(--mj-status-success);\n border-radius: 2px;\n transition: width 0.5s ease-out;\n}\n\n/* ===========================\n Tabs Navigation\n =========================== */\n.tabs-container {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n position: sticky;\n top: 0;\n z-index: 10;\n}\n\n/* Phone section picker: hidden until the 768px rule swaps it in for the strip */\n.phone-section-picker {\n display: none;\n}\n\n.tabs {\n display: flex;\n padding: 0 20px;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n -ms-overflow-style: none;\n}\n\n.tabs::-webkit-scrollbar {\n display: none;\n}\n\n.tab {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 14px 18px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: var(--test-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n white-space: nowrap;\n}\n\n.tab:hover {\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.tab.active {\n color: var(--test-primary);\n border-bottom-color: var(--test-primary);\n font-weight: 600;\n}\n\n.tab i {\n font-size: 15px;\n}\n\n.tab-badge {\n background: var(--test-border);\n color: var(--test-text-secondary);\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n transition: var(--test-transition);\n}\n\n.tab.active .tab-badge {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n color: var(--test-primary);\n}\n\n.tab-shortcut {\n font-size: 10px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n margin-left: 4px;\n}\n\n/* ===========================\n Tab Content Area\n =========================== */\n.tab-content {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n scroll-behavior: smooth;\n}\n\n/* ===========================\n Overview Tab\n =========================== */\n.overview-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: fadeIn 0.3s ease-out;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* Info Section */\n.info-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.info-section h3 {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.info-section h3 i {\n color: var(--test-primary);\n}\n\n.info-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n}\n\n.info-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.info-label {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.info-value {\n font-size: 14px;\n color: var(--test-text);\n word-wrap: break-word;\n font-weight: 500;\n}\n\n/* JSON Section */\n.json-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.json-section h3 {\n margin: 0 0 16px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.json-section h3 i {\n color: var(--test-primary);\n}\n\n.json-tabs {\n display: flex;\n gap: 4px;\n margin-bottom: 16px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n padding: 4px;\n flex-wrap: wrap;\n}\n\n.json-tab {\n flex: 1;\n min-width: 100px;\n padding: 10px 14px;\n border: none;\n background: transparent;\n color: var(--test-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n border-radius: var(--test-radius-sm);\n transition: var(--test-transition);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n}\n\n.json-tab:hover {\n color: var(--test-text);\n background: var(--mj-bg-overlay);\n}\n\n.json-tab.active {\n background: var(--test-surface);\n color: var(--test-primary);\n font-weight: 600;\n box-shadow: var(--test-shadow-sm);\n}\n\n.json-tab i {\n font-size: 12px;\n}\n\n.code-editor-container {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid var(--test-border);\n min-height: 200px;\n max-height: 400px;\n}\n\n/* ===========================\n Configuration Tab\n =========================== */\n.config-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: fadeIn 0.3s ease-out;\n}\n\n.config-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.config-section h3 {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.config-section h3 i {\n color: var(--test-primary);\n}\n\n.config-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\n gap: 20px;\n}\n\n.config-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.config-item.full-width {\n grid-column: 1 / -1;\n}\n\n.config-item label {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.config-input {\n padding: 10px 14px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n font-size: 14px;\n transition: var(--test-transition);\n background: var(--test-surface);\n}\n\n.config-input:focus {\n outline: none;\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.config-input::placeholder {\n color: var(--test-text-muted);\n}\n\n.config-hint {\n font-size: 11px;\n color: var(--test-text-muted);\n margin-top: 4px;\n}\n\n.config-editor-container {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid var(--test-border);\n min-height: 200px;\n}\n\n.config-editor-container.small {\n min-height: 100px;\n max-height: 150px;\n}\n\n/* ===========================\n Runs Tab\n =========================== */\n.runs-tab,\n.suites-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n/* Loading States & Skeletons */\n.loading-state {\n padding: 0;\n}\n\n.skeleton-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.skeleton-card {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.skeleton-icon {\n width: 44px;\n height: 44px;\n border-radius: var(--test-radius-md);\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n flex-shrink: 0;\n}\n\n.skeleton-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.skeleton-line {\n height: 14px;\n border-radius: 4px;\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-line.wide { width: 70%; }\n.skeleton-line.narrow { width: 40%; }\n\n@keyframes shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n/* Runs List */\n.runs-list,\n.suites-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.run-item,\n.suite-item {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.run-item:hover,\n.suite-item:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n box-shadow: var(--test-shadow-sm);\n}\n\n.run-icon,\n.suite-icon {\n width: 44px;\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--test-radius-md);\n color: var(--mj-text-inverse);\n font-size: 18px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-sm);\n}\n\n.suite-icon {\n background: var(--mj-status-warning);\n}\n\n.run-content,\n.suite-content {\n flex: 1;\n min-width: 0;\n}\n\n.run-header {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 4px;\n}\n\n.run-id {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.run-status {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.suite-name {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 4px;\n}\n\n.run-meta,\n.suite-meta {\n display: flex;\n gap: 16px;\n font-size: 12px;\n color: var(--test-text-secondary);\n flex-wrap: wrap;\n}\n\n.run-meta span,\n.suite-meta span {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.run-meta span i,\n.suite-meta span i {\n color: var(--test-text-muted);\n font-size: 11px;\n}\n\n.run-item > i.fa-chevron-right,\n.suite-item > i.fa-chevron-right {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.run-item:hover > i.fa-chevron-right,\n.suite-item:hover > i.fa-chevron-right {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n/* Run Evaluation Stack */\n.run-eval-stack {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n flex-wrap: wrap;\n}\n\n/* Evaluation Pills */\n.eval-pill {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n transition: var(--test-transition);\n}\n\n.eval-pill i {\n font-size: 10px;\n}\n\n/* Status pill colors */\n.eval-pill.status-pill.status-passed {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.eval-pill.status-pill.status-failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.eval-pill.status-pill.status-error {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.eval-pill.status-pill.status-timeout {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.eval-pill.status-pill.status-skipped,\n.eval-pill.status-pill.status-pending {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.eval-pill.status-pill.status-running {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n/* Human feedback pills */\n.eval-pill.human-pill.no-feedback {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n padding: 4px 8px;\n}\n\n.eval-pill.human-pill.has-feedback.rating-low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.eval-pill.human-pill.has-feedback.rating-medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.eval-pill.human-pill.has-feedback.rating-good {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.eval-pill.human-pill.has-feedback.rating-excellent {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n/* Auto score pills */\n.eval-pill.auto-pill.no-score {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n padding: 4px 8px;\n}\n\n.eval-pill.auto-pill.has-score.score-low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.eval-pill.auto-pill.has-score.score-medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.eval-pill.auto-pill.has-score.score-good {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.eval-pill.auto-pill.has-score.score-excellent {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n/* Run Tags */\n.run-tags {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 8px;\n flex-wrap: wrap;\n}\n\n.run-tag {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--test-primary);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n}\n\n.run-tag-more {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n background: var(--test-border);\n color: var(--test-text-muted);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n}\n\n/* ===========================\n Keyboard Shortcuts Popup\n =========================== */\n/* Keyboard shortcuts toggle button */\n.shortcuts-toggle {\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n box-shadow: var(--test-shadow-md);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--test-text-secondary);\n font-size: 14px;\n z-index: 99;\n transition: var(--test-transition);\n opacity: 0.7;\n}\n\n.shortcuts-toggle:hover {\n opacity: 1;\n transform: scale(1.1);\n color: var(--test-primary);\n border-color: var(--test-primary);\n}\n\n.keyboard-shortcuts {\n position: fixed;\n bottom: 20px;\n right: 20px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 12px 16px;\n box-shadow: var(--test-shadow-lg);\n font-size: 12px;\n color: var(--test-text-secondary);\n z-index: 100;\n max-width: 260px;\n}\n\n.shortcuts-header {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-bottom: 10px;\n padding-bottom: 8px;\n border-bottom: 1px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text);\n}\n\n.shortcuts-close {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--test-text-muted);\n font-size: 12px;\n padding: 2px 4px;\n border-radius: 4px;\n transition: var(--test-transition);\n}\n\n.shortcuts-close:hover {\n color: var(--test-text);\n background: var(--test-border);\n}\n\n.shortcut-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.shortcut-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.shortcut-keys {\n display: flex;\n gap: 4px;\n}\n\n.shortcut-keys kbd {\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: 4px;\n padding: 2px 6px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n font-size: 11px;\n color: var(--test-text);\n}\n\n/* ===========================\n Responsive Design - Tablet\n =========================== */\n@media (max-width: 1024px) {\n .metrics-bar {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .info-grid {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .config-grid {\n grid-template-columns: 1fr;\n }\n\n .keyboard-shortcuts, .shortcuts-toggle {\n display: none;\n }\n}\n\n/* ===========================\n Responsive Design - Mobile\n =========================== */\n@media (max-width: 768px) {\n /* The tab strip becomes one section-picker button (same pattern as the standard record form). */\n .tabs {\n display: none;\n }\n\n .phone-section-picker {\n display: block;\n padding: 4px 8px;\n }\n\n .test-form {\n height: auto;\n min-height: 100%;\n }\n\n .test-header {\n padding: 16px;\n }\n\n .header-content {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-left {\n width: 100%;\n }\n\n .test-icon {\n width: 48px;\n height: 48px;\n font-size: 20px;\n }\n\n .test-info h1 {\n font-size: 18px;\n }\n\n .test-meta {\n gap: 8px;\n }\n\n .status-badge {\n padding: 4px 10px;\n font-size: 11px;\n }\n\n .header-actions {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions button {\n flex: 1;\n }\n\n .metrics-bar {\n grid-template-columns: repeat(2, 1fr);\n gap: 10px;\n }\n\n .metric-card {\n padding: 12px;\n }\n\n .metric-value {\n font-size: 16px;\n }\n\n .tabs {\n padding: 0 12px;\n }\n\n .tab {\n padding: 12px 14px;\n font-size: 13px;\n gap: 6px;\n }\n\n .tab i {\n font-size: 14px;\n }\n\n .tab-shortcut {\n display: none;\n }\n\n .tab-content {\n padding: 16px;\n }\n\n .info-section,\n .json-section,\n .config-section {\n padding: 18px;\n }\n\n .info-grid {\n grid-template-columns: 1fr;\n }\n\n .json-tabs {\n flex-direction: column;\n }\n\n .json-tab {\n min-width: 0;\n justify-content: flex-start;\n }\n\n .run-item,\n .suite-item {\n padding: 14px;\n }\n\n .run-icon,\n .suite-icon {\n width: 40px;\n height: 40px;\n font-size: 16px;\n }\n\n .run-meta,\n .suite-meta {\n flex-direction: column;\n gap: 4px;\n }\n\n}\n\n/* ===========================\n Responsive Design - Small Mobile\n =========================== */\n@media (max-width: 480px) {\n .test-header {\n padding: 12px;\n }\n\n .header-left {\n gap: 12px;\n }\n\n .test-icon {\n width: 40px;\n height: 40px;\n font-size: 18px;\n border-radius: 8px;\n }\n\n .test-info h1 {\n font-size: 16px;\n }\n\n .metrics-bar {\n grid-template-columns: 1fr 1fr;\n }\n\n .tabs {\n padding: 0 8px;\n }\n\n .tab {\n padding: 10px 12px;\n font-size: 12px;\n }\n\n .tab-badge {\n display: none;\n }\n\n .tab-content {\n padding: 12px;\n }\n\n .run-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 4px;\n }\n}\n\n/* ===========================\n Touch Device Optimizations\n =========================== */\n@media (hover: none) and (pointer: coarse) {\n .tab,\n .json-tab,\n .run-item,\n .suite-item {\n -webkit-tap-highlight-color: transparent;\n }\n\n .run-item:active,\n .suite-item:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n transform: scale(0.98);\n }\n\n .tab:active,\n .json-tab:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n }\n\n /* Larger touch targets */\n .tab {\n min-height: 48px;\n }\n\n .run-item,\n .suite-item {\n min-height: 64px;\n }\n}\n\n/* ===========================\n Reduced Motion\n =========================== */\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n\n .skeleton-icon,\n .skeleton-line {\n animation: none;\n background: var(--mj-border-default);\n }\n}\n\n/* ===========================\n History Tab\n =========================== */\n.history-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n.history-content {\n display: flex;\n flex-direction: column;\n gap: 24px;\n}\n\n/* History Filters */\n.history-filters {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 16px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n box-shadow: var(--test-shadow-sm);\n}\n\n.time-range-filters {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.filter-label {\n font-size: 13px;\n font-weight: 600;\n color: var(--test-text-secondary);\n margin-right: 4px;\n}\n\n.filter-btn {\n padding: 8px 16px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.filter-btn:hover {\n border-color: var(--test-primary-light);\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.filter-btn.active {\n background: var(--test-primary);\n color: var(--mj-text-inverse);\n border-color: var(--test-primary);\n}\n\n.history-actions {\n display: flex;\n gap: 8px;\n}\n\n/* KPI Cards */\n.history-kpi-cards {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 16px;\n}\n\n.kpi-card {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 18px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n box-shadow: var(--test-shadow-sm);\n transition: var(--test-transition);\n}\n\n.kpi-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.kpi-icon {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-brand-primary);\n border-radius: var(--test-radius-md);\n color: var(--mj-text-inverse);\n font-size: 20px;\n flex-shrink: 0;\n}\n\n.kpi-icon.pass-rate {\n background: var(--mj-status-success);\n}\n\n.kpi-content {\n flex: 1;\n min-width: 0;\n}\n\n.kpi-value {\n font-size: 22px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.kpi-label {\n font-size: 12px;\n color: var(--test-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-top: 2px;\n}\n\n.trend-icon {\n font-size: 14px;\n}\n\n.trend-icon.trend-up {\n color: var(--test-success);\n}\n\n.trend-icon.trend-down {\n color: var(--test-error);\n}\n\n/* History Section */\n.history-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.history-section h3 {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.history-section h3 i {\n color: var(--test-primary);\n}\n\n/* History Table */\n.history-table-container {\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.history-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 14px;\n}\n\n.history-table th,\n.history-table td {\n padding: 12px 16px;\n text-align: left;\n border-bottom: 1px solid var(--test-border);\n}\n\n.history-table th {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n}\n\n.history-table tbody tr:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 3%, transparent);\n}\n\n.date-cell {\n font-weight: 600;\n color: var(--test-text);\n}\n\n.passed-cell {\n color: var(--test-success);\n font-weight: 600;\n}\n\n.failed-cell {\n color: var(--test-error);\n font-weight: 600;\n}\n\n.pass-rate-cell {\n min-width: 120px;\n}\n\n.pass-rate-bar {\n position: relative;\n height: 24px;\n background: var(--test-bg);\n border-radius: 12px;\n overflow: hidden;\n}\n\n.pass-rate-fill {\n position: absolute;\n left: 0;\n top: 0;\n height: 100%;\n background: var(--mj-status-success);\n border-radius: 12px;\n transition: width 0.5s ease-out;\n}\n\n.pass-rate-text {\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n font-size: 11px;\n font-weight: 700;\n color: var(--test-text);\n z-index: 1;\n}\n\n/* Suite Performance List */\n.suite-performance-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.suite-perf-card {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 18px;\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.suite-perf-card:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n}\n\n.suite-perf-header {\n flex: 1;\n min-width: 0;\n}\n\n.suite-perf-name {\n font-size: 15px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 6px;\n}\n\n.suite-perf-tags {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.tag-mini {\n display: inline-flex;\n padding: 2px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--test-primary);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n}\n\n.tag-more {\n display: inline-flex;\n padding: 2px 8px;\n background: var(--test-border);\n color: var(--test-text-muted);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n}\n\n.suite-perf-stats {\n display: flex;\n gap: 24px;\n flex-wrap: wrap;\n}\n\n.suite-stat {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 2px;\n}\n\n.suite-stat .stat-value {\n font-size: 16px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n.suite-stat .stat-value.pass-rate.high {\n color: var(--test-success);\n}\n\n.suite-stat .stat-value.pass-rate.low {\n color: var(--test-error);\n}\n\n.suite-stat .stat-label {\n font-size: 10px;\n color: var(--test-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.suite-perf-arrow {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.suite-perf-card:hover .suite-perf-arrow {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n/* ===========================\n Print Styles\n =========================== */\n@media print {\n .test-form {\n background: var(--mj-bg-surface);\n height: auto;\n }\n\n .header-actions,\n .tabs-container,\n .keyboard-shortcuts {\n display: none !important;\n }\n\n .tab-content {\n overflow: visible;\n padding: 0;\n }\n\n .info-section,\n .json-section,\n .config-section {\n break-inside: avoid;\n box-shadow: none;\n border: 1px solid var(--mj-border-default);\n }\n}\n\n/* ===========================\n Editable Form Sections (Config tab)\n =========================== */\n\n.edit-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.edit-section-header {\n margin: 0 0 18px 0;\n}\n\n.edit-section-header h3 {\n margin: 0 0 4px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.edit-section-header h3 i {\n color: var(--test-primary);\n}\n\n.edit-section-sub {\n margin: 0;\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.edit-grid {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 18px;\n}\n\n@media (max-width: 720px) {\n .edit-grid {\n grid-template-columns: 1fr;\n }\n}\n\n.edit-field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n min-width: 0;\n}\n\n.edit-field--full {\n grid-column: 1 / -1;\n}\n\n.edit-field label {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.edit-field .required {\n color: var(--mj-status-error);\n margin-left: 2px;\n}\n\n.config-textarea {\n resize: vertical;\n min-height: 72px;\n font-family: inherit;\n line-height: 1.5;\n}\n\n.select-wrapper {\n position: relative;\n}\n\n.select-wrapper select.config-input {\n padding-right: 36px;\n appearance: none;\n background-color: var(--test-surface);\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%2364748b' d='M1.41 0L6 4.59 10.59 0 12 1.41l-6 6-6-6z'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 14px center;\n background-size: 10px 7px;\n}\n\n/* Tag editor (chips + inline input) */\n.tag-editor {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 8px 10px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n transition: var(--test-transition);\n cursor: text;\n min-height: 42px;\n align-items: center;\n}\n\n.tag-editor:focus-within {\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.tag-chip-editable {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 4px 3px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n border-radius: 999px;\n font-size: 12px;\n font-weight: 600;\n line-height: 1;\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n}\n\n.tag-chip-editable .tag-remove {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n border: none;\n background: transparent;\n color: var(--mj-brand-primary);\n cursor: pointer;\n font-size: 10px;\n transition: background 0.15s;\n}\n\n.tag-chip-editable .tag-remove:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n color: var(--mj-brand-primary-hover);\n}\n\n.tag-input-inline {\n flex: 1;\n min-width: 140px;\n border: none;\n background: transparent;\n outline: none;\n font-size: 13px;\n color: var(--test-text);\n padding: 4px 2px;\n}\n\n.tag-input-inline::placeholder {\n color: var(--test-text-muted);\n}\n\n/* Read-only metadata block at bottom of Config tab */\n.meta-section {\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--test-radius-md);\n padding: 14px 18px;\n border: 1px solid var(--test-border);\n}\n\n.meta-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 14px;\n}\n\n.meta-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.meta-label {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.meta-value {\n font-size: 12px;\n color: var(--test-text-secondary);\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.meta-mono {\n font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;\n font-size: 11px;\n}\n\n/* Dirty indicator next to the title */\n.dirty-indicator {\n display: inline-block;\n margin-left: 8px;\n font-size: 14px;\n color: var(--mj-status-warning);\n line-height: 1;\n animation: pulseDot 1.8s ease-in-out infinite;\n vertical-align: middle;\n}\n\n@keyframes pulseDot {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.5; transform: scale(0.85); }\n}\n\n.unsaved-pill {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n border-radius: 999px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.4px;\n}\n\n.unsaved-pill i {\n font-size: 6px;\n animation: pulseDot 1.8s ease-in-out infinite;\n}\n\n/* Pad the bottom of the tab content when the save bar is visible\n so the bar doesn't cover the last form field. */\n.tab-content.has-savebar {\n padding-bottom: 84px;\n}\n\n/* ===========================\n Sticky Save Bar\n =========================== */\n\n.save-bar {\n position: absolute;\n left: 16px;\n right: 96px; /* leaves room for the bottom-right chat launcher */\n bottom: 16px;\n z-index: 50;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n padding: 12px 16px 12px 20px;\n background: var(--mj-bg-surface-elevated, var(--test-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 25%, var(--test-border));\n border-radius: 14px;\n box-shadow: 0 12px 32px color-mix(in srgb, var(--mj-status-warning) 10%, rgba(0, 0, 0, 0.18));\n backdrop-filter: blur(8px);\n /* Hidden / off-screen state by default. The .save-bar--visible class\n animates it up into view. Using `transition` (not `animation`)\n guarantees the change runs every time isDirty toggles. */\n opacity: 0;\n transform: translateY(calc(100% + 32px));\n pointer-events: none;\n transition:\n transform 420ms cubic-bezier(0.16, 1, 0.3, 1),\n opacity 260ms cubic-bezier(0.16, 1, 0.3, 1);\n will-change: transform, opacity;\n}\n\n.save-bar--visible {\n opacity: 1;\n transform: translateY(0);\n pointer-events: auto;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .save-bar {\n transition: opacity 180ms ease-out;\n transform: none;\n }\n .save-bar--visible {\n transform: none;\n }\n}\n\n.save-bar-message {\n display: flex;\n align-items: center;\n gap: 12px;\n min-width: 0;\n}\n\n.save-bar-dot {\n color: var(--mj-status-warning);\n font-size: 12px;\n line-height: 1;\n animation: pulseDot 1.8s ease-in-out infinite;\n}\n\n.save-bar-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.save-bar-text strong {\n font-size: 14px;\n color: var(--test-text);\n font-weight: 700;\n}\n\n.save-bar-fields {\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.save-bar-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.save-bar-btn {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 9px 16px;\n font-size: 13px;\n font-weight: 600;\n border-radius: 8px;\n border: 1px solid transparent;\n cursor: pointer;\n transition: var(--test-transition);\n font-family: inherit;\n}\n\n.save-bar-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.save-bar-btn--primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, white);\n border-color: var(--mj-brand-primary);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n}\n\n.save-bar-btn--primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n transform: translateY(-1px);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 45%, transparent);\n}\n\n.save-bar-btn--primary:active:not(:disabled) {\n transform: translateY(0);\n}\n\n.save-bar-btn--ghost {\n background: transparent;\n color: var(--test-text-secondary);\n border-color: var(--test-border);\n}\n\n.save-bar-btn--ghost:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n border-color: var(--test-text-muted);\n}\n\n.save-bar-kbd {\n display: inline-flex;\n gap: 3px;\n margin-left: 6px;\n opacity: 0.85;\n}\n\n.save-bar-kbd kbd {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 4px;\n font-size: 10px;\n font-weight: 600;\n font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;\n background: color-mix(in srgb, white 18%, transparent);\n border: 1px solid color-mix(in srgb, white 35%, transparent);\n border-radius: 4px;\n color: inherit;\n}\n\n@media (max-width: 640px) {\n .save-bar {\n left: 8px;\n right: 8px;\n bottom: 88px; /* push above the chat launcher on small screens */\n flex-direction: column;\n align-items: stretch;\n padding: 12px;\n }\n .save-bar-actions {\n justify-content: space-between;\n }\n .save-bar-kbd {\n display: none;\n }\n}\n\n/* Phone (375px): the action row wraps instead of running past the edge, the SHOW\n toggle takes its own line, and the breadcrumb wraps. (The tab strip is\n hidden on phones; the section picker replaces it.) */\n@media (max-width: 768px) {\n .header-actions {\n flex-wrap: wrap;\n }\n\n .header-actions app-evaluation-mode-toggle {\n flex-basis: 100%;\n }\n\n .breadcrumb ol {\n flex-wrap: wrap;\n }\n\n .breadcrumb li {\n min-width: 0;\n }\n}\n"] }]
2774
2794
  }], null, { handleKeyboardShortcut: [{
2775
2795
  type: HostListener,
2776
2796
  args: ['document:keydown', ['$event']]