@memberjunction/ng-core-entity-forms 5.34.1 → 5.36.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 (295) hide show
  1. package/dist/lib/custom/Lists/list-form.component.d.ts +6 -0
  2. package/dist/lib/custom/Lists/list-form.component.d.ts.map +1 -1
  3. package/dist/lib/custom/Lists/list-form.component.js +271 -204
  4. package/dist/lib/custom/Lists/list-form.component.js.map +1 -1
  5. package/dist/lib/custom/Tests/test-form.component.d.ts +25 -1
  6. package/dist/lib/custom/Tests/test-form.component.d.ts.map +1 -1
  7. package/dist/lib/custom/Tests/test-form.component.js +898 -547
  8. package/dist/lib/custom/Tests/test-form.component.js.map +1 -1
  9. package/dist/lib/custom/Tests/test-suite-form.component.d.ts +56 -1
  10. package/dist/lib/custom/Tests/test-suite-form.component.d.ts.map +1 -1
  11. package/dist/lib/custom/Tests/test-suite-form.component.js +1647 -788
  12. package/dist/lib/custom/Tests/test-suite-form.component.js.map +1 -1
  13. package/dist/lib/custom/custom-forms.module.d.ts +25 -24
  14. package/dist/lib/custom/custom-forms.module.d.ts.map +1 -1
  15. package/dist/lib/custom/custom-forms.module.js +4 -0
  16. package/dist/lib/custom/custom-forms.module.js.map +1 -1
  17. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js +178 -176
  18. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js.map +1 -1
  19. package/dist/lib/generated/Entities/MJAIAgentAction/mjaiagentaction.form.component.js +2 -2
  20. package/dist/lib/generated/Entities/MJAIAgentAction/mjaiagentaction.form.component.js.map +1 -1
  21. package/dist/lib/generated/Entities/MJAIAgentCategory/mjaiagentcategory.form.component.js +1 -1
  22. package/dist/lib/generated/Entities/MJAIAgentCategory/mjaiagentcategory.form.component.js.map +1 -1
  23. package/dist/lib/generated/Entities/MJAIAgentDataSource/mjaiagentdatasource.form.component.js +2 -2
  24. package/dist/lib/generated/Entities/MJAIAgentDataSource/mjaiagentdatasource.form.component.js.map +1 -1
  25. package/dist/lib/generated/Entities/MJAIAgentExample/mjaiagentexample.form.component.js +3 -3
  26. package/dist/lib/generated/Entities/MJAIAgentExample/mjaiagentexample.form.component.js.map +1 -1
  27. package/dist/lib/generated/Entities/MJAIAgentLearningCycle/mjaiagentlearningcycle.form.component.js +1 -1
  28. package/dist/lib/generated/Entities/MJAIAgentLearningCycle/mjaiagentlearningcycle.form.component.js.map +1 -1
  29. package/dist/lib/generated/Entities/MJAIAgentNote/mjaiagentnote.form.component.js +3 -3
  30. package/dist/lib/generated/Entities/MJAIAgentNote/mjaiagentnote.form.component.js.map +1 -1
  31. package/dist/lib/generated/Entities/MJAIAgentPermission/mjaiagentpermission.form.component.js +1 -1
  32. package/dist/lib/generated/Entities/MJAIAgentPermission/mjaiagentpermission.form.component.js.map +1 -1
  33. package/dist/lib/generated/Entities/MJAIAgentPrompt/mjaiagentprompt.form.component.js +1 -1
  34. package/dist/lib/generated/Entities/MJAIAgentPrompt/mjaiagentprompt.form.component.js.map +1 -1
  35. package/dist/lib/generated/Entities/MJAIAgentRelationship/mjaiagentrelationship.form.component.js +1 -1
  36. package/dist/lib/generated/Entities/MJAIAgentRelationship/mjaiagentrelationship.form.component.js.map +1 -1
  37. package/dist/lib/generated/Entities/MJAIAgentRequest/mjaiagentrequest.form.component.js +1 -1
  38. package/dist/lib/generated/Entities/MJAIAgentRequest/mjaiagentrequest.form.component.js.map +1 -1
  39. package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.js +6 -6
  40. package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.js.map +1 -1
  41. package/dist/lib/generated/Entities/MJAIAgentRunMedia/mjaiagentrunmedia.form.component.js +1 -1
  42. package/dist/lib/generated/Entities/MJAIAgentRunMedia/mjaiagentrunmedia.form.component.js.map +1 -1
  43. package/dist/lib/generated/Entities/MJAIAgentRunStep/mjaiagentrunstep.form.component.js +1 -1
  44. package/dist/lib/generated/Entities/MJAIAgentRunStep/mjaiagentrunstep.form.component.js.map +1 -1
  45. package/dist/lib/generated/Entities/MJAIAgentSearchScope/mjaiagentsearchscope.form.component.js +2 -2
  46. package/dist/lib/generated/Entities/MJAIAgentSearchScope/mjaiagentsearchscope.form.component.js.map +1 -1
  47. package/dist/lib/generated/Entities/MJAIAgentStep/mjaiagentstep.form.component.js +2 -2
  48. package/dist/lib/generated/Entities/MJAIAgentStep/mjaiagentstep.form.component.js.map +1 -1
  49. package/dist/lib/generated/Entities/MJAIAgentType/mjaiagenttype.form.component.js +2 -2
  50. package/dist/lib/generated/Entities/MJAIAgentType/mjaiagenttype.form.component.js.map +1 -1
  51. package/dist/lib/generated/Entities/MJAIArchitecture/mjaiarchitecture.form.component.js +1 -1
  52. package/dist/lib/generated/Entities/MJAIArchitecture/mjaiarchitecture.form.component.js.map +1 -1
  53. package/dist/lib/generated/Entities/MJAIConfiguration/mjaiconfiguration.form.component.js +1 -1
  54. package/dist/lib/generated/Entities/MJAIConfiguration/mjaiconfiguration.form.component.js.map +1 -1
  55. package/dist/lib/generated/Entities/MJAIModel/mjaimodel.form.component.js +1 -1
  56. package/dist/lib/generated/Entities/MJAIModel/mjaimodel.form.component.js.map +1 -1
  57. package/dist/lib/generated/Entities/MJAIModelCost/mjaimodelcost.form.component.js +1 -1
  58. package/dist/lib/generated/Entities/MJAIModelCost/mjaimodelcost.form.component.js.map +1 -1
  59. package/dist/lib/generated/Entities/MJAIModelModality/mjaimodelmodality.form.component.js +1 -1
  60. package/dist/lib/generated/Entities/MJAIModelModality/mjaimodelmodality.form.component.js.map +1 -1
  61. package/dist/lib/generated/Entities/MJAIModelType/mjaimodeltype.form.component.js +1 -1
  62. package/dist/lib/generated/Entities/MJAIModelType/mjaimodeltype.form.component.js.map +1 -1
  63. package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.js +3 -3
  64. package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.js.map +1 -1
  65. package/dist/lib/generated/Entities/MJAIPromptModel/mjaipromptmodel.form.component.js +2 -2
  66. package/dist/lib/generated/Entities/MJAIPromptModel/mjaipromptmodel.form.component.js.map +1 -1
  67. package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.js +3 -3
  68. package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.js.map +1 -1
  69. package/dist/lib/generated/Entities/MJAIPromptRunMedia/mjaipromptrunmedia.form.component.js +1 -1
  70. package/dist/lib/generated/Entities/MJAIPromptRunMedia/mjaipromptrunmedia.form.component.js.map +1 -1
  71. package/dist/lib/generated/Entities/MJAIResultCache/mjairesultcache.form.component.js +2 -2
  72. package/dist/lib/generated/Entities/MJAIResultCache/mjairesultcache.form.component.js.map +1 -1
  73. package/dist/lib/generated/Entities/MJAIVendorType/mjaivendortype.form.component.js +1 -1
  74. package/dist/lib/generated/Entities/MJAIVendorType/mjaivendortype.form.component.js.map +1 -1
  75. package/dist/lib/generated/Entities/MJAPIKey/mjapikey.form.component.js +1 -1
  76. package/dist/lib/generated/Entities/MJAPIKey/mjapikey.form.component.js.map +1 -1
  77. package/dist/lib/generated/Entities/MJAPIKeyUsageLog/mjapikeyusagelog.form.component.js +1 -1
  78. package/dist/lib/generated/Entities/MJAPIKeyUsageLog/mjapikeyusagelog.form.component.js.map +1 -1
  79. package/dist/lib/generated/Entities/MJAccessControlRule/mjaccesscontrolrule.form.component.js +1 -1
  80. package/dist/lib/generated/Entities/MJAccessControlRule/mjaccesscontrolrule.form.component.js.map +1 -1
  81. package/dist/lib/generated/Entities/MJAction/mjaction.form.component.js +2 -2
  82. package/dist/lib/generated/Entities/MJAction/mjaction.form.component.js.map +1 -1
  83. package/dist/lib/generated/Entities/MJActionExecutionLog/mjactionexecutionlog.form.component.js +1 -1
  84. package/dist/lib/generated/Entities/MJActionExecutionLog/mjactionexecutionlog.form.component.js.map +1 -1
  85. package/dist/lib/generated/Entities/MJApplication/mjapplication.form.component.js +1 -1
  86. package/dist/lib/generated/Entities/MJApplication/mjapplication.form.component.js.map +1 -1
  87. package/dist/lib/generated/Entities/MJArchiveConfiguration/mjarchiveconfiguration.form.component.js +1 -1
  88. package/dist/lib/generated/Entities/MJArchiveConfiguration/mjarchiveconfiguration.form.component.js.map +1 -1
  89. package/dist/lib/generated/Entities/MJArchiveConfigurationEntity/mjarchiveconfigurationentity.form.component.js +1 -1
  90. package/dist/lib/generated/Entities/MJArchiveConfigurationEntity/mjarchiveconfigurationentity.form.component.js.map +1 -1
  91. package/dist/lib/generated/Entities/MJArchiveRun/mjarchiverun.form.component.js +2 -2
  92. package/dist/lib/generated/Entities/MJArchiveRun/mjarchiverun.form.component.js.map +1 -1
  93. package/dist/lib/generated/Entities/MJArchiveRunDetail/mjarchiverundetail.form.component.js +1 -1
  94. package/dist/lib/generated/Entities/MJArchiveRunDetail/mjarchiverundetail.form.component.js.map +1 -1
  95. package/dist/lib/generated/Entities/MJArtifactType/mjartifacttype.form.component.js +43 -37
  96. package/dist/lib/generated/Entities/MJArtifactType/mjartifacttype.form.component.js.map +1 -1
  97. package/dist/lib/generated/Entities/MJArtifactVersion/mjartifactversion.form.component.d.ts.map +1 -1
  98. package/dist/lib/generated/Entities/MJArtifactVersion/mjartifactversion.form.component.js +52 -32
  99. package/dist/lib/generated/Entities/MJArtifactVersion/mjartifactversion.form.component.js.map +1 -1
  100. package/dist/lib/generated/Entities/MJArtifactVersionAttribute/mjartifactversionattribute.form.component.js +1 -1
  101. package/dist/lib/generated/Entities/MJArtifactVersionAttribute/mjartifactversionattribute.form.component.js.map +1 -1
  102. package/dist/lib/generated/Entities/MJCollection/mjcollection.form.component.js +1 -1
  103. package/dist/lib/generated/Entities/MJCollection/mjcollection.form.component.js.map +1 -1
  104. package/dist/lib/generated/Entities/MJCommunicationLog/mjcommunicationlog.form.component.js +1 -1
  105. package/dist/lib/generated/Entities/MJCommunicationLog/mjcommunicationlog.form.component.js.map +1 -1
  106. package/dist/lib/generated/Entities/MJCommunicationProvider/mjcommunicationprovider.form.component.js +1 -1
  107. package/dist/lib/generated/Entities/MJCommunicationProvider/mjcommunicationprovider.form.component.js.map +1 -1
  108. package/dist/lib/generated/Entities/MJCommunicationRun/mjcommunicationrun.form.component.js +1 -1
  109. package/dist/lib/generated/Entities/MJCommunicationRun/mjcommunicationrun.form.component.js.map +1 -1
  110. package/dist/lib/generated/Entities/MJCompanyIntegration/mjcompanyintegration.form.component.js +3 -3
  111. package/dist/lib/generated/Entities/MJCompanyIntegration/mjcompanyintegration.form.component.js.map +1 -1
  112. package/dist/lib/generated/Entities/MJCompanyIntegrationEntityMap/mjcompanyintegrationentitymap.form.component.js +1 -1
  113. package/dist/lib/generated/Entities/MJCompanyIntegrationEntityMap/mjcompanyintegrationentitymap.form.component.js.map +1 -1
  114. package/dist/lib/generated/Entities/MJCompanyIntegrationRun/mjcompanyintegrationrun.form.component.js +1 -1
  115. package/dist/lib/generated/Entities/MJCompanyIntegrationRun/mjcompanyintegrationrun.form.component.js.map +1 -1
  116. package/dist/lib/generated/Entities/MJCompanyIntegrationRunAPILog/mjcompanyintegrationrunapilog.form.component.js +1 -1
  117. package/dist/lib/generated/Entities/MJCompanyIntegrationRunAPILog/mjcompanyintegrationrunapilog.form.component.js.map +1 -1
  118. package/dist/lib/generated/Entities/MJCompanyIntegrationRunDetail/mjcompanyintegrationrundetail.form.component.js +1 -1
  119. package/dist/lib/generated/Entities/MJCompanyIntegrationRunDetail/mjcompanyintegrationrundetail.form.component.js.map +1 -1
  120. package/dist/lib/generated/Entities/MJComponent/mjcomponent.form.component.js +2 -2
  121. package/dist/lib/generated/Entities/MJComponent/mjcomponent.form.component.js.map +1 -1
  122. package/dist/lib/generated/Entities/MJComponentLibrary/mjcomponentlibrary.form.component.js +1 -1
  123. package/dist/lib/generated/Entities/MJComponentLibrary/mjcomponentlibrary.form.component.js.map +1 -1
  124. package/dist/lib/generated/Entities/MJContentItem/mjcontentitem.form.component.js +1 -1
  125. package/dist/lib/generated/Entities/MJContentItem/mjcontentitem.form.component.js.map +1 -1
  126. package/dist/lib/generated/Entities/MJContentProcessRunDetail/mjcontentprocessrundetail.form.component.js +1 -1
  127. package/dist/lib/generated/Entities/MJContentProcessRunDetail/mjcontentprocessrundetail.form.component.js.map +1 -1
  128. package/dist/lib/generated/Entities/MJContentSource/mjcontentsource.form.component.js +2 -2
  129. package/dist/lib/generated/Entities/MJContentSource/mjcontentsource.form.component.js.map +1 -1
  130. package/dist/lib/generated/Entities/MJContentType/mjcontenttype.form.component.js +2 -2
  131. package/dist/lib/generated/Entities/MJContentType/mjcontenttype.form.component.js.map +1 -1
  132. package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.js +2 -2
  133. package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.js.map +1 -1
  134. package/dist/lib/generated/Entities/MJConversationDetail/mjconversationdetail.form.component.js +3 -3
  135. package/dist/lib/generated/Entities/MJConversationDetail/mjconversationdetail.form.component.js.map +1 -1
  136. package/dist/lib/generated/Entities/MJConversationDetailAttachment/mjconversationdetailattachment.form.component.js +8 -6
  137. package/dist/lib/generated/Entities/MJConversationDetailAttachment/mjconversationdetailattachment.form.component.js.map +1 -1
  138. package/dist/lib/generated/Entities/MJCredential/mjcredential.form.component.js +1 -1
  139. package/dist/lib/generated/Entities/MJCredential/mjcredential.form.component.js.map +1 -1
  140. package/dist/lib/generated/Entities/MJDashboard/mjdashboard.form.component.js +1 -1
  141. package/dist/lib/generated/Entities/MJDashboard/mjdashboard.form.component.js.map +1 -1
  142. package/dist/lib/generated/Entities/MJDashboardCategoryPermission/mjdashboardcategorypermission.form.component.js +1 -1
  143. package/dist/lib/generated/Entities/MJDashboardCategoryPermission/mjdashboardcategorypermission.form.component.js.map +1 -1
  144. package/dist/lib/generated/Entities/MJDashboardUserPreference/mjdashboarduserpreference.form.component.js +1 -1
  145. package/dist/lib/generated/Entities/MJDashboardUserPreference/mjdashboarduserpreference.form.component.js.map +1 -1
  146. package/dist/lib/generated/Entities/MJDataContextItem/mjdatacontextitem.form.component.js +1 -1
  147. package/dist/lib/generated/Entities/MJDataContextItem/mjdatacontextitem.form.component.js.map +1 -1
  148. package/dist/lib/generated/Entities/MJDatasetItem/mjdatasetitem.form.component.js +1 -1
  149. package/dist/lib/generated/Entities/MJDatasetItem/mjdatasetitem.form.component.js.map +1 -1
  150. package/dist/lib/generated/Entities/MJDuplicateRun/mjduplicaterun.form.component.js +1 -1
  151. package/dist/lib/generated/Entities/MJDuplicateRun/mjduplicaterun.form.component.js.map +1 -1
  152. package/dist/lib/generated/Entities/MJEmployee/mjemployee.form.component.js +1 -1
  153. package/dist/lib/generated/Entities/MJEmployee/mjemployee.form.component.js.map +1 -1
  154. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js +5 -5
  155. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js.map +1 -1
  156. package/dist/lib/generated/Entities/MJEntityDocument/mjentitydocument.form.component.js +1 -1
  157. package/dist/lib/generated/Entities/MJEntityDocument/mjentitydocument.form.component.js.map +1 -1
  158. package/dist/lib/generated/Entities/MJEntityField/mjentityfield.form.component.js +3 -3
  159. package/dist/lib/generated/Entities/MJEntityField/mjentityfield.form.component.js.map +1 -1
  160. package/dist/lib/generated/Entities/MJEntityOrganicKey/mjentityorganickey.form.component.js +1 -1
  161. package/dist/lib/generated/Entities/MJEntityOrganicKey/mjentityorganickey.form.component.js.map +1 -1
  162. package/dist/lib/generated/Entities/MJEntityOrganicKeyRelatedEntity/mjentityorganickeyrelatedentity.form.component.js +1 -1
  163. package/dist/lib/generated/Entities/MJEntityOrganicKeyRelatedEntity/mjentityorganickeyrelatedentity.form.component.js.map +1 -1
  164. package/dist/lib/generated/Entities/MJEntityPermission/mjentitypermission.form.component.js +1 -1
  165. package/dist/lib/generated/Entities/MJEntityPermission/mjentitypermission.form.component.js.map +1 -1
  166. package/dist/lib/generated/Entities/MJEntityRecordDocument/mjentityrecorddocument.form.component.js +2 -2
  167. package/dist/lib/generated/Entities/MJEntityRecordDocument/mjentityrecorddocument.form.component.js.map +1 -1
  168. package/dist/lib/generated/Entities/MJEntityRelationship/mjentityrelationship.form.component.js +1 -1
  169. package/dist/lib/generated/Entities/MJEntityRelationship/mjentityrelationship.form.component.js.map +1 -1
  170. package/dist/lib/generated/Entities/MJEnvironment/mjenvironment.form.component.js +1 -1
  171. package/dist/lib/generated/Entities/MJEnvironment/mjenvironment.form.component.js.map +1 -1
  172. package/dist/lib/generated/Entities/MJErrorLog/mjerrorlog.form.component.js +1 -1
  173. package/dist/lib/generated/Entities/MJErrorLog/mjerrorlog.form.component.js.map +1 -1
  174. package/dist/lib/generated/Entities/MJFile/mjfile.form.component.js +1 -1
  175. package/dist/lib/generated/Entities/MJFile/mjfile.form.component.js.map +1 -1
  176. package/dist/lib/generated/Entities/MJFileStorageProvider/mjfilestorageprovider.form.component.js +2 -2
  177. package/dist/lib/generated/Entities/MJFileStorageProvider/mjfilestorageprovider.form.component.js.map +1 -1
  178. package/dist/lib/generated/Entities/MJGeneratedCode/mjgeneratedcode.form.component.js +2 -2
  179. package/dist/lib/generated/Entities/MJGeneratedCode/mjgeneratedcode.form.component.js.map +1 -1
  180. package/dist/lib/generated/Entities/MJIntegration/mjintegration.form.component.js +1 -1
  181. package/dist/lib/generated/Entities/MJIntegration/mjintegration.form.component.js.map +1 -1
  182. package/dist/lib/generated/Entities/MJIntegrationObject/mjintegrationobject.form.component.js +2 -2
  183. package/dist/lib/generated/Entities/MJIntegrationObject/mjintegrationobject.form.component.js.map +1 -1
  184. package/dist/lib/generated/Entities/MJIntegrationObjectField/mjintegrationobjectfield.form.component.js +1 -1
  185. package/dist/lib/generated/Entities/MJIntegrationObjectField/mjintegrationobjectfield.form.component.js.map +1 -1
  186. package/dist/lib/generated/Entities/MJIntegrationURLFormat/mjintegrationurlformat.form.component.js +1 -1
  187. package/dist/lib/generated/Entities/MJIntegrationURLFormat/mjintegrationurlformat.form.component.js.map +1 -1
  188. package/dist/lib/generated/Entities/MJKnowledgeHubSavedSearch/mjknowledgehubsavedsearch.form.component.js +1 -1
  189. package/dist/lib/generated/Entities/MJKnowledgeHubSavedSearch/mjknowledgehubsavedsearch.form.component.js.map +1 -1
  190. package/dist/lib/generated/Entities/MJList/mjlist.form.component.d.ts.map +1 -1
  191. package/dist/lib/generated/Entities/MJList/mjlist.form.component.js +45 -27
  192. package/dist/lib/generated/Entities/MJList/mjlist.form.component.js.map +1 -1
  193. package/dist/lib/generated/Entities/MJListCategory/mjlistcategory.form.component.js +1 -1
  194. package/dist/lib/generated/Entities/MJListCategory/mjlistcategory.form.component.js.map +1 -1
  195. package/dist/lib/generated/Entities/MJMCPServer/mjmcpserver.form.component.js +3 -3
  196. package/dist/lib/generated/Entities/MJMCPServer/mjmcpserver.form.component.js.map +1 -1
  197. package/dist/lib/generated/Entities/MJMCPServerConnection/mjmcpserverconnection.form.component.js +1 -1
  198. package/dist/lib/generated/Entities/MJMCPServerConnection/mjmcpserverconnection.form.component.js.map +1 -1
  199. package/dist/lib/generated/Entities/MJMCPServerTool/mjmcpservertool.form.component.js +1 -1
  200. package/dist/lib/generated/Entities/MJMCPServerTool/mjmcpservertool.form.component.js.map +1 -1
  201. package/dist/lib/generated/Entities/MJMCPToolExecutionLog/mjmcptoolexecutionlog.form.component.js +2 -2
  202. package/dist/lib/generated/Entities/MJMCPToolExecutionLog/mjmcptoolexecutionlog.form.component.js.map +1 -1
  203. package/dist/lib/generated/Entities/MJPermissionDomain/mjpermissiondomain.form.component.js +1 -1
  204. package/dist/lib/generated/Entities/MJPermissionDomain/mjpermissiondomain.form.component.js.map +1 -1
  205. package/dist/lib/generated/Entities/MJProject/mjproject.form.component.js +1 -1
  206. package/dist/lib/generated/Entities/MJProject/mjproject.form.component.js.map +1 -1
  207. package/dist/lib/generated/Entities/MJPublicLink/mjpubliclink.form.component.js +1 -1
  208. package/dist/lib/generated/Entities/MJPublicLink/mjpubliclink.form.component.js.map +1 -1
  209. package/dist/lib/generated/Entities/MJQuery/mjquery.form.component.js +2 -2
  210. package/dist/lib/generated/Entities/MJQuery/mjquery.form.component.js.map +1 -1
  211. package/dist/lib/generated/Entities/MJQueue/mjqueue.form.component.js +1 -1
  212. package/dist/lib/generated/Entities/MJQueue/mjqueue.form.component.js.map +1 -1
  213. package/dist/lib/generated/Entities/MJQueueTask/mjqueuetask.form.component.js +1 -1
  214. package/dist/lib/generated/Entities/MJQueueTask/mjqueuetask.form.component.js.map +1 -1
  215. package/dist/lib/generated/Entities/MJRecommendationRun/mjrecommendationrun.form.component.js +1 -1
  216. package/dist/lib/generated/Entities/MJRecommendationRun/mjrecommendationrun.form.component.js.map +1 -1
  217. package/dist/lib/generated/Entities/MJRecordChange/mjrecordchange.form.component.js +2 -2
  218. package/dist/lib/generated/Entities/MJRecordChange/mjrecordchange.form.component.js.map +1 -1
  219. package/dist/lib/generated/Entities/MJRecordGeoCode/mjrecordgeocode.form.component.js +1 -1
  220. package/dist/lib/generated/Entities/MJRecordGeoCode/mjrecordgeocode.form.component.js.map +1 -1
  221. package/dist/lib/generated/Entities/MJRecordLink/mjrecordlink.form.component.js +1 -1
  222. package/dist/lib/generated/Entities/MJRecordLink/mjrecordlink.form.component.js.map +1 -1
  223. package/dist/lib/generated/Entities/MJRecordMergeLog/mjrecordmergelog.form.component.js +1 -1
  224. package/dist/lib/generated/Entities/MJRecordMergeLog/mjrecordmergelog.form.component.js.map +1 -1
  225. package/dist/lib/generated/Entities/MJReport/mjreport.form.component.js +1 -1
  226. package/dist/lib/generated/Entities/MJReport/mjreport.form.component.js.map +1 -1
  227. package/dist/lib/generated/Entities/MJResourcePermission/mjresourcepermission.form.component.js +2 -2
  228. package/dist/lib/generated/Entities/MJResourcePermission/mjresourcepermission.form.component.js.map +1 -1
  229. package/dist/lib/generated/Entities/MJResourceType/mjresourcetype.form.component.js +2 -2
  230. package/dist/lib/generated/Entities/MJResourceType/mjresourcetype.form.component.js.map +1 -1
  231. package/dist/lib/generated/Entities/MJScheduledAction/mjscheduledaction.form.component.js +1 -1
  232. package/dist/lib/generated/Entities/MJScheduledAction/mjscheduledaction.form.component.js.map +1 -1
  233. package/dist/lib/generated/Entities/MJScheduledJob/mjscheduledjob.form.component.js +3 -3
  234. package/dist/lib/generated/Entities/MJScheduledJob/mjscheduledjob.form.component.js.map +1 -1
  235. package/dist/lib/generated/Entities/MJScheduledJobRun/mjscheduledjobrun.form.component.js +1 -1
  236. package/dist/lib/generated/Entities/MJScheduledJobRun/mjscheduledjobrun.form.component.js.map +1 -1
  237. package/dist/lib/generated/Entities/MJSearchExecutionLog/mjsearchexecutionlog.form.component.js +2 -2
  238. package/dist/lib/generated/Entities/MJSearchExecutionLog/mjsearchexecutionlog.form.component.js.map +1 -1
  239. package/dist/lib/generated/Entities/MJSearchProvider/mjsearchprovider.form.component.js +1 -1
  240. package/dist/lib/generated/Entities/MJSearchProvider/mjsearchprovider.form.component.js.map +1 -1
  241. package/dist/lib/generated/Entities/MJSearchScope/mjsearchscope.form.component.js +3 -3
  242. package/dist/lib/generated/Entities/MJSearchScope/mjsearchscope.form.component.js.map +1 -1
  243. package/dist/lib/generated/Entities/MJSearchScopeEntity/mjsearchscopeentity.form.component.js +1 -1
  244. package/dist/lib/generated/Entities/MJSearchScopeEntity/mjsearchscopeentity.form.component.js.map +1 -1
  245. package/dist/lib/generated/Entities/MJSearchScopeExternalIndex/mjsearchscopeexternalindex.form.component.js +1 -1
  246. package/dist/lib/generated/Entities/MJSearchScopeExternalIndex/mjsearchscopeexternalindex.form.component.js.map +1 -1
  247. package/dist/lib/generated/Entities/MJSearchScopeProvider/mjsearchscopeprovider.form.component.js +1 -1
  248. package/dist/lib/generated/Entities/MJSearchScopeProvider/mjsearchscopeprovider.form.component.js.map +1 -1
  249. package/dist/lib/generated/Entities/MJSearchScopeTestQuery/mjsearchscopetestquery.form.component.js +1 -1
  250. package/dist/lib/generated/Entities/MJSearchScopeTestQuery/mjsearchscopetestquery.form.component.js.map +1 -1
  251. package/dist/lib/generated/Entities/MJTag/mjtag.form.component.js +3 -3
  252. package/dist/lib/generated/Entities/MJTag/mjtag.form.component.js.map +1 -1
  253. package/dist/lib/generated/Entities/MJTagSuggestion/mjtagsuggestion.form.component.js +2 -2
  254. package/dist/lib/generated/Entities/MJTagSuggestion/mjtagsuggestion.form.component.js.map +1 -1
  255. package/dist/lib/generated/Entities/MJTask/mjtask.form.component.js +1 -1
  256. package/dist/lib/generated/Entities/MJTask/mjtask.form.component.js.map +1 -1
  257. package/dist/lib/generated/Entities/MJTemplate/mjtemplate.form.component.js +1 -1
  258. package/dist/lib/generated/Entities/MJTemplate/mjtemplate.form.component.js.map +1 -1
  259. package/dist/lib/generated/Entities/MJTemplateCategory/mjtemplatecategory.form.component.js +1 -1
  260. package/dist/lib/generated/Entities/MJTemplateCategory/mjtemplatecategory.form.component.js.map +1 -1
  261. package/dist/lib/generated/Entities/MJTemplateParam/mjtemplateparam.form.component.js +1 -1
  262. package/dist/lib/generated/Entities/MJTemplateParam/mjtemplateparam.form.component.js.map +1 -1
  263. package/dist/lib/generated/Entities/MJTest/mjtest.form.component.js +1 -1
  264. package/dist/lib/generated/Entities/MJTest/mjtest.form.component.js.map +1 -1
  265. package/dist/lib/generated/Entities/MJTestRun/mjtestrun.form.component.js +2 -2
  266. package/dist/lib/generated/Entities/MJTestRun/mjtestrun.form.component.js.map +1 -1
  267. package/dist/lib/generated/Entities/MJTestRunOutput/mjtestrunoutput.form.component.js +1 -1
  268. package/dist/lib/generated/Entities/MJTestRunOutput/mjtestrunoutput.form.component.js.map +1 -1
  269. package/dist/lib/generated/Entities/MJTestSuite/mjtestsuite.form.component.js +1 -1
  270. package/dist/lib/generated/Entities/MJTestSuite/mjtestsuite.form.component.js.map +1 -1
  271. package/dist/lib/generated/Entities/MJTestSuiteRun/mjtestsuiterun.form.component.js +4 -4
  272. package/dist/lib/generated/Entities/MJTestSuiteRun/mjtestsuiterun.form.component.js.map +1 -1
  273. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.d.ts.map +1 -1
  274. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js +123 -105
  275. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js.map +1 -1
  276. package/dist/lib/generated/Entities/MJUserNotificationType/mjusernotificationtype.form.component.js +1 -1
  277. package/dist/lib/generated/Entities/MJUserNotificationType/mjusernotificationtype.form.component.js.map +1 -1
  278. package/dist/lib/generated/Entities/MJUserRecordLog/mjuserrecordlog.form.component.js +1 -1
  279. package/dist/lib/generated/Entities/MJUserRecordLog/mjuserrecordlog.form.component.js.map +1 -1
  280. package/dist/lib/generated/Entities/MJUserView/mjuserview.form.component.d.ts.map +1 -1
  281. package/dist/lib/generated/Entities/MJUserView/mjuserview.form.component.js +27 -9
  282. package/dist/lib/generated/Entities/MJUserView/mjuserview.form.component.js.map +1 -1
  283. package/dist/lib/generated/Entities/MJUserViewCategory/mjuserviewcategory.form.component.js +1 -1
  284. package/dist/lib/generated/Entities/MJUserViewCategory/mjuserviewcategory.form.component.js.map +1 -1
  285. package/dist/lib/generated/Entities/MJVectorIndex/mjvectorindex.form.component.js +1 -1
  286. package/dist/lib/generated/Entities/MJVectorIndex/mjvectorindex.form.component.js.map +1 -1
  287. package/dist/lib/generated/Entities/MJVersionInstallation/mjversioninstallation.form.component.js +1 -1
  288. package/dist/lib/generated/Entities/MJVersionInstallation/mjversioninstallation.form.component.js.map +1 -1
  289. package/dist/lib/generated/Entities/MJVersionLabel/mjversionlabel.form.component.js +1 -1
  290. package/dist/lib/generated/Entities/MJVersionLabel/mjversionlabel.form.component.js.map +1 -1
  291. package/dist/lib/generated/Entities/MJWorkspace/mjworkspace.form.component.js +1 -1
  292. package/dist/lib/generated/Entities/MJWorkspace/mjworkspace.form.component.js.map +1 -1
  293. package/dist/lib/generated/Entities/MJWorkspaceItem/mjworkspaceitem.form.component.js +1 -1
  294. package/dist/lib/generated/Entities/MJWorkspaceItem/mjworkspaceitem.form.component.js.map +1 -1
  295. package/package.json +37 -36
@@ -27,9 +27,15 @@ import * as i7 from "@memberjunction/ng-versions";
27
27
  import * as i8 from "./entity-link-pill.component";
28
28
  const _c0 = () => [1, 2, 3, 4, 5];
29
29
  const _c1 = () => [1, 2, 3];
30
- function MJTestFormComponentExtended_Conditional_25_Template(rf, ctx) { if (rf & 1) {
31
- i0.ɵɵelementStart(0, "span", 16);
32
- i0.ɵɵelement(1, "i", 42);
30
+ const _forTrack0 = ($index, $item) => $item.ID;
31
+ function MJTestFormComponentExtended_Conditional_21_Template(rf, ctx) { if (rf & 1) {
32
+ i0.ɵɵelementStart(0, "span", 14);
33
+ i0.ɵɵtext(1, "\u25CF");
34
+ i0.ɵɵelementEnd();
35
+ } }
36
+ function MJTestFormComponentExtended_Conditional_26_Template(rf, ctx) { if (rf & 1) {
37
+ i0.ɵɵelementStart(0, "span", 18);
38
+ i0.ɵɵelement(1, "i", 54);
33
39
  i0.ɵɵtext(2);
34
40
  i0.ɵɵelementEnd();
35
41
  } if (rf & 2) {
@@ -37,8 +43,14 @@ function MJTestFormComponentExtended_Conditional_25_Template(rf, ctx) { if (rf &
37
43
  i0.ɵɵadvance(2);
38
44
  i0.ɵɵtextInterpolate1(" ", ctx_r0.record.Type, " ");
39
45
  } }
40
- function MJTestFormComponentExtended_Conditional_34_Template(rf, ctx) { if (rf & 1) {
41
- i0.ɵɵelementStart(0, "div", 21)(1, "p");
46
+ function MJTestFormComponentExtended_Conditional_27_Template(rf, ctx) { if (rf & 1) {
47
+ i0.ɵɵelementStart(0, "span", 19);
48
+ i0.ɵɵelement(1, "i", 55);
49
+ i0.ɵɵtext(2, " Unsaved ");
50
+ i0.ɵɵelementEnd();
51
+ } }
52
+ function MJTestFormComponentExtended_Conditional_36_Template(rf, ctx) { if (rf & 1) {
53
+ i0.ɵɵelementStart(0, "div", 24)(1, "p");
42
54
  i0.ɵɵtext(2);
43
55
  i0.ɵɵelementEnd()();
44
56
  } if (rf & 2) {
@@ -46,32 +58,32 @@ function MJTestFormComponentExtended_Conditional_34_Template(rf, ctx) { if (rf &
46
58
  i0.ɵɵadvance(2);
47
59
  i0.ɵɵtextInterpolate(ctx_r0.record.Description);
48
60
  } }
49
- function MJTestFormComponentExtended_Conditional_35_Template(rf, ctx) { if (rf & 1) {
50
- i0.ɵɵelementStart(0, "div", 22)(1, "div", 43)(2, "div", 44);
61
+ function MJTestFormComponentExtended_Conditional_37_Template(rf, ctx) { if (rf & 1) {
62
+ i0.ɵɵelementStart(0, "div", 25)(1, "div", 56)(2, "div", 57);
51
63
  i0.ɵɵtext(3, "Total Runs");
52
64
  i0.ɵɵelementEnd();
53
- i0.ɵɵelementStart(4, "div", 45);
65
+ i0.ɵɵelementStart(4, "div", 58);
54
66
  i0.ɵɵtext(5);
55
67
  i0.ɵɵelementEnd()();
56
- i0.ɵɵelementStart(6, "div", 43)(7, "div", 44);
68
+ i0.ɵɵelementStart(6, "div", 56)(7, "div", 57);
57
69
  i0.ɵɵtext(8, "Pass Rate");
58
70
  i0.ɵɵelementEnd();
59
- i0.ɵɵelementStart(9, "div", 45);
71
+ i0.ɵɵelementStart(9, "div", 58);
60
72
  i0.ɵɵtext(10);
61
73
  i0.ɵɵelementEnd();
62
- i0.ɵɵelementStart(11, "div", 46);
63
- i0.ɵɵelement(12, "div", 47);
74
+ i0.ɵɵelementStart(11, "div", 59);
75
+ i0.ɵɵelement(12, "div", 60);
64
76
  i0.ɵɵelementEnd()();
65
- i0.ɵɵelementStart(13, "div", 43)(14, "div", 44);
77
+ i0.ɵɵelementStart(13, "div", 56)(14, "div", 57);
66
78
  i0.ɵɵtext(15, "Avg Cost");
67
79
  i0.ɵɵelementEnd();
68
- i0.ɵɵelementStart(16, "div", 45);
80
+ i0.ɵɵelementStart(16, "div", 58);
69
81
  i0.ɵɵtext(17);
70
82
  i0.ɵɵelementEnd()();
71
- i0.ɵɵelementStart(18, "div", 43)(19, "div", 44);
83
+ i0.ɵɵelementStart(18, "div", 56)(19, "div", 57);
72
84
  i0.ɵɵtext(20, "Avg Duration");
73
85
  i0.ɵɵelementEnd();
74
- i0.ɵɵelementStart(21, "div", 45);
86
+ i0.ɵɵelementStart(21, "div", 58);
75
87
  i0.ɵɵtext(22);
76
88
  i0.ɵɵelementEnd()()();
77
89
  } if (rf & 2) {
@@ -87,8 +99,8 @@ function MJTestFormComponentExtended_Conditional_35_Template(rf, ctx) { if (rf &
87
99
  i0.ɵɵadvance(5);
88
100
  i0.ɵɵtextInterpolate(ctx_r0.formatDuration(ctx_r0.getAverageDuration()));
89
101
  } }
90
- function MJTestFormComponentExtended_Conditional_50_Template(rf, ctx) { if (rf & 1) {
91
- i0.ɵɵelementStart(0, "span", 29);
102
+ function MJTestFormComponentExtended_Conditional_52_Template(rf, ctx) { if (rf & 1) {
103
+ i0.ɵɵelementStart(0, "span", 32);
92
104
  i0.ɵɵtext(1);
93
105
  i0.ɵɵelementEnd();
94
106
  } if (rf & 2) {
@@ -96,8 +108,8 @@ function MJTestFormComponentExtended_Conditional_50_Template(rf, ctx) { if (rf &
96
108
  i0.ɵɵadvance();
97
109
  i0.ɵɵtextInterpolate(ctx_r0.testRuns.length);
98
110
  } }
99
- function MJTestFormComponentExtended_Conditional_55_Template(rf, ctx) { if (rf & 1) {
100
- i0.ɵɵelementStart(0, "span", 29);
111
+ function MJTestFormComponentExtended_Conditional_57_Template(rf, ctx) { if (rf & 1) {
112
+ i0.ɵɵelementStart(0, "span", 32);
101
113
  i0.ɵɵtext(1);
102
114
  i0.ɵɵelementEnd();
103
115
  } if (rf & 2) {
@@ -105,100 +117,100 @@ function MJTestFormComponentExtended_Conditional_55_Template(rf, ctx) { if (rf &
105
117
  i0.ɵɵadvance();
106
118
  i0.ɵɵtextInterpolate(ctx_r0.suiteTests.length);
107
119
  } }
108
- function MJTestFormComponentExtended_Conditional_61_Template(rf, ctx) { if (rf & 1) {
120
+ function MJTestFormComponentExtended_Conditional_63_Template(rf, ctx) { if (rf & 1) {
109
121
  const _r2 = i0.ɵɵgetCurrentView();
110
- i0.ɵɵelementStart(0, "div", 33)(1, "div", 48)(2, "h3");
111
- i0.ɵɵelement(3, "i", 49);
122
+ i0.ɵɵelementStart(0, "div", 36)(1, "div", 61)(2, "h3");
123
+ i0.ɵɵelement(3, "i", 62);
112
124
  i0.ɵɵtext(4, " Test Information");
113
125
  i0.ɵɵelementEnd();
114
- i0.ɵɵelementStart(5, "div", 50)(6, "div", 51)(7, "div", 52);
126
+ i0.ɵɵelementStart(5, "div", 63)(6, "div", 64)(7, "div", 65);
115
127
  i0.ɵɵtext(8, "Name");
116
128
  i0.ɵɵelementEnd();
117
- i0.ɵɵelementStart(9, "div", 53);
129
+ i0.ɵɵelementStart(9, "div", 66);
118
130
  i0.ɵɵtext(10);
119
131
  i0.ɵɵelementEnd()();
120
- i0.ɵɵelementStart(11, "div", 51)(12, "div", 52);
132
+ i0.ɵɵelementStart(11, "div", 64)(12, "div", 65);
121
133
  i0.ɵɵtext(13, "Type");
122
134
  i0.ɵɵelementEnd();
123
- i0.ɵɵelementStart(14, "div", 53);
135
+ i0.ɵɵelementStart(14, "div", 66);
124
136
  i0.ɵɵtext(15);
125
137
  i0.ɵɵelementEnd()();
126
- i0.ɵɵelementStart(16, "div", 51)(17, "div", 52);
138
+ i0.ɵɵelementStart(16, "div", 64)(17, "div", 65);
127
139
  i0.ɵɵtext(18, "Status");
128
140
  i0.ɵɵelementEnd();
129
- i0.ɵɵelementStart(19, "div", 53)(20, "span", 54);
141
+ i0.ɵɵelementStart(19, "div", 66)(20, "span", 67);
130
142
  i0.ɵɵtext(21);
131
143
  i0.ɵɵelementEnd()()();
132
- i0.ɵɵelementStart(22, "div", 51)(23, "div", 52);
144
+ i0.ɵɵelementStart(22, "div", 64)(23, "div", 65);
133
145
  i0.ɵɵtext(24, "Priority");
134
146
  i0.ɵɵelementEnd();
135
- i0.ɵɵelementStart(25, "div", 53);
147
+ i0.ɵɵelementStart(25, "div", 66);
136
148
  i0.ɵɵtext(26);
137
149
  i0.ɵɵelementEnd()();
138
- i0.ɵɵelementStart(27, "div", 51)(28, "div", 52);
150
+ i0.ɵɵelementStart(27, "div", 64)(28, "div", 65);
139
151
  i0.ɵɵtext(29, "Estimated Duration");
140
152
  i0.ɵɵelementEnd();
141
- i0.ɵɵelementStart(30, "div", 53);
153
+ i0.ɵɵelementStart(30, "div", 66);
142
154
  i0.ɵɵtext(31);
143
155
  i0.ɵɵelementEnd()();
144
- i0.ɵɵelementStart(32, "div", 51)(33, "div", 52);
156
+ i0.ɵɵelementStart(32, "div", 64)(33, "div", 65);
145
157
  i0.ɵɵtext(34, "Estimated Cost");
146
158
  i0.ɵɵelementEnd();
147
- i0.ɵɵelementStart(35, "div", 53);
159
+ i0.ɵɵelementStart(35, "div", 66);
148
160
  i0.ɵɵtext(36);
149
161
  i0.ɵɵelementEnd()();
150
- i0.ɵɵelementStart(37, "div", 51)(38, "div", 52);
162
+ i0.ɵɵelementStart(37, "div", 64)(38, "div", 65);
151
163
  i0.ɵɵtext(39, "Repeat Count");
152
164
  i0.ɵɵelementEnd();
153
- i0.ɵɵelementStart(40, "div", 53);
165
+ i0.ɵɵelementStart(40, "div", 66);
154
166
  i0.ɵɵtext(41);
155
167
  i0.ɵɵelementEnd()();
156
- i0.ɵɵelementStart(42, "div", 51)(43, "div", 52);
168
+ i0.ɵɵelementStart(42, "div", 64)(43, "div", 65);
157
169
  i0.ɵɵtext(44, "Max Execution Time");
158
170
  i0.ɵɵelementEnd();
159
- i0.ɵɵelementStart(45, "div", 53);
171
+ i0.ɵɵelementStart(45, "div", 66);
160
172
  i0.ɵɵtext(46);
161
173
  i0.ɵɵelementEnd()();
162
- i0.ɵɵelementStart(47, "div", 51)(48, "div", 52);
174
+ i0.ɵɵelementStart(47, "div", 64)(48, "div", 65);
163
175
  i0.ɵɵtext(49, "Created");
164
176
  i0.ɵɵelementEnd();
165
- i0.ɵɵelementStart(50, "div", 53);
177
+ i0.ɵɵelementStart(50, "div", 66);
166
178
  i0.ɵɵtext(51);
167
179
  i0.ɵɵpipe(52, "date");
168
180
  i0.ɵɵelementEnd()();
169
- i0.ɵɵelementStart(53, "div", 51)(54, "div", 52);
181
+ i0.ɵɵelementStart(53, "div", 64)(54, "div", 65);
170
182
  i0.ɵɵtext(55, "Updated");
171
183
  i0.ɵɵelementEnd();
172
- i0.ɵɵelementStart(56, "div", 53);
184
+ i0.ɵɵelementStart(56, "div", 66);
173
185
  i0.ɵɵtext(57);
174
186
  i0.ɵɵpipe(58, "date");
175
187
  i0.ɵɵelementEnd()()()();
176
- i0.ɵɵelementStart(59, "div", 55)(60, "h3");
177
- i0.ɵɵelement(61, "i", 56);
188
+ i0.ɵɵelementStart(59, "div", 68)(60, "h3");
189
+ i0.ɵɵelement(61, "i", 69);
178
190
  i0.ɵɵtext(62, " Test Definition");
179
191
  i0.ɵɵelementEnd();
180
- i0.ɵɵelementStart(63, "div", 57)(64, "button", 58);
181
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_61_Template_button_click_64_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.setJsonView("input")); });
182
- i0.ɵɵelement(65, "i", 59);
192
+ i0.ɵɵelementStart(63, "div", 70)(64, "button", 71);
193
+ 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")); });
194
+ i0.ɵɵelement(65, "i", 72);
183
195
  i0.ɵɵtext(66, " Input Definition ");
184
196
  i0.ɵɵelementEnd();
185
- i0.ɵɵelementStart(67, "button", 58);
186
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_61_Template_button_click_67_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.setJsonView("expected")); });
187
- i0.ɵɵelement(68, "i", 60);
197
+ i0.ɵɵelementStart(67, "button", 71);
198
+ 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")); });
199
+ i0.ɵɵelement(68, "i", 73);
188
200
  i0.ɵɵtext(69, " Expected Outcomes ");
189
201
  i0.ɵɵelementEnd();
190
- i0.ɵɵelementStart(70, "button", 58);
191
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_61_Template_button_click_70_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.setJsonView("config")); });
192
- i0.ɵɵelement(71, "i", 61);
202
+ i0.ɵɵelementStart(70, "button", 71);
203
+ 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")); });
204
+ i0.ɵɵelement(71, "i", 74);
193
205
  i0.ɵɵtext(72, " Configuration ");
194
206
  i0.ɵɵelementEnd();
195
- i0.ɵɵelementStart(73, "button", 58);
196
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_61_Template_button_click_73_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.setJsonView("tags")); });
197
- i0.ɵɵelement(74, "i", 62);
207
+ i0.ɵɵelementStart(73, "button", 71);
208
+ 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")); });
209
+ i0.ɵɵelement(74, "i", 75);
198
210
  i0.ɵɵtext(75, " Tags ");
199
211
  i0.ɵɵelementEnd()();
200
- i0.ɵɵelementStart(76, "div", 63);
201
- i0.ɵɵelement(77, "mj-code-editor", 64);
212
+ i0.ɵɵelementStart(76, "div", 76);
213
+ i0.ɵɵelement(77, "mj-code-editor", 77);
202
214
  i0.ɵɵelementEnd()()();
203
215
  } if (rf & 2) {
204
216
  const ctx_r0 = i0.ɵɵnextContext();
@@ -235,295 +247,420 @@ function MJTestFormComponentExtended_Conditional_61_Template(rf, ctx) { if (rf &
235
247
  i0.ɵɵadvance(4);
236
248
  i0.ɵɵproperty("value", ctx_r0.getJsonData())("readonly", true)("toolbar", ctx_r0.jsonToolbar)("lineWrapping", true);
237
249
  } }
238
- function MJTestFormComponentExtended_Conditional_62_Template(rf, ctx) { if (rf & 1) {
250
+ function MJTestFormComponentExtended_Conditional_64_For_25_Template(rf, ctx) { if (rf & 1) {
251
+ i0.ɵɵelementStart(0, "option", 93);
252
+ i0.ɵɵtext(1);
253
+ i0.ɵɵelementEnd();
254
+ } if (rf & 2) {
255
+ const opt_r4 = ctx.$implicit;
256
+ i0.ɵɵproperty("ngValue", opt_r4);
257
+ i0.ɵɵadvance();
258
+ i0.ɵɵtextInterpolate(opt_r4);
259
+ } }
260
+ function MJTestFormComponentExtended_Conditional_64_For_31_Template(rf, ctx) { if (rf & 1) {
261
+ i0.ɵɵelementStart(0, "option", 93);
262
+ i0.ɵɵtext(1);
263
+ i0.ɵɵelementEnd();
264
+ } if (rf & 2) {
265
+ const t_r5 = ctx.$implicit;
266
+ i0.ɵɵproperty("ngValue", t_r5.ID);
267
+ i0.ɵɵadvance();
268
+ i0.ɵɵtextInterpolate(t_r5.Name);
269
+ } }
270
+ function MJTestFormComponentExtended_Conditional_64_For_37_Template(rf, ctx) { if (rf & 1) {
271
+ const _r7 = i0.ɵɵgetCurrentView();
272
+ i0.ɵɵelementStart(0, "span", 98);
273
+ i0.ɵɵtext(1);
274
+ i0.ɵɵelementStart(2, "button", 121);
275
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_64_For_37_Template_button_click_2_listener($event) { const tag_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r0 = i0.ɵɵnextContext(2); ctx_r0.removeTag(tag_r8); return i0.ɵɵresetView($event.stopPropagation()); });
276
+ i0.ɵɵelement(3, "i", 122);
277
+ i0.ɵɵelementEnd()();
278
+ } if (rf & 2) {
279
+ const tag_r8 = ctx.$implicit;
280
+ i0.ɵɵadvance();
281
+ i0.ɵɵtextInterpolate1(" ", tag_r8, " ");
282
+ i0.ɵɵadvance();
283
+ i0.ɵɵattribute("aria-label", "Remove tag " + tag_r8);
284
+ } }
285
+ function MJTestFormComponentExtended_Conditional_64_Template(rf, ctx) { if (rf & 1) {
239
286
  const _r3 = i0.ɵɵgetCurrentView();
240
- i0.ɵɵelementStart(0, "div", 34)(1, "div", 65)(2, "h3");
241
- i0.ɵɵelement(3, "i", 66);
242
- i0.ɵɵtext(4, " Execution Settings");
287
+ i0.ɵɵelementStart(0, "div", 37)(1, "section", 78)(2, "header", 79)(3, "h3");
288
+ i0.ɵɵelement(4, "i", 80);
289
+ i0.ɵɵtext(5, " Details");
243
290
  i0.ɵɵelementEnd();
244
- i0.ɵɵelementStart(5, "div", 67)(6, "div", 68)(7, "label");
245
- i0.ɵɵtext(8, "Priority");
291
+ i0.ɵɵelementStart(6, "p", 81);
292
+ i0.ɵɵtext(7, "Edit any field \u2014 changes are saved with the bar at the bottom.");
293
+ i0.ɵɵelementEnd()();
294
+ i0.ɵɵelementStart(8, "div", 82)(9, "div", 83)(10, "label", 84);
295
+ i0.ɵɵtext(11, "Name ");
296
+ i0.ɵɵelementStart(12, "span", 85);
297
+ i0.ɵɵtext(13, "*");
298
+ i0.ɵɵelementEnd()();
299
+ i0.ɵɵelementStart(14, "input", 86);
300
+ 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); });
301
+ i0.ɵɵelementEnd()();
302
+ i0.ɵɵelementStart(15, "div", 83)(16, "label", 87);
303
+ i0.ɵɵtext(17, "Description");
246
304
  i0.ɵɵelementEnd();
247
- i0.ɵɵelementStart(9, "input", 69);
248
- i0.ɵɵtwoWayListener("ngModelChange", function MJTestFormComponentExtended_Conditional_62_Template_input_ngModelChange_9_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.record.Priority, $event) || (ctx_r0.record.Priority = $event); return i0.ɵɵresetView($event); });
305
+ i0.ɵɵelementStart(18, "textarea", 88);
306
+ 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); });
249
307
  i0.ɵɵelementEnd()();
250
- i0.ɵɵelementStart(10, "div", 68)(11, "label");
251
- i0.ɵɵtext(12, "Repeat Count");
308
+ i0.ɵɵelementStart(19, "div", 89)(20, "label", 90);
309
+ i0.ɵɵtext(21, "Status");
310
+ i0.ɵɵelementEnd();
311
+ i0.ɵɵelementStart(22, "div", 91)(23, "select", 92);
312
+ 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); });
313
+ i0.ɵɵrepeaterCreate(24, MJTestFormComponentExtended_Conditional_64_For_25_Template, 2, 2, "option", 93, i0.ɵɵrepeaterTrackByIdentity);
314
+ i0.ɵɵelementEnd()()();
315
+ i0.ɵɵelementStart(26, "div", 89)(27, "label", 94);
316
+ i0.ɵɵtext(28, "Test Type");
252
317
  i0.ɵɵelementEnd();
253
- i0.ɵɵelementStart(13, "input", 70);
254
- i0.ɵɵtwoWayListener("ngModelChange", function MJTestFormComponentExtended_Conditional_62_Template_input_ngModelChange_13_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.record.RepeatCount, $event) || (ctx_r0.record.RepeatCount = $event); return i0.ɵɵresetView($event); });
318
+ i0.ɵɵelementStart(29, "select", 95);
319
+ i0.ɵɵtwoWayListener("ngModelChange", function MJTestFormComponentExtended_Conditional_64_Template_select_ngModelChange_29_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); });
320
+ i0.ɵɵrepeaterCreate(30, MJTestFormComponentExtended_Conditional_64_For_31_Template, 2, 2, "option", 93, _forTrack0);
255
321
  i0.ɵɵelementEnd()();
256
- i0.ɵɵelementStart(14, "div", 68)(15, "label");
257
- i0.ɵɵtext(16, "Estimated Duration (seconds)");
322
+ i0.ɵɵelementStart(32, "div", 83)(33, "label", 96);
323
+ i0.ɵɵtext(34, "Tags");
324
+ i0.ɵɵelementEnd();
325
+ i0.ɵɵelementStart(35, "div", 97);
326
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_64_Template_div_click_35_listener() { i0.ɵɵrestoreView(_r3); const tagInput_r6 = i0.ɵɵreference(39); return i0.ɵɵresetView(tagInput_r6.focus()); });
327
+ i0.ɵɵrepeaterCreate(36, MJTestFormComponentExtended_Conditional_64_For_37_Template, 4, 2, "span", 98, i0.ɵɵrepeaterTrackByIdentity);
328
+ i0.ɵɵelementStart(38, "input", 99, 0);
329
+ i0.ɵɵtwoWayListener("ngModelChange", function MJTestFormComponentExtended_Conditional_64_Template_input_ngModelChange_38_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.tagDraft, $event) || (ctx_r0.tagDraft = $event); return i0.ɵɵresetView($event); });
330
+ i0.ɵɵlistener("keydown", function MJTestFormComponentExtended_Conditional_64_Template_input_keydown_38_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_38_listener() { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.addTagFromDraft()); });
331
+ i0.ɵɵelementEnd()();
332
+ i0.ɵɵelementStart(40, "span", 100);
333
+ i0.ɵɵtext(41, "Press Enter or comma to add a tag. Backspace on empty input removes the last tag.");
334
+ i0.ɵɵelementEnd()()()();
335
+ i0.ɵɵelementStart(42, "section", 78)(43, "header", 79)(44, "h3");
336
+ i0.ɵɵelement(45, "i", 101);
337
+ i0.ɵɵtext(46, " Execution Settings");
338
+ i0.ɵɵelementEnd()();
339
+ i0.ɵɵelementStart(47, "div", 82)(48, "div", 89)(49, "label", 102);
340
+ i0.ɵɵtext(50, "Priority");
341
+ i0.ɵɵelementEnd();
342
+ i0.ɵɵelementStart(51, "input", 103);
343
+ i0.ɵɵlistener("ngModelChange", function MJTestFormComponentExtended_Conditional_64_Template_input_ngModelChange_51_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.Priority = $event === "" || $event === null ? null : +$event); });
258
344
  i0.ɵɵelementEnd();
259
- i0.ɵɵelementStart(17, "input", 71);
260
- i0.ɵɵtwoWayListener("ngModelChange", function MJTestFormComponentExtended_Conditional_62_Template_input_ngModelChange_17_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.record.EstimatedDurationSeconds, $event) || (ctx_r0.record.EstimatedDurationSeconds = $event); return i0.ɵɵresetView($event); });
345
+ i0.ɵɵelementStart(52, "span", 100);
346
+ i0.ɵɵtext(53, "Lower numbers run first.");
261
347
  i0.ɵɵelementEnd()();
262
- i0.ɵɵelementStart(18, "div", 68)(19, "label");
263
- i0.ɵɵtext(20, "Estimated Cost (USD)");
348
+ i0.ɵɵelementStart(54, "div", 89)(55, "label", 104);
349
+ i0.ɵɵtext(56, "Repeat Count");
350
+ i0.ɵɵelementEnd();
351
+ i0.ɵɵelementStart(57, "input", 105);
352
+ i0.ɵɵlistener("ngModelChange", function MJTestFormComponentExtended_Conditional_64_Template_input_ngModelChange_57_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.RepeatCount = $event === "" || $event === null ? null : +$event); });
264
353
  i0.ɵɵelementEnd();
265
- i0.ɵɵelementStart(21, "input", 72);
266
- i0.ɵɵtwoWayListener("ngModelChange", function MJTestFormComponentExtended_Conditional_62_Template_input_ngModelChange_21_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.record.EstimatedCostUSD, $event) || (ctx_r0.record.EstimatedCostUSD = $event); return i0.ɵɵresetView($event); });
354
+ i0.ɵɵelementStart(58, "span", 100);
355
+ i0.ɵɵtext(59, "Number of times to repeat for statistical analysis.");
267
356
  i0.ɵɵelementEnd()();
268
- i0.ɵɵelementStart(22, "div", 73)(23, "label");
269
- i0.ɵɵtext(24, "Max Execution Time (ms)");
357
+ i0.ɵɵelementStart(60, "div", 89)(61, "label", 106);
358
+ i0.ɵɵtext(62, "Estimated Duration (seconds)");
270
359
  i0.ɵɵelementEnd();
271
- i0.ɵɵelementStart(25, "input", 74);
272
- i0.ɵɵtwoWayListener("ngModelChange", function MJTestFormComponentExtended_Conditional_62_Template_input_ngModelChange_25_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.record.MaxExecutionTimeMS, $event) || (ctx_r0.record.MaxExecutionTimeMS = $event); return i0.ɵɵresetView($event); });
360
+ i0.ɵɵelementStart(63, "input", 107);
361
+ i0.ɵɵlistener("ngModelChange", function MJTestFormComponentExtended_Conditional_64_Template_input_ngModelChange_63_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.EstimatedDurationSeconds = $event === "" || $event === null ? null : +$event); });
362
+ i0.ɵɵelementEnd()();
363
+ i0.ɵɵelementStart(64, "div", 89)(65, "label", 108);
364
+ i0.ɵɵtext(66, "Estimated Cost (USD)");
273
365
  i0.ɵɵelementEnd();
274
- i0.ɵɵelementStart(26, "span", 75);
275
- i0.ɵɵtext(27, "Leave empty for default 5 minute timeout");
366
+ i0.ɵɵelementStart(67, "input", 109);
367
+ i0.ɵɵlistener("ngModelChange", function MJTestFormComponentExtended_Conditional_64_Template_input_ngModelChange_67_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.EstimatedCostUSD = $event === "" || $event === null ? null : +$event); });
368
+ i0.ɵɵelementEnd()();
369
+ i0.ɵɵelementStart(68, "div", 83)(69, "label", 110);
370
+ i0.ɵɵtext(70, "Max Execution Time (ms)");
371
+ i0.ɵɵelementEnd();
372
+ i0.ɵɵelementStart(71, "input", 111);
373
+ 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.MaxExecutionTimeMS = $event === "" || $event === null ? null : +$event); });
374
+ i0.ɵɵelementEnd();
375
+ i0.ɵɵelementStart(72, "span", 100);
376
+ i0.ɵɵtext(73);
276
377
  i0.ɵɵelementEnd()()()();
277
- i0.ɵɵelementStart(28, "div", 65)(29, "h3");
278
- i0.ɵɵelement(30, "i", 59);
279
- i0.ɵɵtext(31, " Input Definition (JSON)");
378
+ i0.ɵɵelementStart(74, "div", 112)(75, "h3");
379
+ i0.ɵɵelement(76, "i", 72);
380
+ i0.ɵɵtext(77, " Input Definition (JSON)");
280
381
  i0.ɵɵelementEnd();
281
- i0.ɵɵelementStart(32, "div", 76)(33, "mj-code-editor", 77);
282
- i0.ɵɵlistener("change", function MJTestFormComponentExtended_Conditional_62_Template_mj_code_editor_change_33_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.InputDefinition = $event); });
382
+ i0.ɵɵelementStart(78, "div", 113)(79, "mj-code-editor", 114);
383
+ i0.ɵɵlistener("change", function MJTestFormComponentExtended_Conditional_64_Template_mj_code_editor_change_79_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.InputDefinition = $event); });
283
384
  i0.ɵɵelementEnd()()();
284
- i0.ɵɵelementStart(34, "div", 65)(35, "h3");
285
- i0.ɵɵelement(36, "i", 60);
286
- i0.ɵɵtext(37, " Expected Outcomes (JSON)");
385
+ i0.ɵɵelementStart(80, "div", 112)(81, "h3");
386
+ i0.ɵɵelement(82, "i", 73);
387
+ i0.ɵɵtext(83, " Expected Outcomes (JSON)");
287
388
  i0.ɵɵelementEnd();
288
- i0.ɵɵelementStart(38, "div", 76)(39, "mj-code-editor", 77);
289
- i0.ɵɵlistener("change", function MJTestFormComponentExtended_Conditional_62_Template_mj_code_editor_change_39_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.ExpectedOutcomes = $event); });
389
+ i0.ɵɵelementStart(84, "div", 113)(85, "mj-code-editor", 114);
390
+ i0.ɵɵlistener("change", function MJTestFormComponentExtended_Conditional_64_Template_mj_code_editor_change_85_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.ExpectedOutcomes = $event); });
290
391
  i0.ɵɵelementEnd()()();
291
- i0.ɵɵelementStart(40, "div", 65)(41, "h3");
292
- i0.ɵɵelement(42, "i", 61);
293
- i0.ɵɵtext(43, " Configuration (JSON)");
392
+ i0.ɵɵelementStart(86, "div", 112)(87, "h3");
393
+ i0.ɵɵelement(88, "i", 74);
394
+ i0.ɵɵtext(89, " Configuration (JSON)");
294
395
  i0.ɵɵelementEnd();
295
- i0.ɵɵelementStart(44, "div", 76)(45, "mj-code-editor", 77);
296
- i0.ɵɵlistener("change", function MJTestFormComponentExtended_Conditional_62_Template_mj_code_editor_change_45_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.Configuration = $event); });
396
+ i0.ɵɵelementStart(90, "div", 113)(91, "mj-code-editor", 114);
397
+ i0.ɵɵlistener("change", function MJTestFormComponentExtended_Conditional_64_Template_mj_code_editor_change_91_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.Configuration = $event); });
297
398
  i0.ɵɵelementEnd()()();
298
- i0.ɵɵelementStart(46, "div", 65)(47, "h3");
299
- i0.ɵɵelement(48, "i", 62);
300
- i0.ɵɵtext(49, " Tags (JSON Array)");
399
+ i0.ɵɵelementStart(92, "section", 115)(93, "div", 116)(94, "div", 117)(95, "div", 118);
400
+ i0.ɵɵtext(96, "Created");
301
401
  i0.ɵɵelementEnd();
302
- i0.ɵɵelementStart(50, "div", 78)(51, "mj-code-editor", 77);
303
- i0.ɵɵlistener("change", function MJTestFormComponentExtended_Conditional_62_Template_mj_code_editor_change_51_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.Tags = $event); });
304
- i0.ɵɵelementEnd()()()();
402
+ i0.ɵɵelementStart(97, "div", 119);
403
+ i0.ɵɵtext(98);
404
+ i0.ɵɵpipe(99, "date");
405
+ i0.ɵɵelementEnd()();
406
+ i0.ɵɵelementStart(100, "div", 117)(101, "div", 118);
407
+ i0.ɵɵtext(102, "Last updated");
408
+ i0.ɵɵelementEnd();
409
+ i0.ɵɵelementStart(103, "div", 119);
410
+ i0.ɵɵtext(104);
411
+ i0.ɵɵpipe(105, "date");
412
+ i0.ɵɵelementEnd()();
413
+ i0.ɵɵelementStart(106, "div", 117)(107, "div", 118);
414
+ i0.ɵɵtext(108, "Test ID");
415
+ i0.ɵɵelementEnd();
416
+ i0.ɵɵelementStart(109, "div", 120);
417
+ i0.ɵɵtext(110);
418
+ i0.ɵɵelementEnd()()()()();
305
419
  } if (rf & 2) {
306
420
  const ctx_r0 = i0.ɵɵnextContext();
307
- i0.ɵɵadvance(9);
308
- i0.ɵɵtwoWayProperty("ngModel", ctx_r0.record.Priority);
309
- i0.ɵɵadvance(4);
310
- i0.ɵɵtwoWayProperty("ngModel", ctx_r0.record.RepeatCount);
421
+ i0.ɵɵadvance(14);
422
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r0.record.Name);
311
423
  i0.ɵɵadvance(4);
312
- i0.ɵɵtwoWayProperty("ngModel", ctx_r0.record.EstimatedDurationSeconds);
424
+ i0.ɵɵproperty("ngModel", ctx_r0.record.Description);
425
+ i0.ɵɵadvance(5);
426
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r0.record.Status);
427
+ i0.ɵɵadvance();
428
+ i0.ɵɵrepeater(ctx_r0.statusOptions);
429
+ i0.ɵɵadvance(5);
430
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r0.record.TypeID);
431
+ i0.ɵɵadvance();
432
+ i0.ɵɵrepeater(ctx_r0.testTypeOptions);
433
+ i0.ɵɵadvance(6);
434
+ i0.ɵɵrepeater(ctx_r0.tags);
435
+ i0.ɵɵadvance(2);
436
+ i0.ɵɵproperty("placeholder", ctx_r0.tags.length === 0 ? "Add tags, press Enter or comma..." : "");
437
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r0.tagDraft);
438
+ i0.ɵɵadvance(13);
439
+ i0.ɵɵproperty("ngModel", ctx_r0.record.Priority);
440
+ i0.ɵɵadvance(6);
441
+ i0.ɵɵproperty("ngModel", ctx_r0.record.RepeatCount);
442
+ i0.ɵɵadvance(6);
443
+ i0.ɵɵproperty("ngModel", ctx_r0.record.EstimatedDurationSeconds);
313
444
  i0.ɵɵadvance(4);
314
- i0.ɵɵtwoWayProperty("ngModel", ctx_r0.record.EstimatedCostUSD);
445
+ i0.ɵɵproperty("ngModel", ctx_r0.record.EstimatedCostUSD);
315
446
  i0.ɵɵadvance(4);
316
- i0.ɵɵtwoWayProperty("ngModel", ctx_r0.record.MaxExecutionTimeMS);
317
- i0.ɵɵadvance(8);
447
+ i0.ɵɵproperty("ngModel", ctx_r0.record.MaxExecutionTimeMS);
448
+ i0.ɵɵadvance(2);
449
+ i0.ɵɵtextInterpolate1("Leave empty for the default 5 minute timeout. Currently: ", ctx_r0.formatTimeout(ctx_r0.record.MaxExecutionTimeMS));
450
+ i0.ɵɵadvance(6);
318
451
  i0.ɵɵproperty("value", ctx_r0.record.InputDefinition || "")("readonly", false)("lineWrapping", true);
319
452
  i0.ɵɵadvance(6);
320
453
  i0.ɵɵproperty("value", ctx_r0.record.ExpectedOutcomes || "")("readonly", false)("lineWrapping", true);
321
454
  i0.ɵɵadvance(6);
322
455
  i0.ɵɵproperty("value", ctx_r0.record.Configuration || "")("readonly", false)("lineWrapping", true);
456
+ i0.ɵɵadvance(7);
457
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(99, 24, ctx_r0.record.__mj_CreatedAt, "medium"));
323
458
  i0.ɵɵadvance(6);
324
- i0.ɵɵproperty("value", ctx_r0.record.Tags || "[]")("readonly", false)("lineWrapping", true);
459
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(105, 27, ctx_r0.record.__mj_UpdatedAt, "medium"));
460
+ i0.ɵɵadvance(6);
461
+ i0.ɵɵtextInterpolate(ctx_r0.record.ID);
325
462
  } }
326
- function MJTestFormComponentExtended_Conditional_63_Conditional_1_For_3_Template(rf, ctx) { if (rf & 1) {
327
- i0.ɵɵelementStart(0, "div", 83);
328
- i0.ɵɵelement(1, "div", 84);
329
- i0.ɵɵelementStart(2, "div", 85);
330
- i0.ɵɵelement(3, "div", 86)(4, "div", 87);
463
+ function MJTestFormComponentExtended_Conditional_65_Conditional_1_For_3_Template(rf, ctx) { if (rf & 1) {
464
+ i0.ɵɵelementStart(0, "div", 127);
465
+ i0.ɵɵelement(1, "div", 128);
466
+ i0.ɵɵelementStart(2, "div", 129);
467
+ i0.ɵɵelement(3, "div", 130)(4, "div", 131);
331
468
  i0.ɵɵelementEnd()();
332
469
  } }
333
- function MJTestFormComponentExtended_Conditional_63_Conditional_1_Template(rf, ctx) { if (rf & 1) {
334
- i0.ɵɵelementStart(0, "div", 79)(1, "div", 82);
335
- i0.ɵɵrepeaterCreate(2, MJTestFormComponentExtended_Conditional_63_Conditional_1_For_3_Template, 5, 0, "div", 83, i0.ɵɵrepeaterTrackByIdentity);
470
+ function MJTestFormComponentExtended_Conditional_65_Conditional_1_Template(rf, ctx) { if (rf & 1) {
471
+ i0.ɵɵelementStart(0, "div", 123)(1, "div", 126);
472
+ i0.ɵɵrepeaterCreate(2, MJTestFormComponentExtended_Conditional_65_Conditional_1_For_3_Template, 5, 0, "div", 127, i0.ɵɵrepeaterTrackByIdentity);
336
473
  i0.ɵɵelementEnd()();
337
474
  } if (rf & 2) {
338
475
  i0.ɵɵadvance(2);
339
476
  i0.ɵɵrepeater(i0.ɵɵpureFunction0(0, _c0));
340
477
  } }
341
- function MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Conditional_13_Template(rf, ctx) { if (rf & 1) {
478
+ function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_13_Template(rf, ctx) { if (rf & 1) {
342
479
  i0.ɵɵelementStart(0, "span");
343
- i0.ɵɵelement(1, "i", 103);
480
+ i0.ɵɵelement(1, "i", 147);
344
481
  i0.ɵɵtext(2);
345
482
  i0.ɵɵelementEnd();
346
483
  } if (rf & 2) {
347
- const run_r5 = i0.ɵɵnextContext().$implicit;
484
+ const run_r10 = i0.ɵɵnextContext().$implicit;
348
485
  const ctx_r0 = i0.ɵɵnextContext(3);
349
486
  i0.ɵɵadvance(2);
350
- i0.ɵɵtextInterpolate1(" ", ctx_r0.formatDuration(run_r5.DurationSeconds));
487
+ i0.ɵɵtextInterpolate1(" ", ctx_r0.formatDuration(run_r10.DurationSeconds));
351
488
  } }
352
- function MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Conditional_14_Template(rf, ctx) { if (rf & 1) {
489
+ function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_14_Template(rf, ctx) { if (rf & 1) {
353
490
  i0.ɵɵelementStart(0, "span");
354
- i0.ɵɵelement(1, "i", 104);
491
+ i0.ɵɵelement(1, "i", 148);
355
492
  i0.ɵɵtext(2);
356
493
  i0.ɵɵelementEnd();
357
494
  } if (rf & 2) {
358
- const run_r5 = i0.ɵɵnextContext().$implicit;
495
+ const run_r10 = i0.ɵɵnextContext().$implicit;
359
496
  const ctx_r0 = i0.ɵɵnextContext(3);
360
497
  i0.ɵɵadvance(2);
361
- i0.ɵɵtextInterpolate1(" ", ctx_r0.formatCost(run_r5.CostUSD));
498
+ i0.ɵɵtextInterpolate1(" ", ctx_r0.formatCost(run_r10.CostUSD));
362
499
  } }
363
- function MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Conditional_15_Template(rf, ctx) { if (rf & 1) {
364
- i0.ɵɵelement(0, "mj-entity-link-pill", 98);
500
+ function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_15_Template(rf, ctx) { if (rf & 1) {
501
+ i0.ɵɵelement(0, "mj-entity-link-pill", 142);
365
502
  } if (rf & 2) {
366
- const run_r5 = i0.ɵɵnextContext().$implicit;
367
- i0.ɵɵproperty("entityName", run_r5.TargetLogEntity)("recordId", run_r5.TargetLogID);
503
+ const run_r10 = i0.ɵɵnextContext().$implicit;
504
+ i0.ɵɵproperty("entityName", run_r10.TargetLogEntity)("recordId", run_r10.TargetLogID);
368
505
  } }
369
- function MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Conditional_17_Template(rf, ctx) { if (rf & 1) {
370
- i0.ɵɵelementStart(0, "span", 100);
371
- i0.ɵɵelement(1, "i", 91);
506
+ function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_17_Template(rf, ctx) { if (rf & 1) {
507
+ i0.ɵɵelementStart(0, "span", 144);
508
+ i0.ɵɵelement(1, "i", 135);
372
509
  i0.ɵɵelementStart(2, "span");
373
510
  i0.ɵɵtext(3);
374
511
  i0.ɵɵelementEnd()();
375
512
  } if (rf & 2) {
376
- const run_r5 = i0.ɵɵnextContext().$implicit;
513
+ const run_r10 = i0.ɵɵnextContext().$implicit;
377
514
  const ctx_r0 = i0.ɵɵnextContext(3);
378
- i0.ɵɵproperty("ngClass", "status-" + run_r5.Status.toLowerCase())("title", ctx_r0.getStatusTooltip(run_r5.Status));
515
+ i0.ɵɵproperty("ngClass", "status-" + run_r10.Status.toLowerCase())("title", ctx_r0.getStatusTooltip(run_r10.Status));
379
516
  i0.ɵɵadvance();
380
- i0.ɵɵclassProp("fa-check", run_r5.Status === "Passed")("fa-times", run_r5.Status === "Failed")("fa-exclamation", run_r5.Status === "Error")("fa-hourglass-end", run_r5.Status === "Timeout")("fa-forward", run_r5.Status === "Skipped")("fa-spinner", run_r5.Status === "Running")("fa-clock", run_r5.Status === "Pending");
517
+ i0.ɵɵclassProp("fa-check", run_r10.Status === "Passed")("fa-times", run_r10.Status === "Failed")("fa-exclamation", run_r10.Status === "Error")("fa-hourglass-end", run_r10.Status === "Timeout")("fa-forward", run_r10.Status === "Skipped")("fa-spinner", run_r10.Status === "Running")("fa-clock", run_r10.Status === "Pending");
381
518
  i0.ɵɵadvance(2);
382
- i0.ɵɵtextInterpolate(run_r5.Status);
519
+ i0.ɵɵtextInterpolate(run_r10.Status);
383
520
  } }
384
- function MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Conditional_18_Conditional_0_Template(rf, ctx) { if (rf & 1) {
385
- i0.ɵɵelementStart(0, "span", 105);
386
- i0.ɵɵelement(1, "i", 107);
521
+ function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_18_Conditional_0_Template(rf, ctx) { if (rf & 1) {
522
+ i0.ɵɵelementStart(0, "span", 149);
523
+ i0.ɵɵelement(1, "i", 151);
387
524
  i0.ɵɵelementEnd();
388
525
  } }
389
- function MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Conditional_18_Conditional_1_Template(rf, ctx) { if (rf & 1) {
390
- i0.ɵɵelementStart(0, "span", 108);
391
- i0.ɵɵelement(1, "i", 109);
526
+ function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_18_Conditional_1_Template(rf, ctx) { if (rf & 1) {
527
+ i0.ɵɵelementStart(0, "span", 152);
528
+ i0.ɵɵelement(1, "i", 153);
392
529
  i0.ɵɵelementStart(2, "span");
393
530
  i0.ɵɵtext(3);
394
531
  i0.ɵɵelementEnd()();
395
532
  } if (rf & 2) {
396
533
  let tmp_19_0;
397
- const rating_r6 = ctx;
398
- const run_r5 = i0.ɵɵnextContext(2).$implicit;
534
+ const rating_r11 = ctx;
535
+ const run_r10 = i0.ɵɵnextContext(2).$implicit;
399
536
  const ctx_r0 = i0.ɵɵnextContext(3);
400
- i0.ɵɵclassProp("rating-low", rating_r6 <= 4)("rating-medium", rating_r6 >= 5 && rating_r6 <= 6)("rating-good", rating_r6 >= 7 && rating_r6 <= 8)("rating-excellent", rating_r6 >= 9);
401
- i0.ɵɵproperty("title", ctx_r0.getHumanTooltip(rating_r6, ((tmp_19_0 = ctx_r0.getFeedbackForRun(run_r5.ID)) == null ? null : tmp_19_0.CorrectionSummary) || ((tmp_19_0 = ctx_r0.getFeedbackForRun(run_r5.ID)) == null ? null : tmp_19_0.Comments) || null));
537
+ i0.ɵɵclassProp("rating-low", rating_r11 <= 4)("rating-medium", rating_r11 >= 5 && rating_r11 <= 6)("rating-good", rating_r11 >= 7 && rating_r11 <= 8)("rating-excellent", rating_r11 >= 9);
538
+ i0.ɵɵproperty("title", ctx_r0.getHumanTooltip(rating_r11, ((tmp_19_0 = ctx_r0.getFeedbackForRun(run_r10.ID)) == null ? null : tmp_19_0.CorrectionSummary) || ((tmp_19_0 = ctx_r0.getFeedbackForRun(run_r10.ID)) == null ? null : tmp_19_0.Comments) || null));
402
539
  i0.ɵɵadvance(3);
403
- i0.ɵɵtextInterpolate(rating_r6);
540
+ i0.ɵɵtextInterpolate(rating_r11);
404
541
  } }
405
- function MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Conditional_18_Template(rf, ctx) { if (rf & 1) {
406
- i0.ɵɵconditionalCreate(0, MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Conditional_18_Conditional_0_Template, 2, 0, "span", 105);
407
- i0.ɵɵconditionalCreate(1, MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Conditional_18_Conditional_1_Template, 4, 10, "span", 106);
542
+ function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_18_Template(rf, ctx) { if (rf & 1) {
543
+ i0.ɵɵconditionalCreate(0, MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_18_Conditional_0_Template, 2, 0, "span", 149);
544
+ i0.ɵɵconditionalCreate(1, MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_18_Conditional_1_Template, 4, 10, "span", 150);
408
545
  } if (rf & 2) {
409
546
  let tmp_13_0;
410
547
  let tmp_14_0;
411
- const run_r5 = i0.ɵɵnextContext().$implicit;
548
+ const run_r10 = i0.ɵɵnextContext().$implicit;
412
549
  const ctx_r0 = i0.ɵɵnextContext(3);
413
- i0.ɵɵconditional(!((tmp_13_0 = ctx_r0.getFeedbackForRun(run_r5.ID)) == null ? null : tmp_13_0.Rating) ? 0 : -1);
550
+ i0.ɵɵconditional(!((tmp_13_0 = ctx_r0.getFeedbackForRun(run_r10.ID)) == null ? null : tmp_13_0.Rating) ? 0 : -1);
414
551
  i0.ɵɵadvance();
415
- i0.ɵɵconditional((tmp_14_0 = (tmp_14_0 = ctx_r0.getFeedbackForRun(run_r5.ID)) == null ? null : tmp_14_0.Rating) ? 1 : -1, tmp_14_0);
552
+ i0.ɵɵconditional((tmp_14_0 = (tmp_14_0 = ctx_r0.getFeedbackForRun(run_r10.ID)) == null ? null : tmp_14_0.Rating) ? 1 : -1, tmp_14_0);
416
553
  } }
417
- function MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Conditional_19_Conditional_0_Template(rf, ctx) { if (rf & 1) {
418
- i0.ɵɵelementStart(0, "span", 110);
419
- i0.ɵɵelement(1, "i", 112);
554
+ function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_19_Conditional_0_Template(rf, ctx) { if (rf & 1) {
555
+ i0.ɵɵelementStart(0, "span", 154);
556
+ i0.ɵɵelement(1, "i", 156);
420
557
  i0.ɵɵelementEnd();
421
558
  } }
422
- function MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Conditional_19_Conditional_1_Template(rf, ctx) { if (rf & 1) {
423
- i0.ɵɵelementStart(0, "span", 113);
424
- i0.ɵɵelement(1, "i", 112);
559
+ function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_19_Conditional_1_Template(rf, ctx) { if (rf & 1) {
560
+ i0.ɵɵelementStart(0, "span", 157);
561
+ i0.ɵɵelement(1, "i", 156);
425
562
  i0.ɵɵelementStart(2, "span");
426
563
  i0.ɵɵtext(3);
427
564
  i0.ɵɵelementEnd()();
428
565
  } if (rf & 2) {
429
- const run_r5 = i0.ɵɵnextContext(2).$implicit;
430
- i0.ɵɵclassProp("score-low", run_r5.Score < 0.5)("score-medium", run_r5.Score >= 0.5 && run_r5.Score < 0.7)("score-good", run_r5.Score >= 0.7 && run_r5.Score < 0.85)("score-excellent", run_r5.Score >= 0.85);
431
- i0.ɵɵproperty("title", "Auto Score: " + (run_r5.Score * 100).toFixed(0) + "% automated evaluation");
566
+ const run_r10 = i0.ɵɵnextContext(2).$implicit;
567
+ i0.ɵɵclassProp("score-low", run_r10.Score < 0.5)("score-medium", run_r10.Score >= 0.5 && run_r10.Score < 0.7)("score-good", run_r10.Score >= 0.7 && run_r10.Score < 0.85)("score-excellent", run_r10.Score >= 0.85);
568
+ i0.ɵɵproperty("title", "Auto Score: " + (run_r10.Score * 100).toFixed(0) + "% automated evaluation");
432
569
  i0.ɵɵadvance(3);
433
- i0.ɵɵtextInterpolate1("", (run_r5.Score * 100).toFixed(0), "%");
570
+ i0.ɵɵtextInterpolate1("", (run_r10.Score * 100).toFixed(0), "%");
434
571
  } }
435
- function MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Conditional_19_Template(rf, ctx) { if (rf & 1) {
436
- i0.ɵɵconditionalCreate(0, MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Conditional_19_Conditional_0_Template, 2, 0, "span", 110);
437
- i0.ɵɵconditionalCreate(1, MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Conditional_19_Conditional_1_Template, 4, 10, "span", 111);
572
+ function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_19_Template(rf, ctx) { if (rf & 1) {
573
+ i0.ɵɵconditionalCreate(0, MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_19_Conditional_0_Template, 2, 0, "span", 154);
574
+ i0.ɵɵconditionalCreate(1, MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_19_Conditional_1_Template, 4, 10, "span", 155);
438
575
  } if (rf & 2) {
439
- const run_r5 = i0.ɵɵnextContext().$implicit;
440
- i0.ɵɵconditional(run_r5.Score == null ? 0 : -1);
576
+ const run_r10 = i0.ɵɵnextContext().$implicit;
577
+ i0.ɵɵconditional(run_r10.Score == null ? 0 : -1);
441
578
  i0.ɵɵadvance();
442
- i0.ɵɵconditional(run_r5.Score != null ? 1 : -1);
579
+ i0.ɵɵconditional(run_r10.Score != null ? 1 : -1);
443
580
  } }
444
- function MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Conditional_20_For_2_Template(rf, ctx) { if (rf & 1) {
445
- i0.ɵɵelementStart(0, "span", 114);
581
+ function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_20_For_2_Template(rf, ctx) { if (rf & 1) {
582
+ i0.ɵɵelementStart(0, "span", 158);
446
583
  i0.ɵɵtext(1);
447
584
  i0.ɵɵelementEnd();
448
585
  } if (rf & 2) {
449
- const tag_r7 = ctx.$implicit;
586
+ const tag_r12 = ctx.$implicit;
450
587
  i0.ɵɵadvance();
451
- i0.ɵɵtextInterpolate(tag_r7);
588
+ i0.ɵɵtextInterpolate(tag_r12);
452
589
  } }
453
- function MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Conditional_20_Conditional_3_Template(rf, ctx) { if (rf & 1) {
454
- i0.ɵɵelementStart(0, "span", 115);
590
+ function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_20_Conditional_3_Template(rf, ctx) { if (rf & 1) {
591
+ i0.ɵɵelementStart(0, "span", 159);
455
592
  i0.ɵɵtext(1);
456
593
  i0.ɵɵelementEnd();
457
594
  } if (rf & 2) {
458
- const run_r5 = i0.ɵɵnextContext(2).$implicit;
595
+ const run_r10 = i0.ɵɵnextContext(2).$implicit;
459
596
  const ctx_r0 = i0.ɵɵnextContext(3);
460
597
  i0.ɵɵadvance();
461
- i0.ɵɵtextInterpolate1("+", ctx_r0.getRunTags(run_r5).length - 3);
598
+ i0.ɵɵtextInterpolate1("+", ctx_r0.getRunTags(run_r10).length - 3);
462
599
  } }
463
- function MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Conditional_20_Template(rf, ctx) { if (rf & 1) {
464
- i0.ɵɵelementStart(0, "div", 101);
465
- i0.ɵɵrepeaterCreate(1, MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Conditional_20_For_2_Template, 2, 1, "span", 114, i0.ɵɵrepeaterTrackByIdentity);
466
- i0.ɵɵconditionalCreate(3, MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Conditional_20_Conditional_3_Template, 2, 1, "span", 115);
600
+ function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_20_Template(rf, ctx) { if (rf & 1) {
601
+ i0.ɵɵelementStart(0, "div", 145);
602
+ i0.ɵɵrepeaterCreate(1, MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_20_For_2_Template, 2, 1, "span", 158, i0.ɵɵrepeaterTrackByIdentity);
603
+ i0.ɵɵconditionalCreate(3, MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_20_Conditional_3_Template, 2, 1, "span", 159);
467
604
  i0.ɵɵelementEnd();
468
605
  } if (rf & 2) {
469
- const run_r5 = i0.ɵɵnextContext().$implicit;
606
+ const run_r10 = i0.ɵɵnextContext().$implicit;
470
607
  const ctx_r0 = i0.ɵɵnextContext(3);
471
608
  i0.ɵɵadvance();
472
- i0.ɵɵrepeater(ctx_r0.getRunTags(run_r5).slice(0, 3));
609
+ i0.ɵɵrepeater(ctx_r0.getRunTags(run_r10).slice(0, 3));
473
610
  i0.ɵɵadvance(2);
474
- i0.ɵɵconditional(ctx_r0.getRunTags(run_r5).length > 3 ? 3 : -1);
611
+ i0.ɵɵconditional(ctx_r0.getRunTags(run_r10).length > 3 ? 3 : -1);
475
612
  } }
476
- function MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Template(rf, ctx) { if (rf & 1) {
477
- const _r4 = i0.ɵɵgetCurrentView();
478
- i0.ɵɵelementStart(0, "div", 89);
479
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Template_div_click_0_listener() { const run_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.openTestRun(run_r5.ID)); });
480
- i0.ɵɵelementStart(1, "div", 90);
481
- i0.ɵɵelement(2, "i", 91);
613
+ function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Template(rf, ctx) { if (rf & 1) {
614
+ const _r9 = i0.ɵɵgetCurrentView();
615
+ i0.ɵɵelementStart(0, "div", 133);
616
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Template_div_click_0_listener() { const run_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.openTestRun(run_r10.ID)); });
617
+ i0.ɵɵelementStart(1, "div", 134);
618
+ i0.ɵɵelement(2, "i", 135);
482
619
  i0.ɵɵelementEnd();
483
- i0.ɵɵelementStart(3, "div", 92)(4, "div", 93)(5, "span", 94);
620
+ i0.ɵɵelementStart(3, "div", 136)(4, "div", 137)(5, "span", 138);
484
621
  i0.ɵɵtext(6);
485
622
  i0.ɵɵelementEnd();
486
- i0.ɵɵelementStart(7, "span", 95);
623
+ i0.ɵɵelementStart(7, "span", 139);
487
624
  i0.ɵɵtext(8);
488
625
  i0.ɵɵelementEnd()();
489
- i0.ɵɵelementStart(9, "div", 96)(10, "span");
490
- i0.ɵɵelement(11, "i", 97);
626
+ i0.ɵɵelementStart(9, "div", 140)(10, "span");
627
+ i0.ɵɵelement(11, "i", 141);
491
628
  i0.ɵɵtext(12);
492
629
  i0.ɵɵelementEnd();
493
- i0.ɵɵconditionalCreate(13, MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Conditional_13_Template, 3, 1, "span");
494
- i0.ɵɵconditionalCreate(14, MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Conditional_14_Template, 3, 1, "span");
495
- i0.ɵɵconditionalCreate(15, MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Conditional_15_Template, 1, 2, "mj-entity-link-pill", 98);
630
+ i0.ɵɵconditionalCreate(13, MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_13_Template, 3, 1, "span");
631
+ i0.ɵɵconditionalCreate(14, MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_14_Template, 3, 1, "span");
632
+ i0.ɵɵconditionalCreate(15, MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_15_Template, 1, 2, "mj-entity-link-pill", 142);
496
633
  i0.ɵɵelementEnd();
497
- i0.ɵɵelementStart(16, "div", 99);
498
- i0.ɵɵconditionalCreate(17, MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Conditional_17_Template, 4, 17, "span", 100);
499
- i0.ɵɵconditionalCreate(18, MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Conditional_18_Template, 2, 2);
500
- i0.ɵɵconditionalCreate(19, MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Conditional_19_Template, 2, 2);
634
+ i0.ɵɵelementStart(16, "div", 143);
635
+ i0.ɵɵconditionalCreate(17, MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_17_Template, 4, 17, "span", 144);
636
+ i0.ɵɵconditionalCreate(18, MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_18_Template, 2, 2);
637
+ i0.ɵɵconditionalCreate(19, MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_19_Template, 2, 2);
501
638
  i0.ɵɵelementEnd();
502
- i0.ɵɵconditionalCreate(20, MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Conditional_20_Template, 4, 1, "div", 101);
639
+ i0.ɵɵconditionalCreate(20, MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Conditional_20_Template, 4, 1, "div", 145);
503
640
  i0.ɵɵelementEnd();
504
- i0.ɵɵelement(21, "i", 102);
641
+ i0.ɵɵelement(21, "i", 146);
505
642
  i0.ɵɵelementEnd();
506
643
  } if (rf & 2) {
507
- const run_r5 = ctx.$implicit;
644
+ const run_r10 = ctx.$implicit;
508
645
  const ctx_r0 = i0.ɵɵnextContext(3);
509
646
  i0.ɵɵadvance();
510
- i0.ɵɵstyleProp("background-color", ctx_r0.getRunStatusColor(run_r5.Status));
647
+ i0.ɵɵstyleProp("background-color", ctx_r0.getRunStatusColor(run_r10.Status));
511
648
  i0.ɵɵadvance();
512
- i0.ɵɵclassProp("fa-check", run_r5.Status === "Passed")("fa-times", run_r5.Status === "Failed")("fa-exclamation", run_r5.Status === "Error")("fa-stopwatch", run_r5.Status === "Timeout")("fa-spinner", run_r5.Status === "Running")("fa-clock", run_r5.Status === "Pending");
649
+ i0.ɵɵclassProp("fa-check", run_r10.Status === "Passed")("fa-times", run_r10.Status === "Failed")("fa-exclamation", run_r10.Status === "Error")("fa-stopwatch", run_r10.Status === "Timeout")("fa-spinner", run_r10.Status === "Running")("fa-clock", run_r10.Status === "Pending");
513
650
  i0.ɵɵadvance(4);
514
- i0.ɵɵtextInterpolate1("Run #", run_r5.ID.substring(0, 8));
651
+ i0.ɵɵtextInterpolate1("Run #", run_r10.ID.substring(0, 8));
515
652
  i0.ɵɵadvance();
516
- i0.ɵɵstyleProp("color", ctx_r0.getRunStatusColor(run_r5.Status));
653
+ i0.ɵɵstyleProp("color", ctx_r0.getRunStatusColor(run_r10.Status));
517
654
  i0.ɵɵadvance();
518
- i0.ɵɵtextInterpolate(run_r5.Status);
655
+ i0.ɵɵtextInterpolate(run_r10.Status);
519
656
  i0.ɵɵadvance(4);
520
- i0.ɵɵtextInterpolate1(" ", ctx_r0.getRelativeTime(run_r5.StartedAt));
657
+ i0.ɵɵtextInterpolate1(" ", ctx_r0.getRelativeTime(run_r10.StartedAt));
521
658
  i0.ɵɵadvance();
522
- i0.ɵɵconditional(run_r5.DurationSeconds ? 13 : -1);
659
+ i0.ɵɵconditional(run_r10.DurationSeconds ? 13 : -1);
523
660
  i0.ɵɵadvance();
524
- i0.ɵɵconditional(run_r5.CostUSD ? 14 : -1);
661
+ i0.ɵɵconditional(run_r10.CostUSD ? 14 : -1);
525
662
  i0.ɵɵadvance();
526
- i0.ɵɵconditional(run_r5.TargetLogEntityID && run_r5.TargetLogID ? 15 : -1);
663
+ i0.ɵɵconditional(run_r10.TargetLogEntityID && run_r10.TargetLogID ? 15 : -1);
527
664
  i0.ɵɵadvance(2);
528
665
  i0.ɵɵconditional(ctx_r0.evalPreferences.showExecution ? 17 : -1);
529
666
  i0.ɵɵadvance();
@@ -531,21 +668,21 @@ function MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Template
531
668
  i0.ɵɵadvance();
532
669
  i0.ɵɵconditional(ctx_r0.evalPreferences.showAuto ? 19 : -1);
533
670
  i0.ɵɵadvance();
534
- i0.ɵɵconditional(ctx_r0.getRunTags(run_r5).length > 0 ? 20 : -1);
671
+ i0.ɵɵconditional(ctx_r0.getRunTags(run_r10).length > 0 ? 20 : -1);
535
672
  } }
536
- function MJTestFormComponentExtended_Conditional_63_Conditional_2_Template(rf, ctx) { if (rf & 1) {
537
- i0.ɵɵelementStart(0, "div", 80);
538
- i0.ɵɵrepeaterCreate(1, MJTestFormComponentExtended_Conditional_63_Conditional_2_For_2_Template, 22, 26, "div", 88, i0.ɵɵrepeaterTrackByIdentity);
673
+ function MJTestFormComponentExtended_Conditional_65_Conditional_2_Template(rf, ctx) { if (rf & 1) {
674
+ i0.ɵɵelementStart(0, "div", 124);
675
+ i0.ɵɵrepeaterCreate(1, MJTestFormComponentExtended_Conditional_65_Conditional_2_For_2_Template, 22, 26, "div", 132, i0.ɵɵrepeaterTrackByIdentity);
539
676
  i0.ɵɵelementEnd();
540
677
  } if (rf & 2) {
541
678
  const ctx_r0 = i0.ɵɵnextContext(2);
542
679
  i0.ɵɵadvance();
543
680
  i0.ɵɵrepeater(ctx_r0.testRuns);
544
681
  } }
545
- function MJTestFormComponentExtended_Conditional_63_Conditional_3_Template(rf, ctx) { if (rf & 1) {
546
- const _r8 = i0.ɵɵgetCurrentView();
547
- i0.ɵɵelementStart(0, "div", 81)(1, "div", 116);
548
- i0.ɵɵelement(2, "i", 117);
682
+ function MJTestFormComponentExtended_Conditional_65_Conditional_3_Template(rf, ctx) { if (rf & 1) {
683
+ const _r13 = i0.ɵɵgetCurrentView();
684
+ i0.ɵɵelementStart(0, "div", 125)(1, "div", 160);
685
+ i0.ɵɵelement(2, "i", 161);
549
686
  i0.ɵɵelementEnd();
550
687
  i0.ɵɵelementStart(3, "h4");
551
688
  i0.ɵɵtext(4, "No Test Runs Yet");
@@ -553,17 +690,17 @@ function MJTestFormComponentExtended_Conditional_63_Conditional_3_Template(rf, c
553
690
  i0.ɵɵelementStart(5, "p");
554
691
  i0.ɵɵtext(6, "Run this test to see execution history and results here.");
555
692
  i0.ɵɵelementEnd();
556
- i0.ɵɵelementStart(7, "button", 18);
557
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_63_Conditional_3_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r8); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.runTest()); });
558
- i0.ɵɵelement(8, "i", 19);
693
+ i0.ɵɵelementStart(7, "button", 21);
694
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_65_Conditional_3_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r13); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.runTest()); });
695
+ i0.ɵɵelement(8, "i", 22);
559
696
  i0.ɵɵtext(9, " Run Test Now ");
560
697
  i0.ɵɵelementEnd()();
561
698
  } }
562
- function MJTestFormComponentExtended_Conditional_63_Template(rf, ctx) { if (rf & 1) {
563
- i0.ɵɵelementStart(0, "div", 35);
564
- i0.ɵɵconditionalCreate(1, MJTestFormComponentExtended_Conditional_63_Conditional_1_Template, 4, 1, "div", 79);
565
- i0.ɵɵconditionalCreate(2, MJTestFormComponentExtended_Conditional_63_Conditional_2_Template, 3, 0, "div", 80);
566
- i0.ɵɵconditionalCreate(3, MJTestFormComponentExtended_Conditional_63_Conditional_3_Template, 10, 0, "div", 81);
699
+ function MJTestFormComponentExtended_Conditional_65_Template(rf, ctx) { if (rf & 1) {
700
+ i0.ɵɵelementStart(0, "div", 38);
701
+ i0.ɵɵconditionalCreate(1, MJTestFormComponentExtended_Conditional_65_Conditional_1_Template, 4, 1, "div", 123);
702
+ i0.ɵɵconditionalCreate(2, MJTestFormComponentExtended_Conditional_65_Conditional_2_Template, 3, 0, "div", 124);
703
+ i0.ɵɵconditionalCreate(3, MJTestFormComponentExtended_Conditional_65_Conditional_3_Template, 10, 0, "div", 125);
567
704
  i0.ɵɵelementEnd();
568
705
  } if (rf & 2) {
569
706
  const ctx_r0 = i0.ɵɵnextContext();
@@ -574,70 +711,70 @@ function MJTestFormComponentExtended_Conditional_63_Template(rf, ctx) { if (rf &
574
711
  i0.ɵɵadvance();
575
712
  i0.ɵɵconditional(ctx_r0.testRunsLoaded && !ctx_r0.loadingRuns && ctx_r0.testRuns.length === 0 ? 3 : -1);
576
713
  } }
577
- function MJTestFormComponentExtended_Conditional_64_Conditional_1_For_3_Template(rf, ctx) { if (rf & 1) {
578
- i0.ɵɵelementStart(0, "div", 83);
579
- i0.ɵɵelement(1, "div", 84);
580
- i0.ɵɵelementStart(2, "div", 85);
581
- i0.ɵɵelement(3, "div", 86)(4, "div", 87);
714
+ function MJTestFormComponentExtended_Conditional_66_Conditional_1_For_3_Template(rf, ctx) { if (rf & 1) {
715
+ i0.ɵɵelementStart(0, "div", 127);
716
+ i0.ɵɵelement(1, "div", 128);
717
+ i0.ɵɵelementStart(2, "div", 129);
718
+ i0.ɵɵelement(3, "div", 130)(4, "div", 131);
582
719
  i0.ɵɵelementEnd()();
583
720
  } }
584
- function MJTestFormComponentExtended_Conditional_64_Conditional_1_Template(rf, ctx) { if (rf & 1) {
585
- i0.ɵɵelementStart(0, "div", 79)(1, "div", 82);
586
- i0.ɵɵrepeaterCreate(2, MJTestFormComponentExtended_Conditional_64_Conditional_1_For_3_Template, 5, 0, "div", 83, i0.ɵɵrepeaterTrackByIdentity);
721
+ function MJTestFormComponentExtended_Conditional_66_Conditional_1_Template(rf, ctx) { if (rf & 1) {
722
+ i0.ɵɵelementStart(0, "div", 123)(1, "div", 126);
723
+ i0.ɵɵrepeaterCreate(2, MJTestFormComponentExtended_Conditional_66_Conditional_1_For_3_Template, 5, 0, "div", 127, i0.ɵɵrepeaterTrackByIdentity);
587
724
  i0.ɵɵelementEnd()();
588
725
  } if (rf & 2) {
589
726
  i0.ɵɵadvance(2);
590
727
  i0.ɵɵrepeater(i0.ɵɵpureFunction0(0, _c1));
591
728
  } }
592
- function MJTestFormComponentExtended_Conditional_64_Conditional_2_For_2_Conditional_10_Template(rf, ctx) { if (rf & 1) {
729
+ function MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_10_Template(rf, ctx) { if (rf & 1) {
593
730
  i0.ɵɵelementStart(0, "span");
594
- i0.ɵɵelement(1, "i", 49);
731
+ i0.ɵɵelement(1, "i", 62);
595
732
  i0.ɵɵtext(2);
596
733
  i0.ɵɵelementEnd();
597
734
  } if (rf & 2) {
598
- const suiteTest_r10 = i0.ɵɵnextContext().$implicit;
735
+ const suiteTest_r15 = i0.ɵɵnextContext().$implicit;
599
736
  i0.ɵɵadvance(2);
600
- i0.ɵɵtextInterpolate1(" ", suiteTest_r10.Status);
737
+ i0.ɵɵtextInterpolate1(" ", suiteTest_r15.Status);
601
738
  } }
602
- function MJTestFormComponentExtended_Conditional_64_Conditional_2_For_2_Template(rf, ctx) { if (rf & 1) {
603
- const _r9 = i0.ɵɵgetCurrentView();
604
- i0.ɵɵelementStart(0, "div", 120);
605
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_64_Conditional_2_For_2_Template_div_click_0_listener() { const suiteTest_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.openTestSuite(suiteTest_r10.SuiteID)); });
606
- i0.ɵɵelementStart(1, "div", 121);
607
- i0.ɵɵelement(2, "i", 30);
608
- i0.ɵɵelementEnd();
609
- i0.ɵɵelementStart(3, "div", 122)(4, "div", 123);
739
+ function MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Template(rf, ctx) { if (rf & 1) {
740
+ const _r14 = i0.ɵɵgetCurrentView();
741
+ i0.ɵɵelementStart(0, "div", 164);
742
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Template_div_click_0_listener() { const suiteTest_r15 = i0.ɵɵrestoreView(_r14).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.openTestSuite(suiteTest_r15.SuiteID)); });
743
+ i0.ɵɵelementStart(1, "div", 165);
744
+ i0.ɵɵelement(2, "i", 33);
745
+ i0.ɵɵelementEnd();
746
+ i0.ɵɵelementStart(3, "div", 166)(4, "div", 167);
610
747
  i0.ɵɵtext(5);
611
748
  i0.ɵɵelementEnd();
612
- i0.ɵɵelementStart(6, "div", 124)(7, "span");
613
- i0.ɵɵelement(8, "i", 125);
749
+ i0.ɵɵelementStart(6, "div", 168)(7, "span");
750
+ i0.ɵɵelement(8, "i", 169);
614
751
  i0.ɵɵtext(9);
615
752
  i0.ɵɵelementEnd();
616
- i0.ɵɵconditionalCreate(10, MJTestFormComponentExtended_Conditional_64_Conditional_2_For_2_Conditional_10_Template, 3, 1, "span");
753
+ i0.ɵɵconditionalCreate(10, MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Conditional_10_Template, 3, 1, "span");
617
754
  i0.ɵɵelementEnd()();
618
- i0.ɵɵelement(11, "i", 102);
755
+ i0.ɵɵelement(11, "i", 146);
619
756
  i0.ɵɵelementEnd();
620
757
  } if (rf & 2) {
621
- const suiteTest_r10 = ctx.$implicit;
758
+ const suiteTest_r15 = ctx.$implicit;
622
759
  i0.ɵɵadvance(5);
623
- i0.ɵɵtextInterpolate(suiteTest_r10.Suite);
760
+ i0.ɵɵtextInterpolate(suiteTest_r15.Suite);
624
761
  i0.ɵɵadvance(4);
625
- i0.ɵɵtextInterpolate1(" Sequence: ", suiteTest_r10.Sequence);
762
+ i0.ɵɵtextInterpolate1(" Sequence: ", suiteTest_r15.Sequence);
626
763
  i0.ɵɵadvance();
627
- i0.ɵɵconditional(suiteTest_r10.Status ? 10 : -1);
764
+ i0.ɵɵconditional(suiteTest_r15.Status ? 10 : -1);
628
765
  } }
629
- function MJTestFormComponentExtended_Conditional_64_Conditional_2_Template(rf, ctx) { if (rf & 1) {
630
- i0.ɵɵelementStart(0, "div", 118);
631
- i0.ɵɵrepeaterCreate(1, MJTestFormComponentExtended_Conditional_64_Conditional_2_For_2_Template, 12, 3, "div", 119, i0.ɵɵrepeaterTrackByIdentity);
766
+ function MJTestFormComponentExtended_Conditional_66_Conditional_2_Template(rf, ctx) { if (rf & 1) {
767
+ i0.ɵɵelementStart(0, "div", 162);
768
+ i0.ɵɵrepeaterCreate(1, MJTestFormComponentExtended_Conditional_66_Conditional_2_For_2_Template, 12, 3, "div", 163, i0.ɵɵrepeaterTrackByIdentity);
632
769
  i0.ɵɵelementEnd();
633
770
  } if (rf & 2) {
634
771
  const ctx_r0 = i0.ɵɵnextContext(2);
635
772
  i0.ɵɵadvance();
636
773
  i0.ɵɵrepeater(ctx_r0.suiteTests);
637
774
  } }
638
- function MJTestFormComponentExtended_Conditional_64_Conditional_3_Template(rf, ctx) { if (rf & 1) {
639
- i0.ɵɵelementStart(0, "div", 81)(1, "div", 116);
640
- i0.ɵɵelement(2, "i", 126);
775
+ function MJTestFormComponentExtended_Conditional_66_Conditional_3_Template(rf, ctx) { if (rf & 1) {
776
+ i0.ɵɵelementStart(0, "div", 125)(1, "div", 160);
777
+ i0.ɵɵelement(2, "i", 170);
641
778
  i0.ɵɵelementEnd();
642
779
  i0.ɵɵelementStart(3, "h4");
643
780
  i0.ɵɵtext(4, "Not Part of Any Suite");
@@ -646,11 +783,11 @@ function MJTestFormComponentExtended_Conditional_64_Conditional_3_Template(rf, c
646
783
  i0.ɵɵtext(6, "This test is not included in any test suites. Add it to a suite to run it with other tests.");
647
784
  i0.ɵɵelementEnd()();
648
785
  } }
649
- function MJTestFormComponentExtended_Conditional_64_Template(rf, ctx) { if (rf & 1) {
650
- i0.ɵɵelementStart(0, "div", 36);
651
- i0.ɵɵconditionalCreate(1, MJTestFormComponentExtended_Conditional_64_Conditional_1_Template, 4, 1, "div", 79);
652
- i0.ɵɵconditionalCreate(2, MJTestFormComponentExtended_Conditional_64_Conditional_2_Template, 3, 0, "div", 118);
653
- i0.ɵɵconditionalCreate(3, MJTestFormComponentExtended_Conditional_64_Conditional_3_Template, 7, 0, "div", 81);
786
+ function MJTestFormComponentExtended_Conditional_66_Template(rf, ctx) { if (rf & 1) {
787
+ i0.ɵɵelementStart(0, "div", 39);
788
+ i0.ɵɵconditionalCreate(1, MJTestFormComponentExtended_Conditional_66_Conditional_1_Template, 4, 1, "div", 123);
789
+ i0.ɵɵconditionalCreate(2, MJTestFormComponentExtended_Conditional_66_Conditional_2_Template, 3, 0, "div", 162);
790
+ i0.ɵɵconditionalCreate(3, MJTestFormComponentExtended_Conditional_66_Conditional_3_Template, 7, 0, "div", 125);
654
791
  i0.ɵɵelementEnd();
655
792
  } if (rf & 2) {
656
793
  const ctx_r0 = i0.ɵɵnextContext();
@@ -661,20 +798,20 @@ function MJTestFormComponentExtended_Conditional_64_Template(rf, ctx) { if (rf &
661
798
  i0.ɵɵadvance();
662
799
  i0.ɵɵconditional(ctx_r0.suiteTestsLoaded && !ctx_r0.loadingSuites && ctx_r0.suiteTests.length === 0 ? 3 : -1);
663
800
  } }
664
- function MJTestFormComponentExtended_Conditional_65_Conditional_1_Template(rf, ctx) { if (rf & 1) {
665
- i0.ɵɵelementStart(0, "div", 79);
666
- i0.ɵɵelement(1, "mj-loading", 128);
801
+ function MJTestFormComponentExtended_Conditional_67_Conditional_1_Template(rf, ctx) { if (rf & 1) {
802
+ i0.ɵɵelementStart(0, "div", 123);
803
+ i0.ɵɵelement(1, "mj-loading", 172);
667
804
  i0.ɵɵelementEnd();
668
805
  } }
669
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_17_Conditional_9_Template(rf, ctx) { if (rf & 1) {
670
- i0.ɵɵelementStart(0, "div", 137)(1, "div", 142);
671
- i0.ɵɵelement(2, "i", 143);
806
+ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_17_Conditional_9_Template(rf, ctx) { if (rf & 1) {
807
+ i0.ɵɵelementStart(0, "div", 181)(1, "div", 186);
808
+ i0.ɵɵelement(2, "i", 187);
672
809
  i0.ɵɵelementEnd();
673
- i0.ɵɵelementStart(3, "div", 139)(4, "div", 140);
810
+ i0.ɵɵelementStart(3, "div", 183)(4, "div", 184);
674
811
  i0.ɵɵtext(5);
675
- i0.ɵɵelement(6, "i", 144);
812
+ i0.ɵɵelement(6, "i", 188);
676
813
  i0.ɵɵelementEnd();
677
- i0.ɵɵelementStart(7, "div", 141);
814
+ i0.ɵɵelementStart(7, "div", 185);
678
815
  i0.ɵɵtext(8, "Pass Rate");
679
816
  i0.ɵɵelementEnd()()();
680
817
  } if (rf & 2) {
@@ -684,14 +821,14 @@ function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_17
684
821
  i0.ɵɵadvance();
685
822
  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");
686
823
  } }
687
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_17_Conditional_10_Template(rf, ctx) { if (rf & 1) {
688
- i0.ɵɵelementStart(0, "div", 137)(1, "div", 138);
689
- i0.ɵɵelement(2, "i", 145);
824
+ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_17_Conditional_10_Template(rf, ctx) { if (rf & 1) {
825
+ i0.ɵɵelementStart(0, "div", 181)(1, "div", 182);
826
+ i0.ɵɵelement(2, "i", 189);
690
827
  i0.ɵɵelementEnd();
691
- i0.ɵɵelementStart(3, "div", 139)(4, "div", 140);
828
+ i0.ɵɵelementStart(3, "div", 183)(4, "div", 184);
692
829
  i0.ɵɵtext(5);
693
830
  i0.ɵɵelementEnd();
694
- i0.ɵɵelementStart(6, "div", 141);
831
+ i0.ɵɵelementStart(6, "div", 185);
695
832
  i0.ɵɵtext(7, "Avg Score");
696
833
  i0.ɵɵelementEnd()()();
697
834
  } if (rf & 2) {
@@ -699,34 +836,34 @@ function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_17
699
836
  i0.ɵɵadvance(5);
700
837
  i0.ɵɵtextInterpolate1("", (ctx_r0.getOverallAvgScore() * 100).toFixed(1), "%");
701
838
  } }
702
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_17_Template(rf, ctx) { if (rf & 1) {
703
- i0.ɵɵelementStart(0, "div", 135)(1, "div", 137)(2, "div", 138);
704
- i0.ɵɵelement(3, "i", 117);
839
+ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_17_Template(rf, ctx) { if (rf & 1) {
840
+ i0.ɵɵelementStart(0, "div", 179)(1, "div", 181)(2, "div", 182);
841
+ i0.ɵɵelement(3, "i", 161);
705
842
  i0.ɵɵelementEnd();
706
- i0.ɵɵelementStart(4, "div", 139)(5, "div", 140);
843
+ i0.ɵɵelementStart(4, "div", 183)(5, "div", 184);
707
844
  i0.ɵɵtext(6);
708
845
  i0.ɵɵelementEnd();
709
- i0.ɵɵelementStart(7, "div", 141);
846
+ i0.ɵɵelementStart(7, "div", 185);
710
847
  i0.ɵɵtext(8, "Total Runs");
711
848
  i0.ɵɵelementEnd()()();
712
- i0.ɵɵconditionalCreate(9, MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_17_Conditional_9_Template, 9, 11, "div", 137);
713
- i0.ɵɵconditionalCreate(10, MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_17_Conditional_10_Template, 8, 1, "div", 137);
714
- i0.ɵɵelementStart(11, "div", 137)(12, "div", 138);
715
- i0.ɵɵelement(13, "i", 103);
849
+ i0.ɵɵconditionalCreate(9, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_17_Conditional_9_Template, 9, 11, "div", 181);
850
+ i0.ɵɵconditionalCreate(10, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_17_Conditional_10_Template, 8, 1, "div", 181);
851
+ i0.ɵɵelementStart(11, "div", 181)(12, "div", 182);
852
+ i0.ɵɵelement(13, "i", 147);
716
853
  i0.ɵɵelementEnd();
717
- i0.ɵɵelementStart(14, "div", 139)(15, "div", 140);
854
+ i0.ɵɵelementStart(14, "div", 183)(15, "div", 184);
718
855
  i0.ɵɵtext(16);
719
856
  i0.ɵɵelementEnd();
720
- i0.ɵɵelementStart(17, "div", 141);
857
+ i0.ɵɵelementStart(17, "div", 185);
721
858
  i0.ɵɵtext(18, "Avg Duration");
722
859
  i0.ɵɵelementEnd()()();
723
- i0.ɵɵelementStart(19, "div", 137)(20, "div", 138);
724
- i0.ɵɵelement(21, "i", 104);
860
+ i0.ɵɵelementStart(19, "div", 181)(20, "div", 182);
861
+ i0.ɵɵelement(21, "i", 148);
725
862
  i0.ɵɵelementEnd();
726
- i0.ɵɵelementStart(22, "div", 139)(23, "div", 140);
863
+ i0.ɵɵelementStart(22, "div", 183)(23, "div", 184);
727
864
  i0.ɵɵtext(24);
728
865
  i0.ɵɵelementEnd();
729
- i0.ɵɵelementStart(25, "div", 141);
866
+ i0.ɵɵelementStart(25, "div", 185);
730
867
  i0.ɵɵtext(26, "Avg Cost");
731
868
  i0.ɵɵelementEnd()()()();
732
869
  } if (rf & 2) {
@@ -742,91 +879,91 @@ function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_17
742
879
  i0.ɵɵadvance(8);
743
880
  i0.ɵɵtextInterpolate(ctx_r0.formatCost(ctx_r0.getOverallAvgCost()));
744
881
  } }
745
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_18_Conditional_12_Template(rf, ctx) { if (rf & 1) {
882
+ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_Conditional_12_Template(rf, ctx) { if (rf & 1) {
746
883
  i0.ɵɵelementStart(0, "th");
747
884
  i0.ɵɵtext(1, "Passed");
748
885
  i0.ɵɵelementEnd();
749
886
  } }
750
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_18_Conditional_13_Template(rf, ctx) { if (rf & 1) {
887
+ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_Conditional_13_Template(rf, ctx) { if (rf & 1) {
751
888
  i0.ɵɵelementStart(0, "th");
752
889
  i0.ɵɵtext(1, "Failed");
753
890
  i0.ɵɵelementEnd();
754
891
  } }
755
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_18_Conditional_14_Template(rf, ctx) { if (rf & 1) {
892
+ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_Conditional_14_Template(rf, ctx) { if (rf & 1) {
756
893
  i0.ɵɵelementStart(0, "th");
757
894
  i0.ɵɵtext(1, "Pass Rate");
758
895
  i0.ɵɵelementEnd();
759
896
  } }
760
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_18_Conditional_15_Template(rf, ctx) { if (rf & 1) {
897
+ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_Conditional_15_Template(rf, ctx) { if (rf & 1) {
761
898
  i0.ɵɵelementStart(0, "th");
762
899
  i0.ɵɵtext(1, "Avg Score");
763
900
  i0.ɵɵelementEnd();
764
901
  } }
765
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_18_For_22_Conditional_6_Template(rf, ctx) { if (rf & 1) {
766
- i0.ɵɵelementStart(0, "td", 151);
902
+ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_For_22_Conditional_6_Template(rf, ctx) { if (rf & 1) {
903
+ i0.ɵɵelementStart(0, "td", 195);
767
904
  i0.ɵɵtext(1);
768
905
  i0.ɵɵelementEnd();
769
906
  } if (rf & 2) {
770
- const day_r12 = i0.ɵɵnextContext().$implicit;
907
+ const day_r17 = i0.ɵɵnextContext().$implicit;
771
908
  i0.ɵɵadvance();
772
- i0.ɵɵtextInterpolate(day_r12.passCount);
909
+ i0.ɵɵtextInterpolate(day_r17.passCount);
773
910
  } }
774
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_18_For_22_Conditional_7_Template(rf, ctx) { if (rf & 1) {
775
- i0.ɵɵelementStart(0, "td", 152);
911
+ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_For_22_Conditional_7_Template(rf, ctx) { if (rf & 1) {
912
+ i0.ɵɵelementStart(0, "td", 196);
776
913
  i0.ɵɵtext(1);
777
914
  i0.ɵɵelementEnd();
778
915
  } if (rf & 2) {
779
- const day_r12 = i0.ɵɵnextContext().$implicit;
916
+ const day_r17 = i0.ɵɵnextContext().$implicit;
780
917
  i0.ɵɵadvance();
781
- i0.ɵɵtextInterpolate(day_r12.failCount);
918
+ i0.ɵɵtextInterpolate(day_r17.failCount);
782
919
  } }
783
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_18_For_22_Conditional_8_Template(rf, ctx) { if (rf & 1) {
784
- i0.ɵɵelementStart(0, "td", 153)(1, "div", 157);
785
- i0.ɵɵelement(2, "div", 158);
786
- i0.ɵɵelementStart(3, "span", 159);
920
+ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_For_22_Conditional_8_Template(rf, ctx) { if (rf & 1) {
921
+ i0.ɵɵelementStart(0, "td", 197)(1, "div", 201);
922
+ i0.ɵɵelement(2, "div", 202);
923
+ i0.ɵɵelementStart(3, "span", 203);
787
924
  i0.ɵɵtext(4);
788
925
  i0.ɵɵelementEnd()()();
789
926
  } if (rf & 2) {
790
- const day_r12 = i0.ɵɵnextContext().$implicit;
927
+ const day_r17 = i0.ɵɵnextContext().$implicit;
791
928
  i0.ɵɵadvance(2);
792
- i0.ɵɵstyleProp("width", day_r12.passRate, "%");
929
+ i0.ɵɵstyleProp("width", day_r17.passRate, "%");
793
930
  i0.ɵɵadvance(2);
794
- i0.ɵɵtextInterpolate1("", day_r12.passRate.toFixed(1), "%");
931
+ i0.ɵɵtextInterpolate1("", day_r17.passRate.toFixed(1), "%");
795
932
  } }
796
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_18_For_22_Conditional_9_Template(rf, ctx) { if (rf & 1) {
797
- i0.ɵɵelementStart(0, "td", 154);
933
+ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_For_22_Conditional_9_Template(rf, ctx) { if (rf & 1) {
934
+ i0.ɵɵelementStart(0, "td", 198);
798
935
  i0.ɵɵtext(1);
799
936
  i0.ɵɵelementEnd();
800
937
  } if (rf & 2) {
801
- const day_r12 = i0.ɵɵnextContext().$implicit;
938
+ const day_r17 = i0.ɵɵnextContext().$implicit;
802
939
  i0.ɵɵadvance();
803
- i0.ɵɵtextInterpolate1("", (day_r12.avgScore * 100).toFixed(1), "%");
940
+ i0.ɵɵtextInterpolate1("", (day_r17.avgScore * 100).toFixed(1), "%");
804
941
  } }
805
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_18_For_22_Template(rf, ctx) { if (rf & 1) {
806
- i0.ɵɵelementStart(0, "tr")(1, "td", 149);
942
+ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_For_22_Template(rf, ctx) { if (rf & 1) {
943
+ i0.ɵɵelementStart(0, "tr")(1, "td", 193);
807
944
  i0.ɵɵtext(2);
808
945
  i0.ɵɵpipe(3, "date");
809
946
  i0.ɵɵelementEnd();
810
- i0.ɵɵelementStart(4, "td", 150);
947
+ i0.ɵɵelementStart(4, "td", 194);
811
948
  i0.ɵɵtext(5);
812
949
  i0.ɵɵelementEnd();
813
- i0.ɵɵconditionalCreate(6, MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_18_For_22_Conditional_6_Template, 2, 1, "td", 151);
814
- i0.ɵɵconditionalCreate(7, MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_18_For_22_Conditional_7_Template, 2, 1, "td", 152);
815
- i0.ɵɵconditionalCreate(8, MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_18_For_22_Conditional_8_Template, 5, 3, "td", 153);
816
- i0.ɵɵconditionalCreate(9, MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_18_For_22_Conditional_9_Template, 2, 1, "td", 154);
817
- i0.ɵɵelementStart(10, "td", 155);
950
+ i0.ɵɵconditionalCreate(6, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_For_22_Conditional_6_Template, 2, 1, "td", 195);
951
+ i0.ɵɵconditionalCreate(7, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_For_22_Conditional_7_Template, 2, 1, "td", 196);
952
+ i0.ɵɵconditionalCreate(8, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_For_22_Conditional_8_Template, 5, 3, "td", 197);
953
+ i0.ɵɵconditionalCreate(9, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_For_22_Conditional_9_Template, 2, 1, "td", 198);
954
+ i0.ɵɵelementStart(10, "td", 199);
818
955
  i0.ɵɵtext(11);
819
956
  i0.ɵɵelementEnd();
820
- i0.ɵɵelementStart(12, "td", 156);
957
+ i0.ɵɵelementStart(12, "td", 200);
821
958
  i0.ɵɵtext(13);
822
959
  i0.ɵɵelementEnd()();
823
960
  } if (rf & 2) {
824
- const day_r12 = ctx.$implicit;
961
+ const day_r17 = ctx.$implicit;
825
962
  const ctx_r0 = i0.ɵɵnextContext(4);
826
963
  i0.ɵɵadvance(2);
827
- i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(3, 8, day_r12.date, "mediumDate"));
964
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(3, 8, day_r17.date, "mediumDate"));
828
965
  i0.ɵɵadvance(3);
829
- i0.ɵɵtextInterpolate(day_r12.runCount);
966
+ i0.ɵɵtextInterpolate(day_r17.runCount);
830
967
  i0.ɵɵadvance();
831
968
  i0.ɵɵconditional(ctx_r0.evalPreferences.showExecution ? 6 : -1);
832
969
  i0.ɵɵadvance();
@@ -836,25 +973,25 @@ function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_18
836
973
  i0.ɵɵadvance();
837
974
  i0.ɵɵconditional(ctx_r0.evalPreferences.showAuto ? 9 : -1);
838
975
  i0.ɵɵadvance(2);
839
- i0.ɵɵtextInterpolate(ctx_r0.formatDuration(day_r12.avgDuration));
976
+ i0.ɵɵtextInterpolate(ctx_r0.formatDuration(day_r17.avgDuration));
840
977
  i0.ɵɵadvance(2);
841
- i0.ɵɵtextInterpolate(ctx_r0.formatCost(day_r12.avgCost));
978
+ i0.ɵɵtextInterpolate(ctx_r0.formatCost(day_r17.avgCost));
842
979
  } }
843
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_18_Template(rf, ctx) { if (rf & 1) {
844
- i0.ɵɵelementStart(0, "div", 136)(1, "h3");
845
- i0.ɵɵelement(2, "i", 146);
980
+ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_Template(rf, ctx) { if (rf & 1) {
981
+ i0.ɵɵelementStart(0, "div", 180)(1, "h3");
982
+ i0.ɵɵelement(2, "i", 190);
846
983
  i0.ɵɵtext(3, " Daily Performance");
847
984
  i0.ɵɵelementEnd();
848
- i0.ɵɵelementStart(4, "div", 147)(5, "table", 148)(6, "thead")(7, "tr")(8, "th");
985
+ i0.ɵɵelementStart(4, "div", 191)(5, "table", 192)(6, "thead")(7, "tr")(8, "th");
849
986
  i0.ɵɵtext(9, "Date");
850
987
  i0.ɵɵelementEnd();
851
988
  i0.ɵɵelementStart(10, "th");
852
989
  i0.ɵɵtext(11, "Runs");
853
990
  i0.ɵɵelementEnd();
854
- i0.ɵɵconditionalCreate(12, MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_18_Conditional_12_Template, 2, 0, "th");
855
- i0.ɵɵconditionalCreate(13, MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_18_Conditional_13_Template, 2, 0, "th");
856
- i0.ɵɵconditionalCreate(14, MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_18_Conditional_14_Template, 2, 0, "th");
857
- i0.ɵɵconditionalCreate(15, MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_18_Conditional_15_Template, 2, 0, "th");
991
+ i0.ɵɵconditionalCreate(12, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_Conditional_12_Template, 2, 0, "th");
992
+ i0.ɵɵconditionalCreate(13, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_Conditional_13_Template, 2, 0, "th");
993
+ i0.ɵɵconditionalCreate(14, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_Conditional_14_Template, 2, 0, "th");
994
+ i0.ɵɵconditionalCreate(15, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_Conditional_15_Template, 2, 0, "th");
858
995
  i0.ɵɵelementStart(16, "th");
859
996
  i0.ɵɵtext(17, "Avg Duration");
860
997
  i0.ɵɵelementEnd();
@@ -862,7 +999,7 @@ function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_18
862
999
  i0.ɵɵtext(19, "Avg Cost");
863
1000
  i0.ɵɵelementEnd()()();
864
1001
  i0.ɵɵelementStart(20, "tbody");
865
- i0.ɵɵrepeaterCreate(21, MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_18_For_22_Template, 14, 11, "tr", null, i0.ɵɵrepeaterTrackByIdentity);
1002
+ i0.ɵɵrepeaterCreate(21, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_For_22_Template, 14, 11, "tr", null, i0.ɵɵrepeaterTrackByIdentity);
866
1003
  i0.ɵɵelementEnd()()()();
867
1004
  } if (rf & 2) {
868
1005
  const ctx_r0 = i0.ɵɵnextContext(3);
@@ -877,145 +1014,145 @@ function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_18
877
1014
  i0.ɵɵadvance(6);
878
1015
  i0.ɵɵrepeater(ctx_r0.historyData);
879
1016
  } }
880
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_19_For_6_Conditional_4_For_2_Template(rf, ctx) { if (rf & 1) {
881
- i0.ɵɵelementStart(0, "span", 171);
1017
+ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Conditional_4_For_2_Template(rf, ctx) { if (rf & 1) {
1018
+ i0.ɵɵelementStart(0, "span", 215);
882
1019
  i0.ɵɵtext(1);
883
1020
  i0.ɵɵelementEnd();
884
1021
  } if (rf & 2) {
885
- const tag_r15 = ctx.$implicit;
1022
+ const tag_r20 = ctx.$implicit;
886
1023
  i0.ɵɵadvance();
887
- i0.ɵɵtextInterpolate(tag_r15);
1024
+ i0.ɵɵtextInterpolate(tag_r20);
888
1025
  } }
889
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_19_For_6_Conditional_4_Conditional_3_Template(rf, ctx) { if (rf & 1) {
890
- i0.ɵɵelementStart(0, "span", 172);
1026
+ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Conditional_4_Conditional_3_Template(rf, ctx) { if (rf & 1) {
1027
+ i0.ɵɵelementStart(0, "span", 216);
891
1028
  i0.ɵɵtext(1);
892
1029
  i0.ɵɵelementEnd();
893
1030
  } if (rf & 2) {
894
- const suite_r14 = i0.ɵɵnextContext(2).$implicit;
1031
+ const suite_r19 = i0.ɵɵnextContext(2).$implicit;
895
1032
  i0.ɵɵadvance();
896
- i0.ɵɵtextInterpolate1("+", suite_r14.tags.length - 3);
1033
+ i0.ɵɵtextInterpolate1("+", suite_r19.tags.length - 3);
897
1034
  } }
898
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_19_For_6_Conditional_4_Template(rf, ctx) { if (rf & 1) {
899
- i0.ɵɵelementStart(0, "div", 165);
900
- i0.ɵɵrepeaterCreate(1, MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_19_For_6_Conditional_4_For_2_Template, 2, 1, "span", 171, i0.ɵɵrepeaterTrackByIdentity);
901
- i0.ɵɵconditionalCreate(3, MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_19_For_6_Conditional_4_Conditional_3_Template, 2, 1, "span", 172);
1035
+ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Conditional_4_Template(rf, ctx) { if (rf & 1) {
1036
+ i0.ɵɵelementStart(0, "div", 209);
1037
+ i0.ɵɵrepeaterCreate(1, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Conditional_4_For_2_Template, 2, 1, "span", 215, i0.ɵɵrepeaterTrackByIdentity);
1038
+ i0.ɵɵconditionalCreate(3, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Conditional_4_Conditional_3_Template, 2, 1, "span", 216);
902
1039
  i0.ɵɵelementEnd();
903
1040
  } if (rf & 2) {
904
- const suite_r14 = i0.ɵɵnextContext().$implicit;
1041
+ const suite_r19 = i0.ɵɵnextContext().$implicit;
905
1042
  i0.ɵɵadvance();
906
- i0.ɵɵrepeater(suite_r14.tags.slice(0, 3));
1043
+ i0.ɵɵrepeater(suite_r19.tags.slice(0, 3));
907
1044
  i0.ɵɵadvance(2);
908
- i0.ɵɵconditional(suite_r14.tags.length > 3 ? 3 : -1);
1045
+ i0.ɵɵconditional(suite_r19.tags.length > 3 ? 3 : -1);
909
1046
  } }
910
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_19_For_6_Conditional_11_Template(rf, ctx) { if (rf & 1) {
911
- i0.ɵɵelementStart(0, "div", 167)(1, "span", 173);
1047
+ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Conditional_11_Template(rf, ctx) { if (rf & 1) {
1048
+ i0.ɵɵelementStart(0, "div", 211)(1, "span", 217);
912
1049
  i0.ɵɵtext(2);
913
1050
  i0.ɵɵelementEnd();
914
- i0.ɵɵelementStart(3, "span", 169);
1051
+ i0.ɵɵelementStart(3, "span", 213);
915
1052
  i0.ɵɵtext(4, "Pass Rate");
916
1053
  i0.ɵɵelementEnd()();
917
1054
  } if (rf & 2) {
918
- const suite_r14 = i0.ɵɵnextContext().$implicit;
1055
+ const suite_r19 = i0.ɵɵnextContext().$implicit;
919
1056
  i0.ɵɵadvance();
920
- i0.ɵɵclassProp("high", suite_r14.passRate >= 80)("low", suite_r14.passRate < 50);
1057
+ i0.ɵɵclassProp("high", suite_r19.passRate >= 80)("low", suite_r19.passRate < 50);
921
1058
  i0.ɵɵadvance();
922
- i0.ɵɵtextInterpolate1(" ", suite_r14.passRate.toFixed(1), "% ");
1059
+ i0.ɵɵtextInterpolate1(" ", suite_r19.passRate.toFixed(1), "% ");
923
1060
  } }
924
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_19_For_6_Conditional_12_Template(rf, ctx) { if (rf & 1) {
925
- i0.ɵɵelementStart(0, "div", 167)(1, "span", 168);
1061
+ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Conditional_12_Template(rf, ctx) { if (rf & 1) {
1062
+ i0.ɵɵelementStart(0, "div", 211)(1, "span", 212);
926
1063
  i0.ɵɵtext(2);
927
1064
  i0.ɵɵelementEnd();
928
- i0.ɵɵelementStart(3, "span", 169);
1065
+ i0.ɵɵelementStart(3, "span", 213);
929
1066
  i0.ɵɵtext(4, "Avg Score");
930
1067
  i0.ɵɵelementEnd()();
931
1068
  } if (rf & 2) {
932
- const suite_r14 = i0.ɵɵnextContext().$implicit;
1069
+ const suite_r19 = i0.ɵɵnextContext().$implicit;
933
1070
  i0.ɵɵadvance(2);
934
- i0.ɵɵtextInterpolate1("", (suite_r14.avgScore * 100).toFixed(1), "%");
1071
+ i0.ɵɵtextInterpolate1("", (suite_r19.avgScore * 100).toFixed(1), "%");
935
1072
  } }
936
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_19_For_6_Conditional_23_Template(rf, ctx) { if (rf & 1) {
937
- i0.ɵɵelementStart(0, "div", 167)(1, "span", 168);
1073
+ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Conditional_23_Template(rf, ctx) { if (rf & 1) {
1074
+ i0.ɵɵelementStart(0, "div", 211)(1, "span", 212);
938
1075
  i0.ɵɵtext(2);
939
1076
  i0.ɵɵelementEnd();
940
- i0.ɵɵelementStart(3, "span", 169);
1077
+ i0.ɵɵelementStart(3, "span", 213);
941
1078
  i0.ɵɵtext(4, "Last Run");
942
1079
  i0.ɵɵelementEnd()();
943
1080
  } if (rf & 2) {
944
- const suite_r14 = i0.ɵɵnextContext().$implicit;
1081
+ const suite_r19 = i0.ɵɵnextContext().$implicit;
945
1082
  const ctx_r0 = i0.ɵɵnextContext(4);
946
1083
  i0.ɵɵadvance(2);
947
- i0.ɵɵtextInterpolate(ctx_r0.getRelativeTime(suite_r14.lastRun));
1084
+ i0.ɵɵtextInterpolate(ctx_r0.getRelativeTime(suite_r19.lastRun));
948
1085
  } }
949
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_19_For_6_Template(rf, ctx) { if (rf & 1) {
950
- const _r13 = i0.ɵɵgetCurrentView();
951
- i0.ɵɵelementStart(0, "div", 162);
952
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_19_For_6_Template_div_click_0_listener() { const suite_r14 = i0.ɵɵrestoreView(_r13).$implicit; const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.openSuiteFromHistory(suite_r14.suiteId)); });
953
- i0.ɵɵelementStart(1, "div", 163)(2, "div", 164);
1086
+ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Template(rf, ctx) { if (rf & 1) {
1087
+ const _r18 = i0.ɵɵgetCurrentView();
1088
+ i0.ɵɵelementStart(0, "div", 206);
1089
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Template_div_click_0_listener() { const suite_r19 = i0.ɵɵrestoreView(_r18).$implicit; const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.openSuiteFromHistory(suite_r19.suiteId)); });
1090
+ i0.ɵɵelementStart(1, "div", 207)(2, "div", 208);
954
1091
  i0.ɵɵtext(3);
955
1092
  i0.ɵɵelementEnd();
956
- i0.ɵɵconditionalCreate(4, MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_19_For_6_Conditional_4_Template, 4, 1, "div", 165);
1093
+ i0.ɵɵconditionalCreate(4, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Conditional_4_Template, 4, 1, "div", 209);
957
1094
  i0.ɵɵelementEnd();
958
- i0.ɵɵelementStart(5, "div", 166)(6, "div", 167)(7, "span", 168);
1095
+ i0.ɵɵelementStart(5, "div", 210)(6, "div", 211)(7, "span", 212);
959
1096
  i0.ɵɵtext(8);
960
1097
  i0.ɵɵelementEnd();
961
- i0.ɵɵelementStart(9, "span", 169);
1098
+ i0.ɵɵelementStart(9, "span", 213);
962
1099
  i0.ɵɵtext(10, "Runs");
963
1100
  i0.ɵɵelementEnd()();
964
- i0.ɵɵconditionalCreate(11, MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_19_For_6_Conditional_11_Template, 5, 5, "div", 167);
965
- i0.ɵɵconditionalCreate(12, MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_19_For_6_Conditional_12_Template, 5, 1, "div", 167);
966
- i0.ɵɵelementStart(13, "div", 167)(14, "span", 168);
1101
+ i0.ɵɵconditionalCreate(11, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Conditional_11_Template, 5, 5, "div", 211);
1102
+ i0.ɵɵconditionalCreate(12, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Conditional_12_Template, 5, 1, "div", 211);
1103
+ i0.ɵɵelementStart(13, "div", 211)(14, "span", 212);
967
1104
  i0.ɵɵtext(15);
968
1105
  i0.ɵɵelementEnd();
969
- i0.ɵɵelementStart(16, "span", 169);
1106
+ i0.ɵɵelementStart(16, "span", 213);
970
1107
  i0.ɵɵtext(17, "Avg Duration");
971
1108
  i0.ɵɵelementEnd()();
972
- i0.ɵɵelementStart(18, "div", 167)(19, "span", 168);
1109
+ i0.ɵɵelementStart(18, "div", 211)(19, "span", 212);
973
1110
  i0.ɵɵtext(20);
974
1111
  i0.ɵɵelementEnd();
975
- i0.ɵɵelementStart(21, "span", 169);
1112
+ i0.ɵɵelementStart(21, "span", 213);
976
1113
  i0.ɵɵtext(22, "Avg Cost");
977
1114
  i0.ɵɵelementEnd()();
978
- i0.ɵɵconditionalCreate(23, MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_19_For_6_Conditional_23_Template, 5, 1, "div", 167);
1115
+ i0.ɵɵconditionalCreate(23, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Conditional_23_Template, 5, 1, "div", 211);
979
1116
  i0.ɵɵelementEnd();
980
- i0.ɵɵelement(24, "i", 170);
1117
+ i0.ɵɵelement(24, "i", 214);
981
1118
  i0.ɵɵelementEnd();
982
1119
  } if (rf & 2) {
983
- const suite_r14 = ctx.$implicit;
1120
+ const suite_r19 = ctx.$implicit;
984
1121
  const ctx_r0 = i0.ɵɵnextContext(4);
985
1122
  i0.ɵɵadvance(3);
986
- i0.ɵɵtextInterpolate(suite_r14.suiteName);
1123
+ i0.ɵɵtextInterpolate(suite_r19.suiteName);
987
1124
  i0.ɵɵadvance();
988
- i0.ɵɵconditional(suite_r14.tags.length > 0 ? 4 : -1);
1125
+ i0.ɵɵconditional(suite_r19.tags.length > 0 ? 4 : -1);
989
1126
  i0.ɵɵadvance(4);
990
- i0.ɵɵtextInterpolate(suite_r14.totalRuns);
1127
+ i0.ɵɵtextInterpolate(suite_r19.totalRuns);
991
1128
  i0.ɵɵadvance(3);
992
1129
  i0.ɵɵconditional(ctx_r0.evalPreferences.showExecution ? 11 : -1);
993
1130
  i0.ɵɵadvance();
994
1131
  i0.ɵɵconditional(ctx_r0.evalPreferences.showAuto ? 12 : -1);
995
1132
  i0.ɵɵadvance(3);
996
- i0.ɵɵtextInterpolate(ctx_r0.formatDuration(suite_r14.avgDuration));
1133
+ i0.ɵɵtextInterpolate(ctx_r0.formatDuration(suite_r19.avgDuration));
997
1134
  i0.ɵɵadvance(5);
998
- i0.ɵɵtextInterpolate(ctx_r0.formatCost(suite_r14.avgCost));
1135
+ i0.ɵɵtextInterpolate(ctx_r0.formatCost(suite_r19.avgCost));
999
1136
  i0.ɵɵadvance(3);
1000
- i0.ɵɵconditional(suite_r14.lastRun ? 23 : -1);
1137
+ i0.ɵɵconditional(suite_r19.lastRun ? 23 : -1);
1001
1138
  } }
1002
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_19_Template(rf, ctx) { if (rf & 1) {
1003
- i0.ɵɵelementStart(0, "div", 136)(1, "h3");
1004
- i0.ɵɵelement(2, "i", 30);
1139
+ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_Template(rf, ctx) { if (rf & 1) {
1140
+ i0.ɵɵelementStart(0, "div", 180)(1, "h3");
1141
+ i0.ɵɵelement(2, "i", 33);
1005
1142
  i0.ɵɵtext(3, " Performance by Suite");
1006
1143
  i0.ɵɵelementEnd();
1007
- i0.ɵɵelementStart(4, "div", 160);
1008
- i0.ɵɵrepeaterCreate(5, MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_19_For_6_Template, 25, 8, "div", 161, i0.ɵɵrepeaterTrackByIdentity);
1144
+ i0.ɵɵelementStart(4, "div", 204);
1145
+ i0.ɵɵrepeaterCreate(5, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_For_6_Template, 25, 8, "div", 205, i0.ɵɵrepeaterTrackByIdentity);
1009
1146
  i0.ɵɵelementEnd()();
1010
1147
  } if (rf & 2) {
1011
1148
  const ctx_r0 = i0.ɵɵnextContext(3);
1012
1149
  i0.ɵɵadvance(5);
1013
1150
  i0.ɵɵrepeater(ctx_r0.suitePerformance);
1014
1151
  } }
1015
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_20_Template(rf, ctx) { if (rf & 1) {
1016
- const _r16 = i0.ɵɵgetCurrentView();
1017
- i0.ɵɵelementStart(0, "div", 81)(1, "div", 116);
1018
- i0.ɵɵelement(2, "i", 31);
1152
+ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_20_Template(rf, ctx) { if (rf & 1) {
1153
+ const _r21 = i0.ɵɵgetCurrentView();
1154
+ i0.ɵɵelementStart(0, "div", 125)(1, "div", 160);
1155
+ i0.ɵɵelement(2, "i", 34);
1019
1156
  i0.ɵɵelementEnd();
1020
1157
  i0.ɵɵelementStart(3, "h4");
1021
1158
  i0.ɵɵtext(4, "No History Available");
@@ -1023,42 +1160,42 @@ function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_20
1023
1160
  i0.ɵɵelementStart(5, "p");
1024
1161
  i0.ɵɵtext(6, "Run this test to start building history and analytics data.");
1025
1162
  i0.ɵɵelementEnd();
1026
- i0.ɵɵelementStart(7, "button", 18);
1027
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_20_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r16); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.runTest()); });
1028
- i0.ɵɵelement(8, "i", 19);
1163
+ i0.ɵɵelementStart(7, "button", 21);
1164
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_20_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r21); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.runTest()); });
1165
+ i0.ɵɵelement(8, "i", 22);
1029
1166
  i0.ɵɵtext(9, " Run Test Now ");
1030
1167
  i0.ɵɵelementEnd()();
1031
1168
  } }
1032
- function MJTestFormComponentExtended_Conditional_65_Conditional_2_Template(rf, ctx) { if (rf & 1) {
1033
- const _r11 = i0.ɵɵgetCurrentView();
1034
- i0.ɵɵelementStart(0, "div", 127)(1, "div", 129)(2, "div", 130)(3, "span", 131);
1169
+ function MJTestFormComponentExtended_Conditional_67_Conditional_2_Template(rf, ctx) { if (rf & 1) {
1170
+ const _r16 = i0.ɵɵgetCurrentView();
1171
+ i0.ɵɵelementStart(0, "div", 171)(1, "div", 173)(2, "div", 174)(3, "span", 175);
1035
1172
  i0.ɵɵtext(4, "Time Range:");
1036
1173
  i0.ɵɵelementEnd();
1037
- i0.ɵɵelementStart(5, "button", 132);
1038
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_65_Conditional_2_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r11); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setHistoryTimeRange("7d")); });
1174
+ i0.ɵɵelementStart(5, "button", 176);
1175
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_67_Conditional_2_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r16); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setHistoryTimeRange("7d")); });
1039
1176
  i0.ɵɵtext(6, "7 Days");
1040
1177
  i0.ɵɵelementEnd();
1041
- i0.ɵɵelementStart(7, "button", 132);
1042
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_65_Conditional_2_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r11); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setHistoryTimeRange("30d")); });
1178
+ i0.ɵɵelementStart(7, "button", 176);
1179
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_67_Conditional_2_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r16); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setHistoryTimeRange("30d")); });
1043
1180
  i0.ɵɵtext(8, "30 Days");
1044
1181
  i0.ɵɵelementEnd();
1045
- i0.ɵɵelementStart(9, "button", 132);
1046
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_65_Conditional_2_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r11); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setHistoryTimeRange("90d")); });
1182
+ i0.ɵɵelementStart(9, "button", 176);
1183
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_67_Conditional_2_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r16); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setHistoryTimeRange("90d")); });
1047
1184
  i0.ɵɵtext(10, "90 Days");
1048
1185
  i0.ɵɵelementEnd();
1049
- i0.ɵɵelementStart(11, "button", 132);
1050
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_65_Conditional_2_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r11); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setHistoryTimeRange("all")); });
1186
+ i0.ɵɵelementStart(11, "button", 176);
1187
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_67_Conditional_2_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r16); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setHistoryTimeRange("all")); });
1051
1188
  i0.ɵɵtext(12, "All Time");
1052
1189
  i0.ɵɵelementEnd()();
1053
- i0.ɵɵelementStart(13, "div", 133)(14, "button", 20);
1054
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_65_Conditional_2_Template_button_click_14_listener() { i0.ɵɵrestoreView(_r11); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.exportHistoryToCSV()); });
1055
- i0.ɵɵelement(15, "i", 134);
1190
+ i0.ɵɵelementStart(13, "div", 177)(14, "button", 23);
1191
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_67_Conditional_2_Template_button_click_14_listener() { i0.ɵɵrestoreView(_r16); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.exportHistoryToCSV()); });
1192
+ i0.ɵɵelement(15, "i", 178);
1056
1193
  i0.ɵɵtext(16, " Export CSV ");
1057
1194
  i0.ɵɵelementEnd()()();
1058
- i0.ɵɵconditionalCreate(17, MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_17_Template, 27, 5, "div", 135);
1059
- i0.ɵɵconditionalCreate(18, MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_18_Template, 23, 4, "div", 136);
1060
- i0.ɵɵconditionalCreate(19, MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_19_Template, 7, 0, "div", 136);
1061
- i0.ɵɵconditionalCreate(20, MJTestFormComponentExtended_Conditional_65_Conditional_2_Conditional_20_Template, 10, 0, "div", 81);
1195
+ i0.ɵɵconditionalCreate(17, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_17_Template, 27, 5, "div", 179);
1196
+ i0.ɵɵconditionalCreate(18, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_18_Template, 23, 4, "div", 180);
1197
+ i0.ɵɵconditionalCreate(19, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_19_Template, 7, 0, "div", 180);
1198
+ i0.ɵɵconditionalCreate(20, MJTestFormComponentExtended_Conditional_67_Conditional_2_Conditional_20_Template, 10, 0, "div", 125);
1062
1199
  i0.ɵɵelementEnd();
1063
1200
  } if (rf & 2) {
1064
1201
  const ctx_r0 = i0.ɵɵnextContext(2);
@@ -1081,10 +1218,10 @@ function MJTestFormComponentExtended_Conditional_65_Conditional_2_Template(rf, c
1081
1218
  i0.ɵɵadvance();
1082
1219
  i0.ɵɵconditional(ctx_r0.historyData.length === 0 ? 20 : -1);
1083
1220
  } }
1084
- function MJTestFormComponentExtended_Conditional_65_Template(rf, ctx) { if (rf & 1) {
1085
- i0.ɵɵelementStart(0, "div", 37);
1086
- i0.ɵɵconditionalCreate(1, MJTestFormComponentExtended_Conditional_65_Conditional_1_Template, 2, 0, "div", 79);
1087
- i0.ɵɵconditionalCreate(2, MJTestFormComponentExtended_Conditional_65_Conditional_2_Template, 21, 13, "div", 127);
1221
+ function MJTestFormComponentExtended_Conditional_67_Template(rf, ctx) { if (rf & 1) {
1222
+ i0.ɵɵelementStart(0, "div", 40);
1223
+ i0.ɵɵconditionalCreate(1, MJTestFormComponentExtended_Conditional_67_Conditional_1_Template, 2, 0, "div", 123);
1224
+ i0.ɵɵconditionalCreate(2, MJTestFormComponentExtended_Conditional_67_Conditional_2_Template, 21, 13, "div", 171);
1088
1225
  i0.ɵɵelementEnd();
1089
1226
  } if (rf & 2) {
1090
1227
  const ctx_r0 = i0.ɵɵnextContext();
@@ -1093,50 +1230,59 @@ function MJTestFormComponentExtended_Conditional_65_Template(rf, ctx) { if (rf &
1093
1230
  i0.ɵɵadvance();
1094
1231
  i0.ɵɵconditional(!ctx_r0.loadingHistory && ctx_r0.historyLoaded ? 2 : -1);
1095
1232
  } }
1096
- function MJTestFormComponentExtended_Conditional_68_Template(rf, ctx) { if (rf & 1) {
1097
- const _r17 = i0.ɵɵgetCurrentView();
1098
- i0.ɵɵelementStart(0, "div", 40)(1, "div", 174);
1099
- i0.ɵɵelement(2, "i", 39);
1233
+ function MJTestFormComponentExtended_Conditional_70_Template(rf, ctx) { if (rf & 1) {
1234
+ const _r22 = i0.ɵɵgetCurrentView();
1235
+ i0.ɵɵelementStart(0, "div", 43)(1, "div", 218);
1236
+ i0.ɵɵelement(2, "i", 42);
1100
1237
  i0.ɵɵtext(3, " Shortcuts ");
1101
- i0.ɵɵelementStart(4, "button", 175);
1102
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_68_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r17); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.toggleShortcuts()); });
1103
- i0.ɵɵelement(5, "i", 176);
1238
+ i0.ɵɵelementStart(4, "button", 219);
1239
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Conditional_70_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r22); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.toggleShortcuts()); });
1240
+ i0.ɵɵelement(5, "i", 122);
1104
1241
  i0.ɵɵelementEnd()();
1105
- i0.ɵɵelementStart(6, "div", 177)(7, "div", 178)(8, "span");
1106
- i0.ɵɵtext(9, "Refresh");
1242
+ i0.ɵɵelementStart(6, "div", 220)(7, "div", 221)(8, "span");
1243
+ i0.ɵɵtext(9, "Save changes");
1107
1244
  i0.ɵɵelementEnd();
1108
- i0.ɵɵelementStart(10, "span", 179)(11, "kbd");
1245
+ i0.ɵɵelementStart(10, "span", 222)(11, "kbd");
1109
1246
  i0.ɵɵtext(12, "Cmd");
1110
1247
  i0.ɵɵelementEnd();
1111
1248
  i0.ɵɵelementStart(13, "kbd");
1112
- i0.ɵɵtext(14, "R");
1249
+ i0.ɵɵtext(14, "S");
1113
1250
  i0.ɵɵelementEnd()()();
1114
- i0.ɵɵelementStart(15, "div", 178)(16, "span");
1115
- i0.ɵɵtext(17, "Run Test");
1251
+ i0.ɵɵelementStart(15, "div", 221)(16, "span");
1252
+ i0.ɵɵtext(17, "Refresh");
1116
1253
  i0.ɵɵelementEnd();
1117
- i0.ɵɵelementStart(18, "span", 179)(19, "kbd");
1254
+ i0.ɵɵelementStart(18, "span", 222)(19, "kbd");
1118
1255
  i0.ɵɵtext(20, "Cmd");
1119
1256
  i0.ɵɵelementEnd();
1120
1257
  i0.ɵɵelementStart(21, "kbd");
1121
- i0.ɵɵtext(22, "Enter");
1258
+ i0.ɵɵtext(22, "R");
1259
+ i0.ɵɵelementEnd()()();
1260
+ i0.ɵɵelementStart(23, "div", 221)(24, "span");
1261
+ i0.ɵɵtext(25, "Run Test");
1262
+ i0.ɵɵelementEnd();
1263
+ i0.ɵɵelementStart(26, "span", 222)(27, "kbd");
1264
+ i0.ɵɵtext(28, "Cmd");
1265
+ i0.ɵɵelementEnd();
1266
+ i0.ɵɵelementStart(29, "kbd");
1267
+ i0.ɵɵtext(30, "Enter");
1122
1268
  i0.ɵɵelementEnd()()();
1123
- i0.ɵɵelementStart(23, "div", 178)(24, "span");
1124
- i0.ɵɵtext(25, "Switch Tabs");
1269
+ i0.ɵɵelementStart(31, "div", 221)(32, "span");
1270
+ i0.ɵɵtext(33, "Switch Tabs");
1125
1271
  i0.ɵɵelementEnd();
1126
- i0.ɵɵelementStart(26, "span", 179)(27, "kbd");
1127
- i0.ɵɵtext(28, "1");
1272
+ i0.ɵɵelementStart(34, "span", 222)(35, "kbd");
1273
+ i0.ɵɵtext(36, "1");
1128
1274
  i0.ɵɵelementEnd();
1129
- i0.ɵɵtext(29, "-");
1130
- i0.ɵɵelementStart(30, "kbd");
1131
- i0.ɵɵtext(31, "5");
1275
+ i0.ɵɵtext(37, "-");
1276
+ i0.ɵɵelementStart(38, "kbd");
1277
+ i0.ɵɵtext(39, "5");
1132
1278
  i0.ɵɵelementEnd()()()()();
1133
1279
  } }
1134
- function MJTestFormComponentExtended_Conditional_69_Template(rf, ctx) { if (rf & 1) {
1135
- const _r18 = i0.ɵɵgetCurrentView();
1136
- i0.ɵɵelementStart(0, "mj-slide-panel", 180);
1137
- i0.ɵɵlistener("Closed", function MJTestFormComponentExtended_Conditional_69_Template_mj_slide_panel_Closed_0_listener() { i0.ɵɵrestoreView(_r18); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnPanelClosed()); });
1138
- i0.ɵɵelementStart(1, "app-test-run-dialog", 181);
1139
- i0.ɵɵlistener("PanelClose", function MJTestFormComponentExtended_Conditional_69_Template_app_test_run_dialog_PanelClose_1_listener() { i0.ɵɵrestoreView(_r18); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnPanelClosed()); });
1280
+ function MJTestFormComponentExtended_Conditional_71_Template(rf, ctx) { if (rf & 1) {
1281
+ const _r23 = i0.ɵɵgetCurrentView();
1282
+ i0.ɵɵelementStart(0, "mj-slide-panel", 223);
1283
+ i0.ɵɵlistener("Closed", function MJTestFormComponentExtended_Conditional_71_Template_mj_slide_panel_Closed_0_listener() { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnPanelClosed()); });
1284
+ i0.ɵɵelementStart(1, "app-test-run-dialog", 224);
1285
+ i0.ɵɵlistener("PanelClose", function MJTestFormComponentExtended_Conditional_71_Template_app_test_run_dialog_PanelClose_1_listener() { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnPanelClosed()); });
1140
1286
  i0.ɵɵelementEnd()();
1141
1287
  } if (rf & 2) {
1142
1288
  const ctx_r0 = i0.ɵɵnextContext();
@@ -1144,6 +1290,32 @@ function MJTestFormComponentExtended_Conditional_69_Template(rf, ctx) { if (rf &
1144
1290
  i0.ɵɵadvance();
1145
1291
  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");
1146
1292
  } }
1293
+ function MJTestFormComponentExtended_Conditional_80_Template(rf, ctx) { if (rf & 1) {
1294
+ i0.ɵɵtext(0);
1295
+ } if (rf & 2) {
1296
+ const ctx_r0 = i0.ɵɵnextContext();
1297
+ i0.ɵɵtextInterpolate1(" ", ctx_r0.dirtyFieldNames[0], " edited ");
1298
+ } }
1299
+ function MJTestFormComponentExtended_Conditional_81_Template(rf, ctx) { if (rf & 1) {
1300
+ i0.ɵɵtext(0);
1301
+ } if (rf & 2) {
1302
+ const ctx_r0 = i0.ɵɵnextContext();
1303
+ i0.ɵɵtextInterpolate1(" ", ctx_r0.dirtyFieldNames.length, " fields edited ");
1304
+ } }
1305
+ function MJTestFormComponentExtended_Conditional_84_Template(rf, ctx) { if (rf & 1) {
1306
+ i0.ɵɵelement(0, "i", 225);
1307
+ i0.ɵɵtext(1, " Saving\u2026 ");
1308
+ } }
1309
+ function MJTestFormComponentExtended_Conditional_85_Template(rf, ctx) { if (rf & 1) {
1310
+ i0.ɵɵelement(0, "i", 226);
1311
+ i0.ɵɵtext(1, " Save changes ");
1312
+ i0.ɵɵelementStart(2, "span", 227)(3, "kbd");
1313
+ i0.ɵɵtext(4, "\u2318");
1314
+ i0.ɵɵelementEnd();
1315
+ i0.ɵɵelementStart(5, "kbd");
1316
+ i0.ɵɵtext(6, "S");
1317
+ i0.ɵɵelementEnd()();
1318
+ } }
1147
1319
  /** Settings key for keyboard shortcuts visibility */
1148
1320
  const SHORTCUTS_SETTINGS_KEY = '__mj.Testing.ShowKeyboardShortcuts';
1149
1321
  let MJTestFormComponentExtended = class MJTestFormComponentExtended extends MJTestFormComponent {
@@ -1190,11 +1362,18 @@ let MJTestFormComponentExtended = class MJTestFormComponentExtended extends MJTe
1190
1362
  this.evalPrefsService = inject(EvaluationPreferencesService);
1191
1363
  this.viewContainerRef = inject(ViewContainerRef);
1192
1364
  this.appManager = inject(ApplicationManager);
1365
+ // Edit state
1366
+ this.isSaving = false;
1367
+ this.testTypeOptions = [];
1368
+ this.tagDraft = '';
1369
+ this.statusOptions = ['Active', 'Pending', 'Disabled'];
1193
1370
  }
1194
1371
  get metadata() { return this.ProviderToUse; }
1195
1372
  async ngOnInit() {
1196
1373
  await super.ngOnInit();
1197
1374
  this.loadShortcutsSetting();
1375
+ // Fire-and-forget: test type list for the edit form
1376
+ this.loadTestTypeOptions();
1198
1377
  // Subscribe to evaluation preferences
1199
1378
  this.evalPrefsService.preferences$
1200
1379
  .pipe(takeUntil(this.destroy$))
@@ -1220,6 +1399,14 @@ let MJTestFormComponentExtended = class MJTestFormComponentExtended extends MJTe
1220
1399
  handleKeyboardShortcut(event) {
1221
1400
  if (!this.keyboardShortcutsEnabled)
1222
1401
  return;
1402
+ // Cmd/Ctrl + S: Save (if dirty)
1403
+ if ((event.metaKey || event.ctrlKey) && event.key === 's' && !event.shiftKey) {
1404
+ if (this.isDirty) {
1405
+ event.preventDefault();
1406
+ this.saveChanges();
1407
+ }
1408
+ return;
1409
+ }
1223
1410
  // Cmd/Ctrl + R: Refresh
1224
1411
  if ((event.metaKey || event.ctrlKey) && event.key === 'r' && !event.shiftKey) {
1225
1412
  event.preventDefault();
@@ -1232,8 +1419,8 @@ let MJTestFormComponentExtended = class MJTestFormComponentExtended extends MJTe
1232
1419
  this.runTest();
1233
1420
  return;
1234
1421
  }
1235
- // Number keys for tabs (1-5)
1236
- if (!event.metaKey && !event.ctrlKey && !event.altKey) {
1422
+ // Number keys for tabs (1-5) — skip when typing into form inputs
1423
+ if (!event.metaKey && !event.ctrlKey && !event.altKey && !this.isTextInputFocused()) {
1237
1424
  switch (event.key) {
1238
1425
  case '1':
1239
1426
  this.changeTab('overview');
@@ -1253,6 +1440,20 @@ let MJTestFormComponentExtended = class MJTestFormComponentExtended extends MJTe
1253
1440
  }
1254
1441
  }
1255
1442
  }
1443
+ // Warn before tab close / hard navigation when there are unsaved changes
1444
+ handleBeforeUnload(event) {
1445
+ if (this.isDirty) {
1446
+ event.preventDefault();
1447
+ event.returnValue = '';
1448
+ }
1449
+ }
1450
+ isTextInputFocused() {
1451
+ const el = document.activeElement;
1452
+ if (!el)
1453
+ return false;
1454
+ const tag = el.tagName;
1455
+ return tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT' || el.isContentEditable;
1456
+ }
1256
1457
  async loadTestRuns() {
1257
1458
  if (this.testRunsLoaded)
1258
1459
  return;
@@ -1871,103 +2072,233 @@ let MJTestFormComponentExtended = class MJTestFormComponentExtended extends MJTe
1871
2072
  console.warn('Failed to save shortcuts setting:', error);
1872
2073
  }
1873
2074
  }
2075
+ // ==========================================
2076
+ // Edit / Save Methods
2077
+ // ==========================================
2078
+ /** True if the test record has any unsaved field changes. */
2079
+ get isDirty() {
2080
+ return this.record?.Dirty === true;
2081
+ }
2082
+ /** Names of fields with pending edits, used by the save bar. */
2083
+ get dirtyFieldNames() {
2084
+ if (!this.record?.Fields)
2085
+ return [];
2086
+ return this.record.Fields.filter(f => f.Dirty).map(f => f.Name);
2087
+ }
2088
+ /** Parsed tags as a plain array — derived from record.Tags JSON. */
2089
+ get tags() {
2090
+ return TagsHelper.parseTags(this.record?.Tags);
2091
+ }
2092
+ /** Load test types for the Type dropdown. */
2093
+ async loadTestTypeOptions() {
2094
+ try {
2095
+ const rv = RunView.FromMetadataProvider(this.ProviderToUse);
2096
+ const result = await rv.RunView({
2097
+ EntityName: 'MJ: Test Types',
2098
+ OrderBy: 'Name',
2099
+ ResultType: 'entity_object'
2100
+ });
2101
+ if (result.Success) {
2102
+ this.testTypeOptions = result.Results || [];
2103
+ this.cdr.markForCheck();
2104
+ }
2105
+ }
2106
+ catch (error) {
2107
+ console.warn('Failed to load test type options:', error);
2108
+ }
2109
+ }
2110
+ /** Save all pending changes on the test record. */
2111
+ async saveChanges() {
2112
+ if (!this.isDirty || this.isSaving)
2113
+ return;
2114
+ this.isSaving = true;
2115
+ this.cdr.markForCheck();
2116
+ try {
2117
+ const ok = await this.SaveRecord(false);
2118
+ if (ok) {
2119
+ SharedService.Instance.CreateSimpleNotification('Test saved', 'success', 2000);
2120
+ // Re-parse JSON fields since editor content may have changed
2121
+ this.parseJsonFields();
2122
+ }
2123
+ else {
2124
+ const detail = this.record?.LatestResult?.CompleteMessage || this.record?.LatestResult?.Message || 'Save failed';
2125
+ SharedService.Instance.CreateSimpleNotification(detail, 'error', 4000);
2126
+ }
2127
+ }
2128
+ catch (err) {
2129
+ const msg = err instanceof Error ? err.message : 'Save failed';
2130
+ SharedService.Instance.CreateSimpleNotification(msg, 'error', 4000);
2131
+ }
2132
+ finally {
2133
+ this.isSaving = false;
2134
+ this.cdr.markForCheck();
2135
+ }
2136
+ }
2137
+ /** Discard all pending field changes on the test. */
2138
+ discardChanges() {
2139
+ if (!this.isDirty)
2140
+ return;
2141
+ if (!confirm('Discard your unsaved changes?'))
2142
+ return;
2143
+ this.record.Revert();
2144
+ this.tagDraft = '';
2145
+ this.parseJsonFields();
2146
+ this.cdr.markForCheck();
2147
+ }
2148
+ /** Add a tag from tagDraft (called on Enter / comma / blur). */
2149
+ addTagFromDraft() {
2150
+ const raw = this.tagDraft.trim();
2151
+ if (!raw)
2152
+ return;
2153
+ const incoming = raw.split(',').map(t => t.trim()).filter(t => t.length > 0);
2154
+ const existing = this.tags;
2155
+ const merged = [...existing];
2156
+ for (const t of incoming) {
2157
+ if (!merged.includes(t))
2158
+ merged.push(t);
2159
+ }
2160
+ this.record.Tags = TagsHelper.toJson(merged);
2161
+ this.tagDraft = '';
2162
+ this.cdr.markForCheck();
2163
+ }
2164
+ /** Remove a single tag. */
2165
+ removeTag(tag) {
2166
+ this.record.Tags = TagsHelper.removeTag(this.record.Tags, tag);
2167
+ this.cdr.markForCheck();
2168
+ }
2169
+ /** Handle Enter / comma in the tag input to commit the draft tag. */
2170
+ onTagInputKeydown(event) {
2171
+ if (event.key === 'Enter' || event.key === ',') {
2172
+ event.preventDefault();
2173
+ this.addTagFromDraft();
2174
+ return;
2175
+ }
2176
+ if (event.key === 'Backspace' && !this.tagDraft) {
2177
+ const all = this.tags;
2178
+ if (all.length > 0) {
2179
+ event.preventDefault();
2180
+ this.removeTag(all[all.length - 1]);
2181
+ }
2182
+ }
2183
+ }
1874
2184
  static { this.ɵfac = /*@__PURE__*/ (() => { let ɵMJTestFormComponentExtended_BaseFactory; return function MJTestFormComponentExtended_Factory(__ngFactoryType__) { return (ɵMJTestFormComponentExtended_BaseFactory || (ɵMJTestFormComponentExtended_BaseFactory = i0.ɵɵgetInheritedFactory(MJTestFormComponentExtended)))(__ngFactoryType__ || MJTestFormComponentExtended); }; })(); }
1875
2185
  static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJTestFormComponentExtended, selectors: [["mj-test-form"]], hostBindings: function MJTestFormComponentExtended_HostBindings(rf, ctx) { if (rf & 1) {
1876
- i0.ɵɵlistener("keydown", function MJTestFormComponentExtended_keydown_HostBindingHandler($event) { return ctx.handleKeyboardShortcut($event); }, i0.ɵɵresolveDocument);
1877
- } }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 70, vars: 38, consts: [[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"], [1, "test-meta"], [1, "status-badge", 3, "ngClass"], [1, "fas", 3, "ngClass"], [1, "test-type"], [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"], [1, "fas", "fa-tag"], [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, "config-section"], [1, "fas", "fa-cogs"], [1, "config-grid"], [1, "config-item"], ["type", "number", "placeholder", "Lower = Higher Priority", 1, "config-input", 3, "ngModelChange", "ngModel"], ["type", "number", "min", "1", 1, "config-input", 3, "ngModelChange", "ngModel"], ["type", "number", 1, "config-input", 3, "ngModelChange", "ngModel"], ["type", "number", "step", "0.000001", 1, "config-input", 3, "ngModelChange", "ngModel"], [1, "config-item", "full-width"], ["type", "number", "placeholder", "Default: 300000 (5 min)", 1, "config-input", 3, "ngModelChange", "ngModel"], [1, "config-hint"], [1, "config-editor-container"], ["language", "json", 3, "change", "value", "readonly", "lineWrapping"], [1, "config-editor-container", "small"], [1, "loading-state"], [1, "runs-list"], [1, "empty-state"], [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"], [1, "empty-icon"], [1, "fas", "fa-play-circle"], [1, "suites-list"], [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, "fas", "fa-folder-open"], [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"], [1, "kpi-card"], [1, "kpi-icon"], [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"], [1, "shortcuts-header"], ["title", "Hide shortcuts", 1, "shortcuts-close", 3, "click"], [1, "fas", "fa-times"], [1, "shortcut-list"], [1, "shortcut-item"], [1, "shortcut-keys"], ["Mode", "slide", 3, "Closed", "Title", "Resizable"], [3, "PanelClose", "PanelMode", "selectedTestId", "selectedSuiteId", "runMode"]], template: function MJTestFormComponentExtended_Template(rf, ctx) { if (rf & 1) {
1878
- i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "nav", 2)(3, "ol")(4, "li")(5, "a", 3);
2186
+ 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);
2187
+ } }, 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-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"], [1, "empty-state"], [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"], [1, "empty-icon"], [1, "fas", "fa-play-circle"], [1, "suites-list"], [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, "fas", "fa-folder-open"], [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"], [1, "kpi-card"], [1, "kpi-icon"], [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"], [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) {
2188
+ i0.ɵɵelementStart(0, "div", 1)(1, "div", 2)(2, "nav", 3)(3, "ol")(4, "li")(5, "a", 4);
1879
2189
  i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_a_click_5_listener() { return ctx.navigateToTestingDashboard(); });
1880
- i0.ɵɵelement(6, "i", 4);
1881
- i0.ɵɵelementStart(7, "span", 5);
2190
+ i0.ɵɵelement(6, "i", 5);
2191
+ i0.ɵɵelementStart(7, "span", 6);
1882
2192
  i0.ɵɵtext(8, "Testing");
1883
2193
  i0.ɵɵelementEnd()()();
1884
- i0.ɵɵelementStart(9, "li", 6);
1885
- i0.ɵɵelement(10, "i", 7)(11, "i", 8);
2194
+ i0.ɵɵelementStart(9, "li", 7);
2195
+ i0.ɵɵelement(10, "i", 8)(11, "i", 9);
1886
2196
  i0.ɵɵelementStart(12, "span");
1887
2197
  i0.ɵɵtext(13);
1888
2198
  i0.ɵɵelementEnd()()()();
1889
- i0.ɵɵelementStart(14, "div", 9)(15, "div", 10)(16, "div", 11);
1890
- i0.ɵɵelement(17, "i", 8);
2199
+ i0.ɵɵelementStart(14, "div", 10)(15, "div", 11)(16, "div", 12);
2200
+ i0.ɵɵelement(17, "i", 9);
1891
2201
  i0.ɵɵelementEnd();
1892
- i0.ɵɵelementStart(18, "div", 12)(19, "h1");
2202
+ i0.ɵɵelementStart(18, "div", 13)(19, "h1");
1893
2203
  i0.ɵɵtext(20);
2204
+ i0.ɵɵconditionalCreate(21, MJTestFormComponentExtended_Conditional_21_Template, 2, 0, "span", 14);
1894
2205
  i0.ɵɵelementEnd();
1895
- i0.ɵɵelementStart(21, "div", 13)(22, "span", 14);
1896
- i0.ɵɵelement(23, "i", 15);
1897
- i0.ɵɵtext(24);
2206
+ i0.ɵɵelementStart(22, "div", 15)(23, "span", 16);
2207
+ i0.ɵɵelement(24, "i", 17);
2208
+ i0.ɵɵtext(25);
1898
2209
  i0.ɵɵelementEnd();
1899
- i0.ɵɵconditionalCreate(25, MJTestFormComponentExtended_Conditional_25_Template, 3, 1, "span", 16);
2210
+ i0.ɵɵconditionalCreate(26, MJTestFormComponentExtended_Conditional_26_Template, 3, 1, "span", 18);
2211
+ i0.ɵɵconditionalCreate(27, MJTestFormComponentExtended_Conditional_27_Template, 3, 0, "span", 19);
1900
2212
  i0.ɵɵelementEnd()()();
1901
- i0.ɵɵelementStart(26, "div", 17);
1902
- i0.ɵɵelement(27, "app-evaluation-mode-toggle");
1903
- i0.ɵɵelementStart(28, "button", 18);
1904
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_28_listener() { return ctx.runTest(); });
1905
- i0.ɵɵelement(29, "i", 19);
1906
- i0.ɵɵtext(30, " Run Test ");
2213
+ i0.ɵɵelementStart(28, "div", 20);
2214
+ i0.ɵɵelement(29, "app-evaluation-mode-toggle");
2215
+ i0.ɵɵelementStart(30, "button", 21);
2216
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_30_listener() { return ctx.runTest(); });
2217
+ i0.ɵɵelement(31, "i", 22);
2218
+ i0.ɵɵtext(32, " Run Test ");
1907
2219
  i0.ɵɵelementEnd();
1908
- i0.ɵɵelementStart(31, "button", 20);
1909
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_31_listener() { return ctx.refresh(); });
1910
- i0.ɵɵelement(32, "i", 15);
1911
- i0.ɵɵtext(33);
2220
+ i0.ɵɵelementStart(33, "button", 23);
2221
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_33_listener() { return ctx.refresh(); });
2222
+ i0.ɵɵelement(34, "i", 17);
2223
+ i0.ɵɵtext(35);
1912
2224
  i0.ɵɵelementEnd()()();
1913
- i0.ɵɵconditionalCreate(34, MJTestFormComponentExtended_Conditional_34_Template, 3, 1, "div", 21);
1914
- i0.ɵɵconditionalCreate(35, MJTestFormComponentExtended_Conditional_35_Template, 23, 6, "div", 22);
2225
+ i0.ɵɵconditionalCreate(36, MJTestFormComponentExtended_Conditional_36_Template, 3, 1, "div", 24);
2226
+ i0.ɵɵconditionalCreate(37, MJTestFormComponentExtended_Conditional_37_Template, 23, 6, "div", 25);
1915
2227
  i0.ɵɵelementEnd();
1916
- i0.ɵɵelementStart(36, "div", 23)(37, "div", 24)(38, "button", 25);
1917
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_38_listener() { return ctx.changeTab("overview"); });
1918
- i0.ɵɵelement(39, "i", 26);
1919
- i0.ɵɵelementStart(40, "span");
1920
- i0.ɵɵtext(41, "Overview");
2228
+ i0.ɵɵelementStart(38, "div", 26)(39, "div", 27)(40, "button", 28);
2229
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_40_listener() { return ctx.changeTab("overview"); });
2230
+ i0.ɵɵelement(41, "i", 29);
2231
+ i0.ɵɵelementStart(42, "span");
2232
+ i0.ɵɵtext(43, "Overview");
1921
2233
  i0.ɵɵelementEnd()();
1922
- i0.ɵɵelementStart(42, "button", 25);
1923
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_42_listener() { return ctx.changeTab("config"); });
1924
- i0.ɵɵelement(43, "i", 27);
1925
- i0.ɵɵelementStart(44, "span");
1926
- i0.ɵɵtext(45, "Configuration");
2234
+ i0.ɵɵelementStart(44, "button", 28);
2235
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_44_listener() { return ctx.changeTab("config"); });
2236
+ i0.ɵɵelement(45, "i", 30);
2237
+ i0.ɵɵelementStart(46, "span");
2238
+ i0.ɵɵtext(47, "Configuration");
1927
2239
  i0.ɵɵelementEnd()();
1928
- i0.ɵɵelementStart(46, "button", 25);
1929
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_46_listener() { return ctx.changeTab("runs"); });
1930
- i0.ɵɵelement(47, "i", 28);
1931
- i0.ɵɵelementStart(48, "span");
1932
- i0.ɵɵtext(49, "Runs");
2240
+ i0.ɵɵelementStart(48, "button", 28);
2241
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_48_listener() { return ctx.changeTab("runs"); });
2242
+ i0.ɵɵelement(49, "i", 31);
2243
+ i0.ɵɵelementStart(50, "span");
2244
+ i0.ɵɵtext(51, "Runs");
1933
2245
  i0.ɵɵelementEnd();
1934
- i0.ɵɵconditionalCreate(50, MJTestFormComponentExtended_Conditional_50_Template, 2, 1, "span", 29);
2246
+ i0.ɵɵconditionalCreate(52, MJTestFormComponentExtended_Conditional_52_Template, 2, 1, "span", 32);
1935
2247
  i0.ɵɵelementEnd();
1936
- i0.ɵɵelementStart(51, "button", 25);
1937
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_51_listener() { return ctx.changeTab("suites"); });
1938
- i0.ɵɵelement(52, "i", 30);
1939
- i0.ɵɵelementStart(53, "span");
1940
- i0.ɵɵtext(54, "Test Suites");
2248
+ i0.ɵɵelementStart(53, "button", 28);
2249
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_53_listener() { return ctx.changeTab("suites"); });
2250
+ i0.ɵɵelement(54, "i", 33);
2251
+ i0.ɵɵelementStart(55, "span");
2252
+ i0.ɵɵtext(56, "Test Suites");
1941
2253
  i0.ɵɵelementEnd();
1942
- i0.ɵɵconditionalCreate(55, MJTestFormComponentExtended_Conditional_55_Template, 2, 1, "span", 29);
2254
+ i0.ɵɵconditionalCreate(57, MJTestFormComponentExtended_Conditional_57_Template, 2, 1, "span", 32);
1943
2255
  i0.ɵɵelementEnd();
1944
- i0.ɵɵelementStart(56, "button", 25);
1945
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_56_listener() { return ctx.changeTab("analytics"); });
1946
- i0.ɵɵelement(57, "i", 31);
1947
- i0.ɵɵelementStart(58, "span");
1948
- i0.ɵɵtext(59, "Analytics");
2256
+ i0.ɵɵelementStart(58, "button", 28);
2257
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_58_listener() { return ctx.changeTab("analytics"); });
2258
+ i0.ɵɵelement(59, "i", 34);
2259
+ i0.ɵɵelementStart(60, "span");
2260
+ i0.ɵɵtext(61, "Analytics");
1949
2261
  i0.ɵɵelementEnd()()()();
1950
- i0.ɵɵelementStart(60, "div", 32);
1951
- i0.ɵɵconditionalCreate(61, MJTestFormComponentExtended_Conditional_61_Template, 78, 29, "div", 33);
1952
- i0.ɵɵconditionalCreate(62, MJTestFormComponentExtended_Conditional_62_Template, 52, 17, "div", 34);
1953
- i0.ɵɵconditionalCreate(63, MJTestFormComponentExtended_Conditional_63_Template, 4, 3, "div", 35);
1954
- i0.ɵɵconditionalCreate(64, MJTestFormComponentExtended_Conditional_64_Template, 4, 3, "div", 36);
1955
- i0.ɵɵconditionalCreate(65, MJTestFormComponentExtended_Conditional_65_Template, 3, 2, "div", 37);
2262
+ i0.ɵɵelementStart(62, "div", 35);
2263
+ i0.ɵɵconditionalCreate(63, MJTestFormComponentExtended_Conditional_63_Template, 78, 29, "div", 36);
2264
+ i0.ɵɵconditionalCreate(64, MJTestFormComponentExtended_Conditional_64_Template, 111, 30, "div", 37);
2265
+ i0.ɵɵconditionalCreate(65, MJTestFormComponentExtended_Conditional_65_Template, 4, 3, "div", 38);
2266
+ i0.ɵɵconditionalCreate(66, MJTestFormComponentExtended_Conditional_66_Template, 4, 3, "div", 39);
2267
+ i0.ɵɵconditionalCreate(67, MJTestFormComponentExtended_Conditional_67_Template, 3, 2, "div", 40);
2268
+ i0.ɵɵelementEnd();
2269
+ i0.ɵɵelementStart(68, "button", 41);
2270
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_68_listener() { return ctx.toggleShortcuts(); });
2271
+ i0.ɵɵelement(69, "i", 42);
1956
2272
  i0.ɵɵelementEnd();
1957
- i0.ɵɵelementStart(66, "button", 38);
1958
- i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_66_listener() { return ctx.toggleShortcuts(); });
1959
- i0.ɵɵelement(67, "i", 39);
2273
+ i0.ɵɵconditionalCreate(70, MJTestFormComponentExtended_Conditional_70_Template, 40, 0, "div", 43);
2274
+ i0.ɵɵconditionalCreate(71, MJTestFormComponentExtended_Conditional_71_Template, 2, 6, "mj-slide-panel", 44);
2275
+ i0.ɵɵelementStart(72, "div", 45)(73, "div", 46)(74, "span", 47);
2276
+ i0.ɵɵtext(75, "\u25CF");
1960
2277
  i0.ɵɵelementEnd();
1961
- i0.ɵɵconditionalCreate(68, MJTestFormComponentExtended_Conditional_68_Template, 32, 0, "div", 40);
1962
- i0.ɵɵconditionalCreate(69, MJTestFormComponentExtended_Conditional_69_Template, 2, 6, "mj-slide-panel", 41);
2278
+ i0.ɵɵelementStart(76, "span", 48)(77, "strong");
2279
+ i0.ɵɵtext(78, "Unsaved changes");
1963
2280
  i0.ɵɵelementEnd();
2281
+ i0.ɵɵelementStart(79, "span", 49);
2282
+ i0.ɵɵconditionalCreate(80, MJTestFormComponentExtended_Conditional_80_Template, 1, 1)(81, MJTestFormComponentExtended_Conditional_81_Template, 1, 1);
2283
+ i0.ɵɵelementEnd()()();
2284
+ i0.ɵɵelementStart(82, "div", 50)(83, "button", 51);
2285
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_83_listener() { return ctx.saveChanges(); });
2286
+ i0.ɵɵconditionalCreate(84, MJTestFormComponentExtended_Conditional_84_Template, 2, 0)(85, MJTestFormComponentExtended_Conditional_85_Template, 7, 0);
2287
+ i0.ɵɵelementEnd();
2288
+ i0.ɵɵelementStart(86, "button", 52);
2289
+ i0.ɵɵlistener("click", function MJTestFormComponentExtended_Template_button_click_86_listener() { return ctx.discardChanges(); });
2290
+ i0.ɵɵelement(87, "i", 53);
2291
+ i0.ɵɵtext(88, " Discard ");
2292
+ i0.ɵɵelementEnd()()()();
1964
2293
  } if (rf & 2) {
1965
2294
  i0.ɵɵadvance(13);
1966
2295
  i0.ɵɵtextInterpolate(ctx.record.Name);
1967
2296
  i0.ɵɵadvance(3);
1968
2297
  i0.ɵɵstyleProp("background-color", ctx.getStatusColor());
1969
2298
  i0.ɵɵadvance(4);
1970
- i0.ɵɵtextInterpolate(ctx.record.Name);
2299
+ i0.ɵɵtextInterpolate1(" ", ctx.record.Name, " ");
2300
+ i0.ɵɵadvance();
2301
+ i0.ɵɵconditional(ctx.isDirty ? 21 : -1);
1971
2302
  i0.ɵɵadvance(2);
1972
2303
  i0.ɵɵproperty("ngClass", ctx.getStatusClass());
1973
2304
  i0.ɵɵadvance();
@@ -1975,7 +2306,9 @@ let MJTestFormComponentExtended = class MJTestFormComponentExtended extends MJTe
1975
2306
  i0.ɵɵadvance();
1976
2307
  i0.ɵɵtextInterpolate1(" ", ctx.record.Status, " ");
1977
2308
  i0.ɵɵadvance();
1978
- i0.ɵɵconditional(ctx.record.Type ? 25 : -1);
2309
+ i0.ɵɵconditional(ctx.record.Type ? 26 : -1);
2310
+ i0.ɵɵadvance();
2311
+ i0.ɵɵconditional(ctx.isDirty ? 27 : -1);
1979
2312
  i0.ɵɵadvance(6);
1980
2313
  i0.ɵɵproperty("disabled", ctx.isRefreshing);
1981
2314
  i0.ɵɵadvance();
@@ -1983,9 +2316,9 @@ let MJTestFormComponentExtended = class MJTestFormComponentExtended extends MJTe
1983
2316
  i0.ɵɵadvance();
1984
2317
  i0.ɵɵtextInterpolate1(" ", ctx.isRefreshing ? "Refreshing..." : "Refresh", " ");
1985
2318
  i0.ɵɵadvance();
1986
- i0.ɵɵconditional(ctx.record.Description ? 34 : -1);
2319
+ i0.ɵɵconditional(ctx.record.Description ? 36 : -1);
1987
2320
  i0.ɵɵadvance();
1988
- i0.ɵɵconditional(ctx.testRunsLoaded && ctx.testRuns.length > 0 ? 35 : -1);
2321
+ i0.ɵɵconditional(ctx.testRunsLoaded && ctx.testRuns.length > 0 ? 37 : -1);
1989
2322
  i0.ɵɵadvance(3);
1990
2323
  i0.ɵɵclassProp("active", ctx.activeTab === "overview");
1991
2324
  i0.ɵɵattribute("aria-selected", ctx.activeTab === "overview");
@@ -1996,32 +2329,47 @@ let MJTestFormComponentExtended = class MJTestFormComponentExtended extends MJTe
1996
2329
  i0.ɵɵclassProp("active", ctx.activeTab === "runs");
1997
2330
  i0.ɵɵattribute("aria-selected", ctx.activeTab === "runs");
1998
2331
  i0.ɵɵadvance(4);
1999
- i0.ɵɵconditional(ctx.testRunsLoaded ? 50 : -1);
2332
+ i0.ɵɵconditional(ctx.testRunsLoaded ? 52 : -1);
2000
2333
  i0.ɵɵadvance();
2001
2334
  i0.ɵɵclassProp("active", ctx.activeTab === "suites");
2002
2335
  i0.ɵɵattribute("aria-selected", ctx.activeTab === "suites");
2003
2336
  i0.ɵɵadvance(4);
2004
- i0.ɵɵconditional(ctx.suiteTestsLoaded ? 55 : -1);
2337
+ i0.ɵɵconditional(ctx.suiteTestsLoaded ? 57 : -1);
2005
2338
  i0.ɵɵadvance();
2006
2339
  i0.ɵɵclassProp("active", ctx.activeTab === "analytics");
2007
2340
  i0.ɵɵattribute("aria-selected", ctx.activeTab === "analytics");
2008
- i0.ɵɵadvance(5);
2009
- i0.ɵɵconditional(ctx.activeTab === "overview" ? 61 : -1);
2341
+ i0.ɵɵadvance(4);
2342
+ i0.ɵɵclassProp("has-savebar", ctx.isDirty);
2010
2343
  i0.ɵɵadvance();
2011
- i0.ɵɵconditional(ctx.activeTab === "config" ? 62 : -1);
2344
+ i0.ɵɵconditional(ctx.activeTab === "overview" ? 63 : -1);
2012
2345
  i0.ɵɵadvance();
2013
- i0.ɵɵconditional(ctx.activeTab === "runs" ? 63 : -1);
2346
+ i0.ɵɵconditional(ctx.activeTab === "config" ? 64 : -1);
2014
2347
  i0.ɵɵadvance();
2015
- i0.ɵɵconditional(ctx.activeTab === "suites" ? 64 : -1);
2348
+ i0.ɵɵconditional(ctx.activeTab === "runs" ? 65 : -1);
2016
2349
  i0.ɵɵadvance();
2017
- i0.ɵɵconditional(ctx.activeTab === "analytics" ? 65 : -1);
2350
+ i0.ɵɵconditional(ctx.activeTab === "suites" ? 66 : -1);
2351
+ i0.ɵɵadvance();
2352
+ i0.ɵɵconditional(ctx.activeTab === "analytics" ? 67 : -1);
2018
2353
  i0.ɵɵadvance();
2019
2354
  i0.ɵɵproperty("title", ctx.showShortcuts ? "Hide keyboard shortcuts" : "Show keyboard shortcuts");
2020
2355
  i0.ɵɵadvance(2);
2021
- i0.ɵɵconditional(ctx.showShortcuts ? 68 : -1);
2356
+ i0.ɵɵconditional(ctx.showShortcuts ? 70 : -1);
2357
+ i0.ɵɵadvance();
2358
+ i0.ɵɵconditional(ctx.testingDialogService.IsPanelOpen ? 71 : -1);
2022
2359
  i0.ɵɵadvance();
2023
- i0.ɵɵconditional(ctx.testingDialogService.IsPanelOpen ? 69 : -1);
2024
- } }, dependencies: [i1.NgClass, i2.DefaultValueAccessor, i2.NumberValueAccessor, i2.NgControlStatus, i2.MinValidator, i2.NgModel, i3.MJButtonDirective, i4.CodeEditorComponent, i5.TestRunDialogComponent, i5.EvaluationModeToggleComponent, i6.LoadingComponent, i7.MjSlidePanelComponent, i8.EntityLinkPillComponent, i1.DatePipe], styles: ["\n\n\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\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\n.test-form[_ngcontent-%COMP%] {\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\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\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\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\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\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\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\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\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\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\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\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\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\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\n.runs-tab[_ngcontent-%COMP%], \n.suites-tab[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\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\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\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\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\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\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\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\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.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 24px;\n text-align: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n margin-bottom: 20px;\n}\n\n.empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 36px;\n color: var(--test-text-muted);\n}\n\n.empty-state[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: 14px;\n color: var(--test-text-secondary);\n max-width: 300px;\n}\n\n\n\n.no-data[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n color: var(--test-text-muted);\n text-align: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n}\n\n.no-data[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 48px;\n margin-bottom: 16px;\n opacity: 0.3;\n}\n\n.no-data[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n}\n\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\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\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 .empty-state[_ngcontent-%COMP%] {\n padding: 40px 20px;\n }\n\n .empty-icon[_ngcontent-%COMP%] {\n width: 64px;\n height: 64px;\n }\n\n .empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 28px;\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\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\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\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\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\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\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\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\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\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\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 .empty-state[_ngcontent-%COMP%] {\n break-inside: avoid;\n box-shadow: none;\n border: 1px solid var(--mj-border-default);\n }\n}"], changeDetection: 0 }); }
2360
+ i0.ɵɵclassProp("save-bar--visible", ctx.isDirty);
2361
+ i0.ɵɵattribute("aria-hidden", !ctx.isDirty);
2362
+ i0.ɵɵadvance(8);
2363
+ i0.ɵɵconditional(ctx.dirtyFieldNames.length === 1 ? 80 : ctx.dirtyFieldNames.length > 1 ? 81 : -1);
2364
+ i0.ɵɵadvance(3);
2365
+ i0.ɵɵproperty("disabled", ctx.isSaving || !ctx.isDirty);
2366
+ i0.ɵɵattribute("tabindex", ctx.isDirty ? 0 : -1);
2367
+ i0.ɵɵadvance();
2368
+ i0.ɵɵconditional(ctx.isSaving ? 84 : 85);
2369
+ i0.ɵɵadvance(2);
2370
+ i0.ɵɵproperty("disabled", ctx.isSaving || !ctx.isDirty);
2371
+ i0.ɵɵattribute("tabindex", ctx.isDirty ? 0 : -1);
2372
+ } }, dependencies: [i1.NgClass, i2.NgSelectOption, i2.ɵNgSelectMultipleOption, i2.DefaultValueAccessor, i2.NumberValueAccessor, i2.SelectControlValueAccessor, i2.NgControlStatus, i2.MinValidator, i2.NgModel, i3.MJButtonDirective, i4.CodeEditorComponent, i5.TestRunDialogComponent, i5.EvaluationModeToggleComponent, i6.LoadingComponent, i7.MjSlidePanelComponent, i8.EntityLinkPillComponent, i1.DatePipe], styles: ["\n\n\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\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\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\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\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\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\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\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\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\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\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\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\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\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\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\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\n.runs-tab[_ngcontent-%COMP%], \n.suites-tab[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\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\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\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\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\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\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\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\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.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 24px;\n text-align: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n margin-bottom: 20px;\n}\n\n.empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 36px;\n color: var(--test-text-muted);\n}\n\n.empty-state[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: 14px;\n color: var(--test-text-secondary);\n max-width: 300px;\n}\n\n\n\n.no-data[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n color: var(--test-text-muted);\n text-align: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n}\n\n.no-data[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 48px;\n margin-bottom: 16px;\n opacity: 0.3;\n}\n\n.no-data[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n}\n\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\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\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 .empty-state[_ngcontent-%COMP%] {\n padding: 40px 20px;\n }\n\n .empty-icon[_ngcontent-%COMP%] {\n width: 64px;\n height: 64px;\n }\n\n .empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 28px;\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\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\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\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\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\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\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\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\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\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\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 .empty-state[_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\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\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\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\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\n.tab-content.has-savebar[_ngcontent-%COMP%] {\n padding-bottom: 84px;\n}\n\n\n\n\n\n\n.save-bar[_ngcontent-%COMP%] {\n position: absolute;\n left: 16px;\n right: 96px; \n\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(15, 23, 42, 0.18));\n backdrop-filter: blur(8px);\n \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\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 }); }
2025
2373
  };
2026
2374
  MJTestFormComponentExtended = __decorate([
2027
2375
  RegisterClass(BaseFormComponent, 'MJ: Tests')
@@ -2029,10 +2377,13 @@ MJTestFormComponentExtended = __decorate([
2029
2377
  export { MJTestFormComponentExtended };
2030
2378
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJTestFormComponentExtended, [{
2031
2379
  type: Component,
2032
- 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>{{ record.Name }}</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 </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\">\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 <div class=\"config-section\">\n <h3><i class=\"fas fa-cogs\"></i> Execution Settings</h3>\n <div class=\"config-grid\">\n <div class=\"config-item\">\n <label>Priority</label>\n <input type=\"number\" [(ngModel)]=\"record.Priority\" class=\"config-input\" placeholder=\"Lower = Higher Priority\" />\n </div>\n <div class=\"config-item\">\n <label>Repeat Count</label>\n <input type=\"number\" [(ngModel)]=\"record.RepeatCount\" class=\"config-input\" min=\"1\" />\n </div>\n <div class=\"config-item\">\n <label>Estimated Duration (seconds)</label>\n <input type=\"number\" [(ngModel)]=\"record.EstimatedDurationSeconds\" class=\"config-input\" />\n </div>\n <div class=\"config-item\">\n <label>Estimated Cost (USD)</label>\n <input type=\"number\" step=\"0.000001\" [(ngModel)]=\"record.EstimatedCostUSD\" class=\"config-input\" />\n </div>\n <div class=\"config-item full-width\">\n <label>Max Execution Time (ms)</label>\n <input type=\"number\" [(ngModel)]=\"record.MaxExecutionTimeMS\" class=\"config-input\" placeholder=\"Default: 300000 (5 min)\" />\n <span class=\"config-hint\">Leave empty for default 5 minute timeout</span>\n </div>\n </div>\n </div>\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 <div class=\"config-section\">\n <h3><i class=\"fas fa-tags\"></i> Tags (JSON Array)</h3>\n <div class=\"config-editor-container small\">\n <mj-code-editor\n [value]=\"record.Tags || '[]'\"\n language=\"json\"\n [readonly]=\"false\"\n [lineWrapping]=\"true\"\n (change)=\"record.Tags = $event\">\n </mj-code-editor>\n </div>\n </div>\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 <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-play-circle\"></i>\n </div>\n <h4>No Test Runs Yet</h4>\n <p>Run this test to see execution history and results here.</p>\n <button mjButton (click)=\"runTest()\" variant=\"primary\">\n <i class=\"fas fa-play\"></i> Run Test Now\n </button>\n </div>\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 <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-folder-open\"></i>\n </div>\n <h4>Not Part of Any Suite</h4>\n <p>This test is not included in any test suites. Add it to a suite to run it with other tests.</p>\n </div>\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 <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-chart-line\"></i>\n </div>\n <h4>No History Available</h4>\n <p>Run this test to start building history and analytics data.</p>\n <button mjButton (click)=\"runTest()\" variant=\"primary\">\n <i class=\"fas fa-play\"></i> Run Test Now\n </button>\n </div>\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>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</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 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 Empty States\n =========================== */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 24px;\n text-align: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n}\n\n.empty-icon {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n margin-bottom: 20px;\n}\n\n.empty-icon i {\n font-size: 36px;\n color: var(--test-text-muted);\n}\n\n.empty-state h4 {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.empty-state p {\n margin: 0 0 20px 0;\n font-size: 14px;\n color: var(--test-text-secondary);\n max-width: 300px;\n}\n\n/* Legacy no-data for backwards compatibility */\n.no-data {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n color: var(--test-text-muted);\n text-align: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n}\n\n.no-data i {\n font-size: 48px;\n margin-bottom: 16px;\n opacity: 0.3;\n}\n\n.no-data p {\n margin: 0;\n font-size: 14px;\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 .empty-state {\n padding: 40px 20px;\n }\n\n .empty-icon {\n width: 64px;\n height: 64px;\n }\n\n .empty-icon i {\n font-size: 28px;\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 .empty-state {\n break-inside: avoid;\n box-shadow: none;\n border: 1px solid var(--mj-border-default);\n }\n}\n"] }]
2380
+ 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-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 <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-play-circle\"></i>\n </div>\n <h4>No Test Runs Yet</h4>\n <p>Run this test to see execution history and results here.</p>\n <button mjButton (click)=\"runTest()\" variant=\"primary\">\n <i class=\"fas fa-play\"></i> Run Test Now\n </button>\n </div>\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 <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-folder-open\"></i>\n </div>\n <h4>Not Part of Any Suite</h4>\n <p>This test is not included in any test suites. Add it to a suite to run it with other tests.</p>\n </div>\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 <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-chart-line\"></i>\n </div>\n <h4>No History Available</h4>\n <p>Run this test to start building history and analytics data.</p>\n <button mjButton (click)=\"runTest()\" variant=\"primary\">\n <i class=\"fas fa-play\"></i> Run Test Now\n </button>\n </div>\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 Empty States\n =========================== */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 24px;\n text-align: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n}\n\n.empty-icon {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n margin-bottom: 20px;\n}\n\n.empty-icon i {\n font-size: 36px;\n color: var(--test-text-muted);\n}\n\n.empty-state h4 {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.empty-state p {\n margin: 0 0 20px 0;\n font-size: 14px;\n color: var(--test-text-secondary);\n max-width: 300px;\n}\n\n/* Legacy no-data for backwards compatibility */\n.no-data {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n color: var(--test-text-muted);\n text-align: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n}\n\n.no-data i {\n font-size: 48px;\n margin-bottom: 16px;\n opacity: 0.3;\n}\n\n.no-data p {\n margin: 0;\n font-size: 14px;\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 .empty-state {\n padding: 40px 20px;\n }\n\n .empty-icon {\n width: 64px;\n height: 64px;\n }\n\n .empty-icon i {\n font-size: 28px;\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 .empty-state {\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(15, 23, 42, 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"] }]
2033
2381
  }], null, { handleKeyboardShortcut: [{
2034
2382
  type: HostListener,
2035
2383
  args: ['document:keydown', ['$event']]
2384
+ }], handleBeforeUnload: [{
2385
+ type: HostListener,
2386
+ args: ['window:beforeunload', ['$event']]
2036
2387
  }] }); })();
2037
2388
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJTestFormComponentExtended, { className: "MJTestFormComponentExtended", filePath: "src/lib/custom/Tests/test-form.component.ts", lineNumber: 62 }); })();
2038
2389
  //# sourceMappingURL=test-form.component.js.map