@memberjunction/ng-core-entity-forms 5.32.0 → 5.34.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 (93) hide show
  1. package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts +30 -0
  2. package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts.map +1 -1
  3. package/dist/lib/custom/AIAgents/ai-agent-form.component.js +944 -645
  4. package/dist/lib/custom/AIAgents/ai-agent-form.component.js.map +1 -1
  5. package/dist/lib/custom/SearchScopes/searchscope-form.component.d.ts +137 -0
  6. package/dist/lib/custom/SearchScopes/searchscope-form.component.d.ts.map +1 -0
  7. package/dist/lib/custom/SearchScopes/searchscope-form.component.js +888 -0
  8. package/dist/lib/custom/SearchScopes/searchscope-form.component.js.map +1 -0
  9. package/dist/lib/custom/SearchScopes/searchscopeprovider-form.component.d.ts +66 -0
  10. package/dist/lib/custom/SearchScopes/searchscopeprovider-form.component.d.ts.map +1 -0
  11. package/dist/lib/custom/SearchScopes/searchscopeprovider-form.component.js +253 -0
  12. package/dist/lib/custom/SearchScopes/searchscopeprovider-form.component.js.map +1 -0
  13. package/dist/lib/custom/Tests/test-rubric-form.component.js +2 -2
  14. package/dist/lib/custom/Tests/test-rubric-form.component.js.map +1 -1
  15. package/dist/lib/custom/Tests/test-suite-form.component.js +2 -2
  16. package/dist/lib/custom/Tests/test-suite-form.component.js.map +1 -1
  17. package/dist/lib/custom/custom-forms.module.d.ts +28 -25
  18. package/dist/lib/custom/custom-forms.module.d.ts.map +1 -1
  19. package/dist/lib/custom/custom-forms.module.js +18 -4
  20. package/dist/lib/custom/custom-forms.module.js.map +1 -1
  21. package/dist/lib/custom/shared/entity-selector-dialog.component.js +2 -2
  22. package/dist/lib/custom/shared/entity-selector-dialog.component.js.map +1 -1
  23. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.d.ts.map +1 -1
  24. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js +111 -79
  25. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js.map +1 -1
  26. package/dist/lib/generated/Entities/MJAIAgentSearchScope/mjaiagentsearchscope.form.component.d.ts +10 -0
  27. package/dist/lib/generated/Entities/MJAIAgentSearchScope/mjaiagentsearchscope.form.component.d.ts.map +1 -0
  28. package/dist/lib/generated/Entities/MJAIAgentSearchScope/mjaiagentsearchscope.form.component.js +93 -0
  29. package/dist/lib/generated/Entities/MJAIAgentSearchScope/mjaiagentsearchscope.form.component.js.map +1 -0
  30. package/dist/lib/generated/Entities/MJAIResultCache/mjairesultcache.form.component.js +2 -2
  31. package/dist/lib/generated/Entities/MJAIResultCache/mjairesultcache.form.component.js.map +1 -1
  32. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.d.ts.map +1 -1
  33. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js +89 -71
  34. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js.map +1 -1
  35. package/dist/lib/generated/Entities/MJEntityField/mjentityfield.form.component.js +23 -21
  36. package/dist/lib/generated/Entities/MJEntityField/mjentityfield.form.component.js.map +1 -1
  37. package/dist/lib/generated/Entities/MJFileStorageAccount/mjfilestorageaccount.form.component.d.ts.map +1 -1
  38. package/dist/lib/generated/Entities/MJFileStorageAccount/mjfilestorageaccount.form.component.js +33 -15
  39. package/dist/lib/generated/Entities/MJFileStorageAccount/mjfilestorageaccount.form.component.js.map +1 -1
  40. package/dist/lib/generated/Entities/MJRole/mjrole.form.component.d.ts.map +1 -1
  41. package/dist/lib/generated/Entities/MJRole/mjrole.form.component.js +31 -13
  42. package/dist/lib/generated/Entities/MJRole/mjrole.form.component.js.map +1 -1
  43. package/dist/lib/generated/Entities/MJSearchExecutionLog/mjsearchexecutionlog.form.component.d.ts +10 -0
  44. package/dist/lib/generated/Entities/MJSearchExecutionLog/mjsearchexecutionlog.form.component.d.ts.map +1 -0
  45. package/dist/lib/generated/Entities/MJSearchExecutionLog/mjsearchexecutionlog.form.component.js +91 -0
  46. package/dist/lib/generated/Entities/MJSearchExecutionLog/mjsearchexecutionlog.form.component.js.map +1 -0
  47. package/dist/lib/generated/Entities/MJSearchProvider/mjsearchprovider.form.component.d.ts.map +1 -1
  48. package/dist/lib/generated/Entities/MJSearchProvider/mjsearchprovider.form.component.js +23 -5
  49. package/dist/lib/generated/Entities/MJSearchProvider/mjsearchprovider.form.component.js.map +1 -1
  50. package/dist/lib/generated/Entities/MJSearchScope/mjsearchscope.form.component.d.ts +10 -0
  51. package/dist/lib/generated/Entities/MJSearchScope/mjsearchscope.form.component.d.ts.map +1 -0
  52. package/dist/lib/generated/Entities/MJSearchScope/mjsearchscope.form.component.js +243 -0
  53. package/dist/lib/generated/Entities/MJSearchScope/mjsearchscope.form.component.js.map +1 -0
  54. package/dist/lib/generated/Entities/MJSearchScopeEntity/mjsearchscopeentity.form.component.d.ts +10 -0
  55. package/dist/lib/generated/Entities/MJSearchScopeEntity/mjsearchscopeentity.form.component.d.ts.map +1 -0
  56. package/dist/lib/generated/Entities/MJSearchScopeEntity/mjsearchscopeentity.form.component.js +71 -0
  57. package/dist/lib/generated/Entities/MJSearchScopeEntity/mjsearchscopeentity.form.component.js.map +1 -0
  58. package/dist/lib/generated/Entities/MJSearchScopeExternalIndex/mjsearchscopeexternalindex.form.component.d.ts +10 -0
  59. package/dist/lib/generated/Entities/MJSearchScopeExternalIndex/mjsearchscopeexternalindex.form.component.d.ts.map +1 -0
  60. package/dist/lib/generated/Entities/MJSearchScopeExternalIndex/mjsearchscopeexternalindex.form.component.js +75 -0
  61. package/dist/lib/generated/Entities/MJSearchScopeExternalIndex/mjsearchscopeexternalindex.form.component.js.map +1 -0
  62. package/dist/lib/generated/Entities/MJSearchScopePermission/mjsearchscopepermission.form.component.d.ts +10 -0
  63. package/dist/lib/generated/Entities/MJSearchScopePermission/mjsearchscopepermission.form.component.d.ts.map +1 -0
  64. package/dist/lib/generated/Entities/MJSearchScopePermission/mjsearchscopepermission.form.component.js +65 -0
  65. package/dist/lib/generated/Entities/MJSearchScopePermission/mjsearchscopepermission.form.component.js.map +1 -0
  66. package/dist/lib/generated/Entities/MJSearchScopeProvider/mjsearchscopeprovider.form.component.d.ts +10 -0
  67. package/dist/lib/generated/Entities/MJSearchScopeProvider/mjsearchscopeprovider.form.component.d.ts.map +1 -0
  68. package/dist/lib/generated/Entities/MJSearchScopeProvider/mjsearchscopeprovider.form.component.js +75 -0
  69. package/dist/lib/generated/Entities/MJSearchScopeProvider/mjsearchscopeprovider.form.component.js.map +1 -0
  70. package/dist/lib/generated/Entities/MJSearchScopeStorageAccount/mjsearchscopestorageaccount.form.component.d.ts +10 -0
  71. package/dist/lib/generated/Entities/MJSearchScopeStorageAccount/mjsearchscopestorageaccount.form.component.d.ts.map +1 -0
  72. package/dist/lib/generated/Entities/MJSearchScopeStorageAccount/mjsearchscopestorageaccount.form.component.js +63 -0
  73. package/dist/lib/generated/Entities/MJSearchScopeStorageAccount/mjsearchscopestorageaccount.form.component.js.map +1 -0
  74. package/dist/lib/generated/Entities/MJSearchScopeTestQuery/mjsearchscopetestquery.form.component.d.ts +10 -0
  75. package/dist/lib/generated/Entities/MJSearchScopeTestQuery/mjsearchscopetestquery.form.component.d.ts.map +1 -0
  76. package/dist/lib/generated/Entities/MJSearchScopeTestQuery/mjsearchscopetestquery.form.component.js +75 -0
  77. package/dist/lib/generated/Entities/MJSearchScopeTestQuery/mjsearchscopetestquery.form.component.js.map +1 -0
  78. package/dist/lib/generated/Entities/MJTag/mjtag.form.component.js +9 -9
  79. package/dist/lib/generated/Entities/MJTag/mjtag.form.component.js.map +1 -1
  80. package/dist/lib/generated/Entities/MJTemplate/mjtemplate.form.component.d.ts.map +1 -1
  81. package/dist/lib/generated/Entities/MJTemplate/mjtemplate.form.component.js +46 -10
  82. package/dist/lib/generated/Entities/MJTemplate/mjtemplate.form.component.js.map +1 -1
  83. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.d.ts.map +1 -1
  84. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js +223 -169
  85. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js.map +1 -1
  86. package/dist/lib/generated/Entities/MJVectorIndex/mjvectorindex.form.component.d.ts.map +1 -1
  87. package/dist/lib/generated/Entities/MJVectorIndex/mjvectorindex.form.component.js +32 -14
  88. package/dist/lib/generated/Entities/MJVectorIndex/mjvectorindex.form.component.js.map +1 -1
  89. package/dist/lib/generated/generated-forms.module.d.ts +312 -298
  90. package/dist/lib/generated/generated-forms.module.d.ts.map +1 -1
  91. package/dist/lib/generated/generated-forms.module.js +168 -111
  92. package/dist/lib/generated/generated-forms.module.js.map +1 -1
  93. package/package.json +36 -35
@@ -0,0 +1 @@
1
+ {"version":3,"file":"searchscope-form.component.js","sourceRoot":"","sources":["../../../../src/lib/custom/SearchScopes/searchscope-form.component.ts","../../../../src/lib/custom/SearchScopes/searchscope-form.component.html"],"names":[],"mappings":";;;;;;;AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,EAAE,SAAS,EAAa,MAAM,eAAe,CAAC;AAErD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,aAAa,EAA6C,MAAM,2BAA2B,CAAC;AACrG,OAAO,EAAE,0BAA0B,EAAE,MAAM,qEAAqE,CAAC;;;;;;;;;;;ICsI7F,AADJ,+BAA+B,eACO;IAAA,YAAe;IAAA,iBAAO;IACxD,iCAQ+E;IAA3E,+NAAU,iEAA6D,KAAC;IAR5E,iBAQ+E;IAC/E,gCAAkC;IAAA,YAAiC;;IACvE,AADuE,iBAAO,EACxE;;;;IAXgC,eAAe;IAAf,kCAAe;IAO7C,cAAsB;IACtB,AADA,2CAAsB,wBACF;IAEU,eAAiC;IAAjC,kEAAiC;;;IA8BnE,kCAAqC;IACjC,YACJ;IAAA,iBAAS;;;IAFD,6CAA4B;IAChC,cACJ;IADI,wGACJ;;;IAIJ,6BAA8B;IAC1B,wBAAgD;IAChD,+DACA;IAAA,8BAAQ;IAAA,mCAAmB;IAAA,iBAAS;IAAC,oDACzC;IAAA,iBAAI;;;IAyBI,wBAA2C;IAC3C,4BAAM;IAAA,+BAAU;IAAA,iBAAO;;;IAEvB,wBAAoC;IACpC,4BAAM;IAAA,wCAAwB;IAAA,iBAAO;;;;IA6BzC,kCAG+B;IAAvB,uMAAS,mBAAY,KAAC;IAC1B,wBAAgC;IAAC,qBACrC;IAAA,iBAAS;;;IAHD,4GAAgD;;;;IAKxD,kCAEkC;IAA1B,uMAAS,sBAAe,KAAC;IAC7B,wBAAgC;IAAC,wBACrC;IAAA,iBAAS;;;IAKb,6BAA8B;IAC1B,wBAA8C;IAAC,YACnD;IAAA,iBAAI;;;IAD+C,eACnD;IADmD,oDACnD;;;IAMQ,gCAA0D;IACtD,wBAAgD;IAAC,iCACrD;IAAA,iBAAO;;;IAGP,gCAA4D;IACxD,wBAAiC;IACjC,8BAAQ;IAAA,YAAY;IAAA,iBAAS;IAC7B,gCAAsC;IAAA,YAAa;IAAA,iBAAO;IAC1D,gCAAqC;IAAA,YAAmB;IAC5D,AAD4D,iBAAO,EAC5D;;;IAHK,eAAY;IAAZ,+BAAY;IACkB,eAAa;IAAb,gCAAa;IACd,eAAmB;IAAnB,+CAAmB;;;IAXpE,+BAAgC;IAC5B,qHAAyD;IAKzD,sHAOC;IACL,iBAAM;;;IAbF,cAIC;IAJD,0FAIC;IACD,cAOC;IAPD,sCAOC;;;IAQqC,YAA4B;;;IAA5B,6DAA4B;;;IAE1D,gCAE2F;IACvF,YACJ;IAAA,iBAAO;;;IAHD,mFAAmE;IAErE,cACJ;IADI,4FACJ;;;IAMI,AADJ,+BAAiC,eACW;IAAA,YAAuC;;IAAA,iBAAO;IACtF,gCAAwC;IAAA,YAAa;IAAA,iBAAO;IAC5D,gCAAyC;IAAA,YAAkB;IAC/D,AAD+D,iBAAO,EAChE;;;IAHsC,eAAuC;IAAvC,+EAAuC;IACvC,eAAa;IAAb,gCAAa;IACZ,eAAkB;IAAlB,qCAAkB;;;IAJnE,0HAAc;;;IAAd,8CAMC;;;IAGD,6BAAkC;IAAA,YAAkE;IAAA,iBAAI;;;IAAtE,cAAkE;IAAlE,uGAAkE;;;IArBxG,AADJ,+BAAkC,cACW;IACrC,YACA;IAAA,yGAAiC;IACjC,qHAAyC;IAO7C,iBAAM;IACN,sHAQC;IACD,kHAAkC;IAGtC,iBAAM;;;IAtBE,eACA;IADA,uEACA;IAAA,cAA+D;IAA/D,2DAA+D;IAC/D,cAMC;IAND,mEAMC;IAEL,cAQC;IARD,oCAQC;IACD,eAEC;IAFD,4DAEC;;;;IA4DT,AADJ,2BAAK,uCAQI;IADD,AADA,0OAAY,6BAAsB,KAAC,uOAClB,0BAAmB,0BAA0B,uBAAuB,KAAC;IAG9F,AADI,iBAA+B,EAC7B;;;IARE,cAAmG;IAGnG,AADA,AADA,AADA,yHAAmG,4EAC/B,mEACT,qBACvC;;;;IAqBxB,AADJ,2BAAK,uCAQI;IADD,AADA,0OAAY,6BAAsB,KAAC,uOAClB,0BAAmB,8BAA8B,uBAAuB,KAAC;IAGlG,AADI,iBAA+B,EAC7B;;;IARE,cAAuG;IAGvG,AADA,AADA,AADA,6HAAuG,gFAC/B,uEACT,qBAC3C;;;;IAqBxB,AADJ,2BAAK,uCAQI;IADD,AADA,0OAAY,6BAAsB,KAAC,uOAClB,0BAAmB,uBAAuB,uBAAuB,KAAC;IAG3F,AADI,iBAA+B,EAC7B;;;IARE,cAA+F;IAG/F,AADA,AADA,AADA,qHAA+F,wEAC/B,gEACR,qBACpC;;;;IAqBxB,AADJ,2BAAK,uCAQI;IADD,AADA,0OAAY,6BAAsB,KAAC,uOAClB,0BAAmB,8BAA8B,uBAAuB,KAAC;IAGlG,AADI,iBAA+B,EAC7B;;;IARE,cAAuG;IAGvG,AADA,AADA,AADA,6HAAuG,gFAC/B,uEACT,qBAC3C;;;;IAqBxB,AADJ,2BAAK,uCAQI;IADD,AADA,0OAAY,6BAAsB,KAAC,uOAClB,0BAAmB,wBAAwB,uBAAuB,KAAC;IAG5F,AADI,iBAA+B,EAC7B;;;IARE,cAAgG;IAGhG,AADA,AADA,AADA,sHAAgG,yEAC/B,iEACR,qBACrC;;;;IAqBxB,AADJ,2BAAK,uCAQI;IADD,AADA,0OAAY,6BAAsB,KAAC,uOAClB,0BAAmB,uBAAuB,uBAAuB,KAAC;IAG3F,AADI,iBAA+B,EAC7B;;;IARE,cAAgG;IAGhG,AADA,AADA,AADA,sHAAgG,yEAC/B,gEACT,qBACpC;;;;IAqBxB,AADJ,2BAAK,uCAQI;IADD,AADA,0OAAY,6BAAsB,KAAC,uOAClB,0BAAmB,0BAA0B,uBAAuB,KAAC;IAG9F,AADI,iBAA+B,EAC7B;;;IARE,cAAkG;IAGlG,AADA,AADA,AADA,wHAAkG,2EAC/B,mEACR,qBACvC;;;;IAqBxB,AADJ,2BAAK,uCAQI;IADD,AADA,0OAAY,6BAAsB,KAAC,uOAClB,0BAAmB,uBAAuB,uBAAuB,KAAC;IAG3F,AADI,iBAA+B,EAC7B;;;IARE,cAA+F;IAG/F,AADA,AADA,AADA,qHAA+F,wEAC/B,gEACR,sBACnC;;ADrhBrC;;;;;GAKG;AACH,MAAM,qBAAqB,GAAa,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;AAQpF;;;;GAIG;AACH,MAAM,kBAAkB,GAAqB;IACzC,EAAE,WAAW,EAAE,cAAc,EAAE,IAAI,EAAE,6BAA6B,EAAE,OAAO,EAAE,KAAK,EAAE;IACpF,EAAE,WAAW,EAAE,gBAAgB,EAAE,IAAI,EAAE,sBAAsB,EAAE,OAAO,EAAE,IAAI,EAAE;IAC9E,EAAE,WAAW,EAAE,gBAAgB,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,IAAI,EAAE;IAC3E,EAAE,WAAW,EAAE,gBAAgB,EAAE,IAAI,EAAE,4BAA4B,EAAE,OAAO,EAAE,IAAI,EAAE;IACpF,EAAE,WAAW,EAAE,aAAa,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,KAAK,EAAE;CAC5E,CAAC;AASK,IAAM,kCAAkC,GAAxC,MAAM,kCAAmC,SAAQ,0BAA0B;IAA3E;;QAGa,uBAAkB,GAAqB,kBAAkB,CAAC;QAE1E,iCAAiC;QAC1B,iBAAY,GAAG,EAAE,CAAC;QAClB,qBAAgB,GAAG,KAAK,CAAC;QACzB,mBAAc,GAAuB,EAAE,CAAC;QACxC,qBAAgB,GAA8B,EAAE,CAAC;QACjD,qBAAgB,GAAkB,IAAI,CAAC;QACvC,iBAAY,GAAkB,IAAI,CAAC;QAClC,wBAAmB,GAAwB,IAAI,CAAC;QAChD,kBAAa,GAAG,IAAI,aAAa,EAAE,CAAC;QAE5C;;;;;;WAMG;QACK,yBAAoB,GAAa,EAAE,CAAC;QACrC,6BAAwB,GAAkB,IAAI,CAAC;QAgLtD;;;WAGG;QACI,yBAAoB,GAAG,KAAK,CAAC;QAEpC;;;;;;WAMG;QACK,mBAAc,GAA6B,IAAI,CAAC;KAmI3D;;IA9TmB,WAAW;QACvB,IAAI,CAAC,mBAAmB,EAAE,WAAW,EAAE,CAAC;QACxC,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;IACpC,CAAC;IAED;;;;;;OAMG;IACI,UAAU;QACb,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,IAAI,CAAC,gBAAgB;YAAE,OAAO;QACtD,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;QACvC,IAAI,CAAC,KAAK;YAAE,OAAO;QAEnB,wDAAwD;QACxD,IAAI,CAAC,mBAAmB,EAAE,WAAW,EAAE,CAAC;QACxC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAC7B,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;QACzB,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAC7B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAEzB,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC;YACvD,KAAK,EAAE,KAAK;YACZ,UAAU,EAAE,EAAE;YACd,aAAa,EAAE,EAAE;YACjB,cAAc,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,CAAC;YAC3D,QAAQ,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;SAC7B,CAAC,CAAC,SAAS,CAAC;YACT,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE;gBACZ,IAAI,KAAK,CAAC,KAAK,KAAK,UAAU,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;oBACnD,IAAI,CAAC,gBAAgB,GAAG;wBACpB,GAAG,IAAI,CAAC,gBAAgB;wBACxB;4BACI,IAAI,EAAE,KAAK,CAAC,YAAY;4BACxB,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;4BACjC,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,CAAC;4BAC/B,KAAK,EAAE,WAAW;yBACrB;qBACJ,CAAC;oBACF,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;wBAChB,IAAI,CAAC,cAAc,GAAG,CAAC,GAAG,IAAI,CAAC,cAAc,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;oBACvG,CAAC;gBACL,CAAC;qBAAM,IAAI,KAAK,CAAC,KAAK,KAAK,OAAO,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;oBAClD,IAAI,CAAC,cAAc,GAAG,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;oBAC3E,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC;gBACpD,CAAC;YACL,CAAC;YACD,KAAK,EAAE,CAAC,GAAU,EAAE,EAAE;gBAClB,IAAI,CAAC,YAAY,GAAG,GAAG,CAAC,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC/C,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;YAClC,CAAC;YACD,QAAQ,EAAE,GAAG,EAAE;gBACX,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;gBAC9B,+DAA+D;gBAC/D,oCAAoC;gBACpC,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;gBAC5D,IAAI,IAAI,CAAC,oBAAoB,CAAC,MAAM,GAAG,CAAC,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAChE,MAAM,GAAG,GAAG,oCAAkC,CAAC,uBAAuB,CAClE,IAAI,CAAC,oBAAoB,EACzB,UAAU,CACb,CAAC;oBACF,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;wBACf,iEAAiE;wBACjE,kEAAkE;wBAClE,yBAAyB;wBACzB,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;oBAC/D,CAAC;gBACL,CAAC;gBACD,IAAI,CAAC,oBAAoB,GAAG,UAAU,CAAC;YAC3C,CAAC;SACJ,CAAC,CAAC;IACP,CAAC;IAEM,aAAa;QAChB,IAAI,CAAC,mBAAmB,EAAE,WAAW,EAAE,CAAC;QACxC,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;QAChC,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;IAClC,CAAC;IAED;;;;;;;;OAQG;IACK,MAAM,CAAC,uBAAuB,CAAC,KAAe,EAAE,KAAe;QACnE,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACjD,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;QACxB,IAAI,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QACvB,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACzB,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC7B,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAE,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC;gBAC1D,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAE,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC;gBAC1D,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC;gBACtB,IAAI,OAAO,GAAG,CAAC;oBAAE,UAAU,EAAE,CAAC;qBACzB,IAAI,OAAO,GAAG,CAAC;oBAAE,UAAU,EAAE,CAAC;gBACnC,oDAAoD;YACxD,CAAC;QACL,CAAC;QACD,MAAM,UAAU,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,UAAU,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAClC,OAAO,CAAC,UAAU,GAAG,UAAU,CAAC,GAAG,UAAU,CAAC;IAClD,CAAC;IAED;;;;OAIG;IACa,KAAK,CAAC,QAAQ;QAC1B,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAC;QACvB,IAAI,CAAC,YAAY,CAAC;YACd,EAAE,UAAU,EAAE,iBAAiB,EAAE,WAAW,EAAE,kBAAkB,EAAE,UAAU,EAAE,IAAI,EAAE;YACpF,EAAE,UAAU,EAAE,oBAAoB,EAAE,WAAW,EAAE,qBAAqB,EAAE,UAAU,EAAE,IAAI,EAAE;YAC1F,EAAE,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,gBAAgB,EAAE,UAAU,EAAE,KAAK,EAAE;YACjF,EAAE,UAAU,EAAE,qBAAqB,EAAE,WAAW,EAAE,sBAAsB,EAAE,UAAU,EAAE,KAAK,EAAE;YAC7F,EAAE,UAAU,EAAE,wBAAwB,EAAE,WAAW,EAAE,yBAAyB,EAAE,UAAU,EAAE,KAAK,EAAE;YACnG,EAAE,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,gBAAgB,EAAE,UAAU,EAAE,KAAK,EAAE;YACjF,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE;YACtE,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,KAAK,EAAE;YAC7E,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE;YACpE,EAAE,UAAU,EAAE,gBAAgB,EAAE,WAAW,EAAE,iBAAiB,EAAE,UAAU,EAAE,KAAK,EAAE;YACnF,EAAE,UAAU,EAAE,0BAA0B,EAAE,WAAW,EAAE,2BAA2B,EAAE,UAAU,EAAE,KAAK,EAAE;YACvG,EAAE,UAAU,EAAE,8BAA8B,EAAE,WAAW,EAAE,+BAA+B,EAAE,UAAU,EAAE,KAAK,EAAE;YAC/G,EAAE,UAAU,EAAE,uBAAuB,EAAE,WAAW,EAAE,uBAAuB,EAAE,UAAU,EAAE,KAAK,EAAE;YAChG,EAAE,UAAU,EAAE,8BAA8B,EAAE,WAAW,EAAE,+BAA+B,EAAE,UAAU,EAAE,KAAK,EAAE;YAC/G,EAAE,UAAU,EAAE,wBAAwB,EAAE,WAAW,EAAE,wBAAwB,EAAE,UAAU,EAAE,KAAK,EAAE;YAClG,EAAE,UAAU,EAAE,uBAAuB,EAAE,WAAW,EAAE,wBAAwB,EAAE,UAAU,EAAE,KAAK,EAAE;YACjG,EAAE,UAAU,EAAE,0BAA0B,EAAE,WAAW,EAAE,0BAA0B,EAAE,UAAU,EAAE,KAAK,EAAE;SACzG,CAAC,CAAC;IACP,CAAC;IAED;;;;OAIG;IACH,IAAW,2BAA2B;QAClC,MAAM,GAAG,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACpC,OAAQ,GAAG,EAAE,CAAC,UAAU,CAA0C,EAAE,WAAW,IAAI,EAAE,CAAC;IAC1F,CAAC;IAED,IAAW,2BAA2B,CAAC,KAAa;QAChD,MAAM,GAAG,GAAG,IAAI,CAAC,gBAAgB,EAAE,IAAI,EAAE,CAAC;QAC1C,MAAM,QAAQ,GAAI,GAAG,CAAC,UAAU,CAAyC,IAAI,EAAE,CAAC;QAChF,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnC,QAAQ,CAAC,aAAa,CAAC,GAAG,KAAK,CAAC;QACpC,CAAC;aAAM,CAAC;YACJ,OAAO,QAAQ,CAAC,aAAa,CAAC,CAAC;QACnC,CAAC;QACD,GAAG,CAAC,UAAU,CAAC,GAAG,QAAQ,CAAC;QAC3B,IAAI,CAAC,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED;;;OAGG;IACH,IAAW,uBAAuB;QAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,2BAA2B,CAAC;QAChD,OAAO,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,MAAM,CAAC,EAAE,OAAO,IAAI,KAAK,CAAC;IACpF,CAAC;IAiBD,IAAW,aAAa;QACpB,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACvB,MAAM,GAAG,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACpC,MAAM,MAAM,GAAI,GAAG,EAAE,CAAC,eAAe,CAAyC,IAAI,EAAE,CAAC;YACrF,IAAI,CAAC,cAAc,GAAG,qBAAqB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;gBAClD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC1B,MAAM,MAAM,GAAG,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC/E,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;YACpD,CAAC,CAAC,CAAC;QACP,CAAC;QACD,OAAO,IAAI,CAAC,cAAc,CAAC;IAC/B,CAAC;IAED;;;;OAIG;IACI,qBAAqB,CAAC,GAAoB,EAAE,GAAoB;QACnE,MAAM,KAAK,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,OAAO;QACpC,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC;QAEnB,MAAM,GAAG,GAAG,IAAI,CAAC,gBAAgB,EAAE,IAAI,EAAE,CAAC;QAC1C,MAAM,OAAO,GAAI,GAAG,CAAC,eAAe,CAAyC,IAAI,EAAE,CAAC;QACpF,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,KAAK,EAAE,CAAC;YAC9B,sEAAsE;YACtE,kCAAkC;YAClC,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACzC,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,GAAG,CAAC,eAAe,CAAC,GAAG,OAAO,CAAC;QACnC,CAAC;aAAM,CAAC;YACJ,OAAO,GAAG,CAAC,eAAe,CAAC,CAAC;QAChC,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,eAAe;QACxB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,IAAI,CAAC,oBAAoB;YAAE,OAAO;QAC1D,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;QACjC,IAAI,CAAC;YACD,MAAM,EAAE,GAAG,IAAI,OAAO,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAiC;gBAC5D,UAAU,EAAE,2BAA2B;gBACvC,kEAAkE;gBAClE,8CAA8C;gBAC9C,MAAM,EAAE;oBACJ,gBAAgB,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,iBAAiB;oBACrE,cAAc,EAAE,mBAAmB,EAAE,eAAe,EAAE,QAAQ,EAAE,WAAW;iBAC9E;gBACD,WAAW,EAAE,kBAAkB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG;gBACpE,OAAO,EAAE,qBAAqB;gBAC9B,OAAO,EAAE,GAAG;gBACZ,UAAU,EAAE,QAAQ;aACvB,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBAClB,QAAQ,CAAC,kCAAkC,MAAM,CAAC,YAAY,IAAI,eAAe,EAAE,CAAC,CAAC;gBACrF,OAAO;YACX,CAAC;YACD,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAqC,CAAC;YACxE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;gBAAS,CAAC;YACP,IAAI,CAAC,oBAAoB,GAAG,KAAK,CAAC;QACtC,CAAC;IACL,CAAC;IAEO,WAAW,CAAC,IAAsC;QACtD,MAAM,OAAO,GAAG;YACZ,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,iBAAiB;YAChE,cAAc,EAAE,mBAAmB,EAAE,eAAe,EAAE,QAAQ,EAAE,WAAW;SAC9E,CAAC;QACF,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAClC,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACnB,MAAM,KAAK,GAAG;gBACV,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC;gBAC9C,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;gBACtC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;gBACrC,MAAM,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC;gBAC1B,MAAM,CAAC,CAAC,CAAC,eAAe,IAAI,CAAC,CAAC;gBAC9B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;gBAC5C,MAAM,CAAC,CAAC,CAAC,iBAAiB,IAAI,EAAE,CAAC;gBACjC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;gBAC7C,MAAM,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC;gBACtB,MAAM,CAAC,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC;aAC5B,CAAC;YACF,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAChC,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,yBAAyB,EAAE,CAAC,CAAC;QAC/E,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QACtC,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC/B,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,OAAO,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;QACtE,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,sBAAsB,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC1G,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,QAAQ,CAAC;QACjC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAChC,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAChC,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAEO,SAAS,CAAC,KAAa;QAC3B,IAAI,KAAK,IAAI,IAAI;YAAE,OAAO,EAAE,CAAC;QAC7B,wEAAwE;QACxE,oEAAoE;QACpE,sBAAsB;QACtB,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACnD,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;QAC5C,CAAC;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAEO,gBAAgB;QACpB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW;YAAE,OAAO,IAAI,CAAC;QAC3C,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YACnD,OAAO,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAiC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC7F,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;4TAtVQ,kCAAkC,yBAAlC,kCAAkC;oEAAlC,kCAAkC;YC5E/C,mDAK4D;YAAxD,AADA,AADA,AADA,AADA,6IAAY,0BAAsB,IAAC,wIAChB,uBAAmB,IAAC,wIACpB,uBAAmB,IAAC,0IACnB,wBAAoB,IAAC,wJACd,+BAA2B,IAAC;YAMvD,+CAKgC;YAiB5B,AARA,AARA,mCAOiB,uBAQA,uBAQA;YAErB,iBAAuB;YAGvB,+CAKgC;YAS5B,AARA,mCAOiB,uBAQA;YAErB,iBAAuB;YAGvB,+CAKgC;YAC5B,mCAQiB;YAErB,iBAAuB;YAGvB,iDAKgC;YAiB5B,AARA,AARA,qCAOiB,yBAQA,yBAQA;YAErB,iBAAuB;YAGvB,iDAKgC;YAS5B,AARA,qCAOiB,yBAQA;YAErB,iBAAuB;YAenB,AANJ,iDAKgC,eACA;YACxB,wGAcC;YACD,8BAA+B;YAC3B,0CAAwB;YAAA,6BAAM;YAAA,0CAAyB;YAAA,iBAAO;YAAA,gGAElE;YAER,AADI,AADI,iBAAI,EACF,EACa;YAcf,AADJ,AANJ,iDAKgC,eACC,iBACY;YAAA,sCAAqB;YAAA,iBAAQ;YAClE,mCAI2D;YAAvD,kLAAsD;YACtD,mCAAiB;YAAA,sDAA2B;YAAA,iBAAS;YACrD,2GAIC;YACL,iBAAS;YACT,qGAA+B;YAO/B,8BAA8B;YAC1B,4BAAU;YAAA,6BAAM;YAAA,iDAAgC;YAAA,iBAAO;YAAC,8GAE5D;YAAA,iBAAI;YAEJ,qCAOiB;YAMb,AADJ,gCAAiC,kBAIO;YAA5B,gHAAS,qBAAiB,IAAC;YAI7B,AAHF,4FAA4B,sEAGnB;YAIb,iBAAS;YACT,iCAAmC;YAAA,gEAA+C;YAG9F,AADI,AADI,AADsF,iBAAO,EACvF,EACJ,EACa;YAcX,AADJ,AADJ,AANJ,iDAKgC,eACF,eACc,iBAQK;YAAjC,AADA,+JAAkD,kHACjC,gBAAY,IAAC;YAPlC,iBAOqC;YAQnC,AAPF,0GAAyB,oFAOhB;YAOb,iBAAM;YAEN,qGAAoB;YAMpB,uGAAuD;YAkBvD,uGAAiC;YA4BzC,AADI,iBAAM,EACa;YAIvB,4CAMuB;YAGvB,iDAKgC;YAS5B,AARA,qCAOiB,yBAQA;YAErB,iBAAuB;YASvB,iDAQ8B;YAC1B,mGAAsB;YAa1B,iBAAuB;YAGvB,iDAQ8B;YAC1B,mGAAsB;YAa1B,iBAAuB;YAGvB,iDAQ8B;YAC1B,mGAAsB;YAa1B,iBAAuB;YAGvB,iDAQ8B;YAC1B,mGAAsB;YAa1B,iBAAuB;YAGvB,iDAQ8B;YAC1B,mGAAsB;YAa1B,iBAAuB;YAGvB,iDAQ8B;YAC1B,mGAAsB;YAa1B,iBAAuB;YAGvB,iDAQ8B;YAC1B,mGAAsB;YAa1B,iBAAuB;YAGvB,iDAQ8B;YAC1B,mGAAsB;YAc9B,AADI,iBAAuB,EACA;;YAvkBiB,AAAlB,mCAAiB,sBAAuB;YAe1D,cAAa;YACb,AADA,0BAAa,gCACc;YAEvB,cAAiB;YAKjB,AADA,AAHA,AADA,mCAAiB,mBACC,0BAGG,gCACM;YAG3B,cAAiB;YAKjB,AADA,AAHA,AADA,mCAAiB,mBACC,0BAGG,gCACM;YAG3B,cAAiB;YAKjB,AADA,AAHA,AADA,mCAAiB,mBACC,0BAGG,gCACM;YAU/B,cAAa;YACb,AADA,0BAAa,gCACc;YAEvB,cAAiB;YAKjB,AADA,AAHA,AADA,mCAAiB,mBACC,0BAGG,gCACM;YAG3B,cAAiB;YAKjB,AADA,AAHA,AADA,mCAAiB,mBACC,0BAGG,gCACM;YAU/B,cAAa;YACb,AADA,0BAAa,gCACc;YAEvB,cAAiB;YAKjB,AADA,AAHA,AADA,mCAAiB,oBACE,0BAGE,gCACM;YAW/B,cAAa;YACb,AADA,0BAAa,gCACc;YAEvB,cAAiB;YAKjB,AADA,AAHA,AADA,mCAAiB,mBACC,0BAGG,gCACM;YAG3B,cAAiB;YAKjB,AADA,AAHA,AADA,mCAAiB,mBACC,0BAGG,gCACM;YAG3B,cAAiB;YAKjB,AADA,AAHA,AADA,mCAAiB,mBACC,0BAGG,gCACM;YAU/B,cAAa;YACb,AADA,0BAAa,gCACc;YAEvB,cAAiB;YAKjB,AADA,AAHA,AADA,mCAAiB,mBACC,0BAGG,gCACM;YAG3B,cAAiB;YAKjB,AADA,AAHA,AADA,mCAAiB,mBACC,0BAGG,gCACM;YAgB/B,cAAa;YACb,AADA,0BAAa,gCACc;YAEvB,eAcC;YAdD,gCAcC;YAiBL,eAAa;YACb,AADA,0BAAa,gCACc;YAKnB,eAAsB;YACtB,AADA,wCAAsB,4CACiB;YAGvC,eAIC;YAJD,qCAIC;YAEL,eAMC;YAND,uDAMC;YAOG,eAAiB;YAKjB,AADA,AAHA,AADA,mCAAiB,mBACC,0BAGG,gCACM;YASnB,eAAgD;YAAhD,mGAAgD;YAEpD,cAMC;YAND,oDAMC;YAeb,eAAa;YACb,AADA,0BAAa,gCACc;YAOf,eAA4C;YAC5C,AADA,+FAA4C,2BACtB;YAG1B,cAaC;YAbD,iDAaC;YAGL,eAIC;YAJD,4CAIC;YAED,cAgBC;YAhBD,mFAgBC;YAED,cA0BC;YA1BD,yDA0BC;YAUL,cAAa;YACb,AADA,0BAAa,gCACc;YAQ3B,cAAa;YACb,AADA,0BAAa,gCACc;YAEvB,cAAiB;YAKjB,AADA,AAHA,AADA,mCAAiB,mBACC,0BAGG,gCACM;YAG3B,cAAiB;YAKjB,AADA,AAHA,AADA,mCAAiB,mBACC,0BAGG,gCACM;YAiB/B,cAAa;YAGb,AADA,AADA,AADA,0BAAa,gCACc,kEACkC,0BACpC;YACzB,cAYC;YAZD,8CAYC;YASD,cAAa;YAGb,AADA,AADA,AADA,0BAAa,gCACc,sEACsC,0BACxC;YACzB,cAYC;YAZD,8CAYC;YASD,cAAa;YAGb,AADA,AADA,AADA,0BAAa,gCACc,+DAC+B,0BACjC;YACzB,cAYC;YAZD,8CAYC;YASD,cAAa;YAGb,AADA,AADA,AADA,0BAAa,gCACc,sEACsC,0BACxC;YACzB,cAYC;YAZD,8CAYC;YASD,cAAa;YAGb,AADA,AADA,AADA,0BAAa,gCACc,gEACgC,0BAClC;YACzB,cAYC;YAZD,8CAYC;YASD,cAAa;YAGb,AADA,AADA,AADA,0BAAa,gCACc,+DAC+B,0BACjC;YACzB,cAYC;YAZD,8CAYC;YASD,cAAa;YAGb,AADA,AADA,AADA,0BAAa,gCACc,kEACkC,0BACpC;YACzB,cAYC;YAZD,8CAYC;YASD,cAAa;YAGb,AADA,AADA,AADA,0BAAa,gCACc,+DAC+B,0BACjC;YACzB,cAYC;YAZD,8CAYC;;;ADzfI,kCAAkC;IAP9C,aAAa,CAAC,iBAAiB,EAAE,mBAAmB,CAAC;GAOzC,kCAAkC,CAuV9C;;iFAvVY,kCAAkC;cAN9C,SAAS;6BACM,KAAK,YACP,8BAA8B;;kFAI/B,kCAAkC;AAyV/C,MAAM,UAAU,sCAAsC;IAClD,iFAAiF;IACjF,6DAA6D;IAC7D,MAAM,IAAI,GAAG,kCAAkC,CAAC;AACpD,CAAC","sourcesContent":["/**\n * Custom SearchScope form (P2D.7 Angular half).\n *\n * Adds a \"Reranker\" custom section that:\n * - Renders a dropdown of registered rerankers — currently a hardcoded list\n * mirroring `BaseReRanker.GetAvailableRerankers()` server-side, with each\n * option's HasCost flag surfaced inline so authors can see at a glance\n * which options will incur API spend.\n * - Reads / writes the current selection from `record.ScopeConfig` JSON's\n * `reRanker.driverClass` key — same path the SearchEngine reads at runtime.\n *\n * **Discovery follow-up:** the canonical source of available rerankers is\n * `BaseReRanker.GetAvailableRerankers()` in `@memberjunction/search-engine`,\n * but that's a Node-only package and can't be imported in the browser.\n * A small GraphQL query (e.g. `AvailableRerankers`) on MJServer that calls\n * the helper server-side would let this dropdown auto-discover any\n * third-party reranker registered with ClassFactory. Tracked as a follow-up\n * — for now the hardcoded list covers the 5 rerankers shipped in Phase 2D.\n *\n * The CodeGen-generated `RerankerBudgetCents` numeric input is already on\n * the form (in the \"Details\" section); we don't need to recreate it.\n * The dropdown above + budget input below give scope authors the full\n * Phase 2D configuration surface.\n */\nimport { Component, OnDestroy } from '@angular/core';\nimport { Subscription } from 'rxjs';\nimport { LogError, RunView } from '@memberjunction/core';\nimport { MJSearchScopeEntity, MJSearchExecutionLogEntityType } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseFormComponent } from '@memberjunction/ng-base-forms';\nimport { SearchService, SearchResultItem, StreamingProviderStatus } from '@memberjunction/ng-search';\nimport { MJSearchScopeFormComponent } from '../../generated/Entities/MJSearchScope/mjsearchscope.form.component';\n\ninterface FusionWeightRow {\n /** Source-type key the SearchEngine matches against (e.g. 'vector', 'fulltext'). */\n Key: string;\n /** Friendly label for the slider — same value as Key today, kept separate for future i18n. */\n Label: string;\n /** Working value of the slider (1-decimal precision) — bound via two-way. */\n Weight: number;\n}\n\n/**\n * Built-in source types the SearchEngine ships. New 3rd-party provider\n * SourceTypes (e.g. external clusters) won't appear here unless the scope\n * author adds them via the JSON Scope Config block — by design, since the\n * fusion-weights UI is for the four canonical built-ins.\n */\nconst BUILT_IN_SOURCE_TYPES: string[] = ['vector', 'fulltext', 'entity', 'storage'];\n\ninterface RerankerOption {\n DriverClass: string;\n Name: string;\n HasCost: boolean;\n}\n\n/**\n * Hardcoded list mirroring the rerankers `@memberjunction/search-engine`\n * registers with ClassFactory. Update when adding a new built-in reranker\n * or when the GraphQL discovery query lands.\n */\nconst BUILT_IN_RERANKERS: RerankerOption[] = [\n { DriverClass: 'NoopReRanker', Name: 'NoopReRanker (pass-through)', HasCost: false },\n { DriverClass: 'CohereReRanker', Name: 'Cohere (rerank-v3.5)', HasCost: true },\n { DriverClass: 'VoyageReRanker', Name: 'Voyage (rerank-2)', HasCost: true },\n { DriverClass: 'OpenAIReRanker', Name: 'OpenAI (gpt-4o-mini judge)', HasCost: true },\n { DriverClass: 'BGEReRanker', Name: 'BGE (local, free)', HasCost: false },\n];\n\n@RegisterClass(BaseFormComponent, 'MJ: Search Scopes')\n@Component({\n standalone: false,\n selector: 'mj-searchscope-form-extended',\n templateUrl: './searchscope-form.component.html',\n styleUrls: ['./searchscope-form.component.css'],\n})\nexport class MJSearchScopeFormComponentExtended extends MJSearchScopeFormComponent implements OnDestroy {\n public override record!: MJSearchScopeEntity;\n\n public readonly AvailableRerankers: RerankerOption[] = BUILT_IN_RERANKERS;\n\n /** Live-preview state (P4.1). */\n public PreviewQuery = '';\n public PreviewIsRunning = false;\n public PreviewResults: SearchResultItem[] = [];\n public PreviewProviders: StreamingProviderStatus[] = [];\n public PreviewElapsedMs: number | null = null;\n public PreviewError: string | null = null;\n private previewSubscription: Subscription | null = null;\n private searchService = new SearchService();\n\n /**\n * P4.3 — A/B comparison via Kendall-tau between consecutive preview runs.\n * After RunPreview completes, the previous run's RecordIDs are diffed\n * against the current run and the rank-correlation similarity is shown\n * inline (\"82% similar to last run\"). Authors use this to immediately\n * see how much a reranker swap or fusion-weight tweak shifted the ranking.\n */\n private PreviousRunRecordIDs: string[] = [];\n public LastRunSimilarityPercent: number | null = null;\n\n public override ngOnDestroy(): void {\n this.previewSubscription?.unsubscribe();\n this.previewSubscription = null;\n }\n\n /**\n * P4.1 — run a streaming preview against this scope. Uses the same\n * SearchService.StreamSearch path the production search UI uses, scoped\n * to just this scope's ID. Renders progressively as each provider\n * reports back so authors can see chip-by-chip what each tuning change\n * actually affects.\n */\n public RunPreview(): void {\n if (!this.record?.ID || this.PreviewIsRunning) return;\n const query = this.PreviewQuery.trim();\n if (!query) return;\n\n // Tear down any previous run before starting a new one.\n this.previewSubscription?.unsubscribe();\n this.PreviewIsRunning = true;\n this.PreviewResults = [];\n this.PreviewProviders = [];\n this.PreviewElapsedMs = null;\n this.PreviewError = null;\n\n this.previewSubscription = this.searchService.StreamSearch({\n Query: query,\n MaxResults: 25,\n ActiveFilters: {},\n IncludeSources: ['vector', 'fulltext', 'entity', 'storage'],\n ScopeIDs: [this.record.ID],\n }).subscribe({\n next: (event) => {\n if (event.Phase === 'provider' && event.ProviderName) {\n this.PreviewProviders = [\n ...this.PreviewProviders,\n {\n Name: event.ProviderName,\n Count: event.Results?.length ?? 0,\n ElapsedMs: event.ElapsedMs ?? 0,\n State: 'Completed',\n },\n ];\n if (event.Results) {\n this.PreviewResults = [...this.PreviewResults, ...event.Results].sort((a, b) => b.Score - a.Score);\n }\n } else if (event.Phase === 'final' && event.Results) {\n this.PreviewResults = [...event.Results].sort((a, b) => b.Score - a.Score);\n this.PreviewElapsedMs = event.ElapsedMs ?? null;\n }\n },\n error: (err: Error) => {\n this.PreviewError = err.message ?? String(err);\n this.PreviewIsRunning = false;\n },\n complete: () => {\n this.PreviewIsRunning = false;\n // Compute Kendall-tau against the prior run, then capture this\n // run's order as the next baseline.\n const currentIDs = this.PreviewResults.map(r => r.RecordID);\n if (this.PreviousRunRecordIDs.length > 0 && currentIDs.length > 0) {\n const tau = MJSearchScopeFormComponentExtended.kendallTauOnSharedItems(\n this.PreviousRunRecordIDs,\n currentIDs,\n );\n if (tau !== null) {\n // Map [-1, 1] tau onto a [0, 100] \"% similar\" gauge so non-stats\n // authors can read it. -1 (reverse) = 0%, 0 (uncorrelated) = 50%,\n // +1 (identical) = 100%.\n this.LastRunSimilarityPercent = Math.round((tau + 1) * 50);\n }\n }\n this.PreviousRunRecordIDs = currentIDs;\n },\n });\n }\n\n public CancelPreview(): void {\n this.previewSubscription?.unsubscribe();\n this.previewSubscription = null;\n this.PreviewIsRunning = false;\n }\n\n /**\n * Compute Kendall-tau rank correlation on the items present in both lists.\n * Items only in one list are ignored (partial-overlap handling). Returns\n * null when the shared overlap is too small (< 2 items) to be meaningful.\n *\n * Tau formula: (concordant - discordant) / (N * (N-1) / 2)\n * where concordant = pairs ranked in the same order in both lists,\n * discordant = pairs ranked in opposite order, N = shared item count.\n */\n private static kendallTauOnSharedItems(listA: string[], listB: string[]): number | null {\n const rankA = new Map(listA.map((id, i) => [id, i]));\n const rankB = new Map(listB.map((id, i) => [id, i]));\n const shared = listA.filter(id => rankB.has(id));\n const n = shared.length;\n if (n < 2) return null;\n let concordant = 0;\n let discordant = 0;\n for (let i = 0; i < n; i++) {\n for (let j = i + 1; j < n; j++) {\n const a = (rankA.get(shared[i])! - rankA.get(shared[j])!);\n const b = (rankB.get(shared[i])! - rankB.get(shared[j])!);\n const product = a * b;\n if (product > 0) concordant++;\n else if (product < 0) discordant++;\n // Ties (product === 0) ignored — items at same rank\n }\n }\n const totalPairs = (n * (n - 1)) / 2;\n if (totalPairs === 0) return null;\n return (concordant - discordant) / totalPairs;\n }\n\n /**\n * Override the section list to include the new \"Reranker\" section before\n * \"Details\". The generated `initSections()` doesn't know about our custom\n * section so we replace the list. Order matches the template's render order.\n */\n public override async ngOnInit(): Promise<void> {\n await super.ngOnInit();\n this.initSections([\n { sectionKey: 'scopeDefinition', sectionName: 'Scope Definition', isExpanded: true },\n { sectionKey: 'scopeConfiguration', sectionName: 'Scope Configuration', isExpanded: true },\n { sectionKey: 'accessControl', sectionName: 'Access Control', isExpanded: false },\n { sectionKey: 'lifecycleManagement', sectionName: 'Lifecycle Management', isExpanded: false },\n { sectionKey: 'technicalConfiguration', sectionName: 'Technical Configuration', isExpanded: false },\n { sectionKey: 'fusionWeights', sectionName: 'Fusion Weights', isExpanded: false },\n { sectionKey: 'reranker', sectionName: 'Reranker', isExpanded: false },\n { sectionKey: 'livePreview', sectionName: 'Live Preview', isExpanded: false },\n { sectionKey: 'details', sectionName: 'Details', isExpanded: false },\n { sectionKey: 'systemMetadata', sectionName: 'System Metadata', isExpanded: false },\n { sectionKey: 'mJSearchScopeTestQueries', sectionName: 'Search Scope Test Queries', isExpanded: false },\n { sectionKey: 'mJSearchScopeStorageAccounts', sectionName: 'Search Scope Storage Accounts', isExpanded: false },\n { sectionKey: 'mJSearchScopeEntities', sectionName: 'Search Scope Entities', isExpanded: false },\n { sectionKey: 'mJSearchScopeExternalIndexes', sectionName: 'Search Scope External Indexes', isExpanded: false },\n { sectionKey: 'mJSearchScopeProviders', sectionName: 'Search Scope Providers', isExpanded: false },\n { sectionKey: 'mJAIAgentSearchScopes', sectionName: 'AI Agent Search Scopes', isExpanded: false },\n { sectionKey: 'mJSearchScopePermissions', sectionName: 'Search Scope Permissions', isExpanded: false },\n ]);\n }\n\n /**\n * Currently-selected reranker driver class, parsed from `record.ScopeConfig`.\n * Empty string means \"no reranker explicitly chosen\" — runtime defaults\n * to NoopReRanker. Stored as `ScopeConfig.reRanker.driverClass`.\n */\n public get SelectedRerankerDriverClass(): string {\n const cfg = this.parseScopeConfig();\n return (cfg?.['reRanker'] as { driverClass?: string } | undefined)?.driverClass ?? '';\n }\n\n public set SelectedRerankerDriverClass(value: string) {\n const cfg = this.parseScopeConfig() ?? {};\n const reRanker = (cfg['reRanker'] as Record<string, unknown> | undefined) ?? {};\n if (value && value.trim().length > 0) {\n reRanker['driverClass'] = value;\n } else {\n delete reRanker['driverClass'];\n }\n cfg['reRanker'] = reRanker;\n this.record.ScopeConfig = JSON.stringify(cfg, null, 2);\n }\n\n /**\n * Whether the currently-selected reranker incurs API cost — used to render\n * an inline cost-warning indicator next to the dropdown.\n */\n public get SelectedRerankerHasCost(): boolean {\n const driver = this.SelectedRerankerDriverClass;\n return BUILT_IN_RERANKERS.find(r => r.DriverClass === driver)?.HasCost ?? false;\n }\n\n /**\n * Whether the CSV export is currently running. Drives the button's disabled\n * state + spinner.\n */\n public IsExportingTuningCsv = false;\n\n /**\n * P4.2 — fusion weight sliders for each canonical SearchEngine source type.\n * Backed by `SearchScope.ScopeConfig.fusionWeights` JSON (the runtime path\n * — see plans/search-scopes-rag-plus/RAG_plan.md §8 Multi-Scope RRF Fusion). Plan task originally\n * proposed `SearchScopeProvider.Weight` but that column doesn't exist in\n * Phase 1; the JSON path is the actual contract the SearchEngine reads.\n */\n private _fusionWeights: FusionWeightRow[] | null = null;\n\n public get FusionWeights(): FusionWeightRow[] {\n if (!this._fusionWeights) {\n const cfg = this.parseScopeConfig();\n const stored = (cfg?.['fusionWeights'] as Record<string, unknown> | undefined) ?? {};\n this._fusionWeights = BUILT_IN_SOURCE_TYPES.map(key => {\n const value = stored[key];\n const weight = typeof value === 'number' && Number.isFinite(value) ? value : 1;\n return { Key: key, Label: key, Weight: weight };\n });\n }\n return this._fusionWeights;\n }\n\n /**\n * Persist a fusion weight change back to `ScopeConfig.fusionWeights`. The\n * caller is the slider's `(change)` event so writes happen only on\n * slide-end, not on every drag tick.\n */\n public OnFusionWeightChanged(row: FusionWeightRow, raw: number | string): void {\n const value = typeof raw === 'number' ? raw : Number(raw);\n if (!Number.isFinite(value)) return;\n row.Weight = value;\n\n const cfg = this.parseScopeConfig() ?? {};\n const weights = (cfg['fusionWeights'] as Record<string, unknown> | undefined) ?? {};\n if (Math.abs(value - 1) < 0.001) {\n // Default value — drop the explicit override so future engine-default\n // changes flow through naturally.\n delete weights[row.Key];\n } else {\n weights[row.Key] = +value.toFixed(2);\n }\n if (Object.keys(weights).length > 0) {\n cfg['fusionWeights'] = weights;\n } else {\n delete cfg['fusionWeights'];\n }\n this.record.ScopeConfig = JSON.stringify(cfg, null, 2);\n }\n\n /**\n * P3.4 — export the last 500 SearchExecutionLog rows for this scope as CSV.\n * Used by scope authors for offline tuning analysis (open in a spreadsheet,\n * pivot by reranker / status / latency, etc.). Filtered to this scope's ID\n * so multi-tenant deployments don't leak other scopes' query history.\n */\n public async ExportTuningCsv(): Promise<void> {\n if (!this.record?.ID || this.IsExportingTuningCsv) return;\n this.IsExportingTuningCsv = true;\n try {\n const rv = new RunView();\n const result = await rv.RunView<MJSearchExecutionLogEntityType>({\n EntityName: 'MJ: Search Execution Logs',\n // Constrain to the columns the CSV writer actually emits — avoids\n // pulling the wider entity (per Section 6.8).\n Fields: [\n '__mj_CreatedAt', 'Status', 'Query', 'ResultCount', 'TotalDurationMs',\n 'RerankerName', 'RerankerCostCents', 'FailureReason', 'UserID', 'AIAgentID',\n ],\n ExtraFilter: `SearchScopeID='${this.record.ID.replace(/'/g, \"''\")}'`,\n OrderBy: '__mj_CreatedAt DESC',\n MaxRows: 500,\n ResultType: 'simple',\n });\n if (!result.Success) {\n LogError(`SearchScope CSV export failed: ${result.ErrorMessage ?? 'unknown error'}`);\n return;\n }\n const rows = (result.Results ?? []) as MJSearchExecutionLogEntityType[];\n this.downloadCsv(rows);\n } finally {\n this.IsExportingTuningCsv = false;\n }\n }\n\n private downloadCsv(rows: MJSearchExecutionLogEntityType[]): void {\n const headers = [\n 'CreatedAt', 'Status', 'Query', 'ResultCount', 'TotalDurationMs',\n 'RerankerName', 'RerankerCostCents', 'FailureReason', 'UserID', 'AIAgentID',\n ];\n const lines = [headers.join(',')];\n for (const r of rows) {\n const cells = [\n this.escapeCsv(String(r.__mj_CreatedAt ?? '')),\n this.escapeCsv(String(r.Status ?? '')),\n this.escapeCsv(String(r.Query ?? '')),\n String(r.ResultCount ?? 0),\n String(r.TotalDurationMs ?? 0),\n this.escapeCsv(String(r.RerankerName ?? '')),\n String(r.RerankerCostCents ?? ''),\n this.escapeCsv(String(r.FailureReason ?? '')),\n String(r.UserID ?? ''),\n String(r.AIAgentID ?? ''),\n ];\n lines.push(cells.join(','));\n }\n const blob = new Blob([lines.join('\\n')], { type: 'text/csv;charset=utf-8;' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.setAttribute('href', url);\n const name = (this.record?.Name ?? 'scope').replace(/[^\\w\\-]+/g, '_');\n link.setAttribute('download', `searchscope-tuning-${name}-${new Date().toISOString().split('T')[0]}.csv`);\n link.style.visibility = 'hidden';\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n }\n\n private escapeCsv(value: string): string {\n if (value == null) return '';\n // Quote when the value contains a comma, quote, newline, or starts with\n // formula-injection characters. Inside a quoted value, escape inner\n // quotes by doubling.\n if (/[\",\\n\\r]/.test(value) || /^[=+\\-@]/.test(value)) {\n return `\"${value.replace(/\"/g, '\"\"')}\"`;\n }\n return value;\n }\n\n private parseScopeConfig(): Record<string, unknown> | null {\n if (!this.record?.ScopeConfig) return null;\n try {\n const parsed = JSON.parse(this.record.ScopeConfig);\n return (parsed && typeof parsed === 'object') ? parsed as Record<string, unknown> : null;\n } catch {\n return null;\n }\n }\n}\n\nexport function LoadMJSearchScopeFormComponentExtended(): void {\n // Tree-shake prevention; called from custom-forms.module's LoadCoreCustomForms()\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const _ref = MJSearchScopeFormComponentExtended;\n}\n","<mj-record-form-container [Record]=\"record\" [FormComponent]=\"this\"\n (Navigate)=\"OnFormNavigate($event)\"\n (DeleteRequested)=\"OnDeleteRequested()\"\n (FavoriteToggled)=\"OnFavoriteToggled()\"\n (HistoryRequested)=\"OnHistoryRequested()\"\n (ListManagementRequested)=\"OnListManagementRequested()\">\n\n <!-- ========================================\n FIELD PANELS\n ======================================== -->\n <!-- Scope Definition Section -->\n <mj-collapsible-panel\n SectionKey=\"scopeDefinition\"\n SectionName=\"Scope Definition\"\n Icon=\"fa fa-info-circle\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field \n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"Name\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field \n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"Description\"\n Type=\"textarea\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field \n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"Icon\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n\n <!-- Scope Configuration Section -->\n <mj-collapsible-panel\n SectionKey=\"scopeConfiguration\"\n SectionName=\"Scope Configuration\"\n Icon=\"fa fa-sliders-h\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field \n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"IsGlobal\"\n Type=\"checkbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field \n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"IsDefault\"\n Type=\"checkbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n\n <!-- Access Control Section -->\n <mj-collapsible-panel\n SectionKey=\"accessControl\"\n SectionName=\"Access Control\"\n Icon=\"fa fa-lock\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field \n [Record]=\"record\"\n [ShowLabel]=\"false\"\n FieldName=\"OwnerUserID\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n LinkType=\"Record\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n\n <!-- Lifecycle Management Section -->\n <mj-collapsible-panel\n SectionKey=\"lifecycleManagement\"\n SectionName=\"Lifecycle Management\"\n Icon=\"fa fa-clock\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field \n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"Status\"\n Type=\"select\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field \n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"StartAt\"\n Type=\"datepicker\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field \n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"EndAt\"\n Type=\"datepicker\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n\n <!-- Technical Configuration Section -->\n <mj-collapsible-panel\n SectionKey=\"technicalConfiguration\"\n SectionName=\"Technical Configuration\"\n Icon=\"fa fa-code\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field \n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"ScopeConfig\"\n Type=\"code\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field \n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"SearchContextConfig\"\n Type=\"code\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n\n <!-- Fusion Weights Section (custom — P4.2).\n Sliders for each canonical SearchEngine source type, backed by\n SearchScope.ScopeConfig.fusionWeights JSON. Weights >1 amplify a\n provider's contribution; weights <1 dampen it. Default 1 = engine\n default (no override). Plan-doc estimated SearchScopeProvider.Weight\n but that column doesn't exist; the JSON path is the actual contract\n the SearchEngine reads. -->\n <mj-collapsible-panel\n SectionKey=\"fusionWeights\"\n SectionName=\"Fusion Weights\"\n Icon=\"fa fa-sliders-h\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <div class=\"fusion-weights\">\n @for (row of FusionWeights; track row.Key) {\n <div class=\"fusion-weight-row\">\n <span class=\"fusion-weight-label\">{{ row.Label }}</span>\n <input\n class=\"fusion-weight-slider\"\n type=\"range\"\n min=\"0\"\n max=\"5\"\n step=\"0.1\"\n [disabled]=\"!EditMode\"\n [value]=\"row.Weight\"\n (change)=\"OnFusionWeightChanged(row, $any($event.target).valueAsNumber)\" />\n <span class=\"fusion-weight-value\">{{ row.Weight | number:'1.1-1' }}</span>\n </div>\n }\n <p class=\"fusion-weights-help\">\n Drag a slider to update <code>ScopeConfig.fusionWeights</code>. Default 1.0 means \"use engine default\";\n values are persisted on form save.\n </p>\n </div>\n </mj-collapsible-panel>\n\n <!-- Reranker Section (custom — P2D.7 Angular half).\n Dropdown writes the choice into ScopeConfig JSON's reRanker.driverClass —\n the same path SearchEngine reads at runtime via pickReRankerConfig().\n RerankerBudgetCents is rendered here too so the cost-cap input lives\n right next to the cost-incurring choice. -->\n <mj-collapsible-panel\n SectionKey=\"reranker\"\n SectionName=\"Reranker\"\n Icon=\"fa fa-sort-amount-down\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <div class=\"reranker-config\">\n <label class=\"reranker-config-label\">Reranker driver class</label>\n <select\n class=\"mj-input reranker-driver-select\"\n [disabled]=\"!EditMode\"\n [ngModel]=\"SelectedRerankerDriverClass\"\n (ngModelChange)=\"SelectedRerankerDriverClass = $event\">\n <option value=\"\">— None (use NoopReRanker) —</option>\n @for (option of AvailableRerankers; track option.DriverClass) {\n <option [value]=\"option.DriverClass\">\n {{ option.Name }}{{ option.HasCost ? ' — paid' : ' — free' }}\n </option>\n }\n </select>\n @if (SelectedRerankerHasCost) {\n <p class=\"reranker-cost-hint\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n This reranker incurs API cost per search. Set\n <strong>RerankerBudgetCents</strong> below to cap spend per invocation.\n </p>\n }\n <p class=\"reranker-help-hint\">\n Stored on <code>ScopeConfig.reRanker.driverClass</code> — the SearchEngine reads this at runtime.\n Leave blank to use the pass-through default.\n </p>\n\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"RerankerBudgetCents\"\n Type=\"number\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n\n <!-- P3.4 — per-scope tuning CSV export.\n Pulls the last 500 rows from MJ: Search Execution Logs filtered\n to this scope's ID and downloads as CSV for offline analysis. -->\n <div class=\"reranker-export-row\">\n <button class=\"reranker-export-btn\"\n type=\"button\"\n [disabled]=\"!record?.ID || IsExportingTuningCsv\"\n (click)=\"ExportTuningCsv()\">\n @if (IsExportingTuningCsv) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Exporting…</span>\n } @else {\n <i class=\"fa-solid fa-download\"></i>\n <span>Export tuning data (CSV)</span>\n }\n </button>\n <span class=\"reranker-export-hint\">Last 500 search invocations against this scope.</span>\n </div>\n </div>\n </mj-collapsible-panel>\n\n <!-- Live Preview Section (custom — P4.1).\n Streaming search against this scope, rendered with chip-strip + result\n list so authors can see how each tuning change (reranker, fusion\n weights, scope template) affects the actual ranked output. -->\n <mj-collapsible-panel\n SectionKey=\"livePreview\"\n SectionName=\"Live Preview\"\n Icon=\"fa fa-flask\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <div class=\"live-preview\">\n <div class=\"live-preview-input-row\">\n <input\n class=\"mj-input live-preview-input\"\n type=\"text\"\n placeholder=\"Type a sample query and press Run…\"\n [disabled]=\"!record?.ID || PreviewIsRunning\"\n [value]=\"PreviewQuery\"\n (input)=\"PreviewQuery = $any($event.target).value\"\n (keydown.enter)=\"RunPreview()\" />\n @if (!PreviewIsRunning) {\n <button class=\"live-preview-btn\"\n type=\"button\"\n [disabled]=\"!record?.ID || !PreviewQuery.trim()\"\n (click)=\"RunPreview()\">\n <i class=\"fa-solid fa-play\"></i> Run\n </button>\n } @else {\n <button class=\"live-preview-btn live-preview-btn-cancel\"\n type=\"button\"\n (click)=\"CancelPreview()\">\n <i class=\"fa-solid fa-stop\"></i> Cancel\n </button>\n }\n </div>\n\n @if (PreviewError) {\n <p class=\"live-preview-error\">\n <i class=\"fa-solid fa-circle-exclamation\"></i> {{ PreviewError }}\n </p>\n }\n\n @if (PreviewIsRunning || PreviewProviders.length > 0) {\n <div class=\"live-preview-chips\">\n @if (PreviewIsRunning && PreviewProviders.length === 0) {\n <span class=\"live-preview-chip live-preview-chip-pending\">\n <i class=\"fa-solid fa-circle-notch fa-spin\"></i> Streaming…\n </span>\n }\n @for (p of PreviewProviders; track p.Name) {\n <span class=\"live-preview-chip live-preview-chip-completed\">\n <i class=\"fa-solid fa-check\"></i>\n <strong>{{ p.Name }}</strong>\n <span class=\"live-preview-chip-count\">{{ p.Count }}</span>\n <span class=\"live-preview-chip-time\">{{ p.ElapsedMs }}ms</span>\n </span>\n }\n </div>\n }\n\n @if (PreviewResults.length > 0) {\n <div class=\"live-preview-results\">\n <div class=\"live-preview-results-header\">\n {{ PreviewResults.length }} result(s)\n @if (PreviewElapsedMs !== null) { in {{ PreviewElapsedMs }}ms }\n @if (LastRunSimilarityPercent !== null) {\n <span class=\"live-preview-similarity\"\n [class.live-preview-similarity-low]=\"LastRunSimilarityPercent < 70\"\n title=\"Kendall-tau rank correlation against the previous run, mapped to [0%, 100%].\">\n · {{ LastRunSimilarityPercent }}% similar to last run\n </span>\n }\n </div>\n @for (r of PreviewResults; track r.ID; let i = $index) {\n @if (i < 10) {\n <div class=\"live-preview-result\">\n <span class=\"live-preview-result-score\">{{ (r.Score * 100) | number:'1.0-0' }}%</span>\n <span class=\"live-preview-result-title\">{{ r.Title }}</span>\n <span class=\"live-preview-result-entity\">{{ r.EntityName }}</span>\n </div>\n }\n }\n @if (PreviewResults.length > 10) {\n <p class=\"live-preview-truncated\">…and {{ PreviewResults.length - 10 }} more (preview shows top 10).</p>\n }\n </div>\n }\n </div>\n </mj-collapsible-panel>\n\n <!-- Details Section (kept empty — RerankerBudgetCents now lives in the\n Reranker section above where it semantically belongs) -->\n <mj-collapsible-panel\n SectionKey=\"details\"\n SectionName=\"Details\"\n Icon=\"fa fa-align-left\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n </mj-collapsible-panel>\n\n <!-- System Metadata Section -->\n <mj-collapsible-panel\n SectionKey=\"systemMetadata\"\n SectionName=\"System Metadata\"\n Icon=\"fa fa-cog\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field \n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"__mj_CreatedAt\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field \n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"__mj_UpdatedAt\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n\n <!-- ========================================\n RELATED ENTITY PANELS\n ======================================== -->\n\n <!-- Search Scope Test Queries Section (P4.4) — canonical test queries for\n offline tuning. Authors save representative queries here, re-run them\n after a config change, and compare results. -->\n <mj-collapsible-panel\n SectionKey=\"mJSearchScopeTestQueries\"\n SectionName=\"Search Scope Test Queries\"\n Icon=\"fa fa-table\"\n Variant=\"related-entity\"\n [Form]=\"this\"\n [FormContext]=\"formContext\"\n [BadgeCount]=\"GetSectionRowCount('mJSearchScopeTestQueries')\"\n [DefaultExpanded]=\"false\">\n @if (record.IsSaved) {\n <div>\n <mj-explorer-entity-data-grid\n [Params]=\"BuildRelationshipViewParamsByEntityName('MJ: Search Scope Test Queries','SearchScopeID')\"\n [NewRecordValues]=\"NewRecordValues('MJ: Search Scope Test Queries')\"\n [AllowLoad]=\"IsSectionExpanded('mJSearchScopeTestQueries')\"\n [ShowToolbar]=\"true\"\n (Navigate)=\"OnFormNavigate($event)\"\n (AfterDataLoad)=\"SetSectionRowCount('mJSearchScopeTestQueries', $event.totalRowCount)\"\n >\n </mj-explorer-entity-data-grid>\n </div>\n }\n </mj-collapsible-panel>\n\n <!-- Search Scope Storage Accounts Section -->\n <mj-collapsible-panel\n SectionKey=\"mJSearchScopeStorageAccounts\"\n SectionName=\"Search Scope Storage Accounts\"\n Icon=\"fa fa-folder-open\"\n Variant=\"related-entity\"\n [Form]=\"this\"\n [FormContext]=\"formContext\"\n [BadgeCount]=\"GetSectionRowCount('mJSearchScopeStorageAccounts')\"\n [DefaultExpanded]=\"false\">\n @if (record.IsSaved) {\n <div>\n <mj-explorer-entity-data-grid\n [Params]=\"BuildRelationshipViewParamsByEntityName('MJ: Search Scope Storage Accounts','SearchScopeID')\"\n [NewRecordValues]=\"NewRecordValues('MJ: Search Scope Storage Accounts')\"\n [AllowLoad]=\"IsSectionExpanded('mJSearchScopeStorageAccounts')\"\n [ShowToolbar]=\"true\"\n (Navigate)=\"OnFormNavigate($event)\"\n (AfterDataLoad)=\"SetSectionRowCount('mJSearchScopeStorageAccounts', $event.totalRowCount)\"\n >\n </mj-explorer-entity-data-grid>\n </div>\n }\n </mj-collapsible-panel>\n\n <!-- Search Scope Entities Section -->\n <mj-collapsible-panel\n SectionKey=\"mJSearchScopeEntities\"\n SectionName=\"Search Scope Entities\"\n Icon=\"fa fa-search\"\n Variant=\"related-entity\"\n [Form]=\"this\"\n [FormContext]=\"formContext\"\n [BadgeCount]=\"GetSectionRowCount('mJSearchScopeEntities')\"\n [DefaultExpanded]=\"false\">\n @if (record.IsSaved) {\n <div>\n <mj-explorer-entity-data-grid\n [Params]=\"BuildRelationshipViewParamsByEntityName('MJ: Search Scope Entities','SearchScopeID')\"\n [NewRecordValues]=\"NewRecordValues('MJ: Search Scope Entities')\"\n [AllowLoad]=\"IsSectionExpanded('mJSearchScopeEntities')\"\n [ShowToolbar]=\"true\"\n (Navigate)=\"OnFormNavigate($event)\"\n (AfterDataLoad)=\"SetSectionRowCount('mJSearchScopeEntities', $event.totalRowCount)\"\n >\n </mj-explorer-entity-data-grid>\n </div>\n }\n </mj-collapsible-panel>\n\n <!-- Search Scope External Indexes Section -->\n <mj-collapsible-panel\n SectionKey=\"mJSearchScopeExternalIndexes\"\n SectionName=\"Search Scope External Indexes\"\n Icon=\"fa fa-search-plus\"\n Variant=\"related-entity\"\n [Form]=\"this\"\n [FormContext]=\"formContext\"\n [BadgeCount]=\"GetSectionRowCount('mJSearchScopeExternalIndexes')\"\n [DefaultExpanded]=\"false\">\n @if (record.IsSaved) {\n <div>\n <mj-explorer-entity-data-grid\n [Params]=\"BuildRelationshipViewParamsByEntityName('MJ: Search Scope External Indexes','SearchScopeID')\"\n [NewRecordValues]=\"NewRecordValues('MJ: Search Scope External Indexes')\"\n [AllowLoad]=\"IsSectionExpanded('mJSearchScopeExternalIndexes')\"\n [ShowToolbar]=\"true\"\n (Navigate)=\"OnFormNavigate($event)\"\n (AfterDataLoad)=\"SetSectionRowCount('mJSearchScopeExternalIndexes', $event.totalRowCount)\"\n >\n </mj-explorer-entity-data-grid>\n </div>\n }\n </mj-collapsible-panel>\n\n <!-- Search Scope Providers Section -->\n <mj-collapsible-panel\n SectionKey=\"mJSearchScopeProviders\"\n SectionName=\"Search Scope Providers\"\n Icon=\"fa fa-search-plus\"\n Variant=\"related-entity\"\n [Form]=\"this\"\n [FormContext]=\"formContext\"\n [BadgeCount]=\"GetSectionRowCount('mJSearchScopeProviders')\"\n [DefaultExpanded]=\"false\">\n @if (record.IsSaved) {\n <div>\n <mj-explorer-entity-data-grid\n [Params]=\"BuildRelationshipViewParamsByEntityName('MJ: Search Scope Providers','SearchScopeID')\"\n [NewRecordValues]=\"NewRecordValues('MJ: Search Scope Providers')\"\n [AllowLoad]=\"IsSectionExpanded('mJSearchScopeProviders')\"\n [ShowToolbar]=\"true\"\n (Navigate)=\"OnFormNavigate($event)\"\n (AfterDataLoad)=\"SetSectionRowCount('mJSearchScopeProviders', $event.totalRowCount)\"\n >\n </mj-explorer-entity-data-grid>\n </div>\n }\n </mj-collapsible-panel>\n\n <!-- AI Agent Search Scopes Section -->\n <mj-collapsible-panel\n SectionKey=\"mJAIAgentSearchScopes\"\n SectionName=\"AI Agent Search Scopes\"\n Icon=\"fa fa-search-plus\"\n Variant=\"related-entity\"\n [Form]=\"this\"\n [FormContext]=\"formContext\"\n [BadgeCount]=\"GetSectionRowCount('mJAIAgentSearchScopes')\"\n [DefaultExpanded]=\"false\">\n @if (record.IsSaved) {\n <div>\n <mj-explorer-entity-data-grid\n [Params]=\"BuildRelationshipViewParamsByEntityName('MJ: AI Agent Search Scopes','SearchScopeID')\"\n [NewRecordValues]=\"NewRecordValues('MJ: AI Agent Search Scopes')\"\n [AllowLoad]=\"IsSectionExpanded('mJAIAgentSearchScopes')\"\n [ShowToolbar]=\"true\"\n (Navigate)=\"OnFormNavigate($event)\"\n (AfterDataLoad)=\"SetSectionRowCount('mJAIAgentSearchScopes', $event.totalRowCount)\"\n >\n </mj-explorer-entity-data-grid>\n </div>\n }\n </mj-collapsible-panel>\n\n <!-- Search Scope Permissions Section -->\n <mj-collapsible-panel\n SectionKey=\"mJSearchScopePermissions\"\n SectionName=\"Search Scope Permissions\"\n Icon=\"fa fa-table\"\n Variant=\"related-entity\"\n [Form]=\"this\"\n [FormContext]=\"formContext\"\n [BadgeCount]=\"GetSectionRowCount('mJSearchScopePermissions')\"\n [DefaultExpanded]=\"false\">\n @if (record.IsSaved) {\n <div>\n <mj-explorer-entity-data-grid\n [Params]=\"BuildRelationshipViewParamsByEntityName('MJ: Search Scope Permissions','SearchScopeID')\"\n [NewRecordValues]=\"NewRecordValues('MJ: Search Scope Permissions')\"\n [AllowLoad]=\"IsSectionExpanded('mJSearchScopePermissions')\"\n [ShowToolbar]=\"true\"\n (Navigate)=\"OnFormNavigate($event)\"\n (AfterDataLoad)=\"SetSectionRowCount('mJSearchScopePermissions', $event.totalRowCount)\"\n >\n </mj-explorer-entity-data-grid>\n </div>\n }\n </mj-collapsible-panel>\n\n <!-- Search Execution Logs Section -->\n <mj-collapsible-panel\n SectionKey=\"mJSearchExecutionLogs\"\n SectionName=\"Search Execution Logs\"\n Icon=\"fa fa-table\"\n Variant=\"related-entity\"\n [Form]=\"this\"\n [FormContext]=\"formContext\"\n [BadgeCount]=\"GetSectionRowCount('mJSearchExecutionLogs')\"\n [DefaultExpanded]=\"false\">\n @if (record.IsSaved) {\n <div>\n <mj-explorer-entity-data-grid\n [Params]=\"BuildRelationshipViewParamsByEntityName('MJ: Search Execution Logs','SearchScopeID')\"\n [NewRecordValues]=\"NewRecordValues('MJ: Search Execution Logs')\"\n [AllowLoad]=\"IsSectionExpanded('mJSearchExecutionLogs')\"\n [ShowToolbar]=\"false\"\n (Navigate)=\"OnFormNavigate($event)\"\n (AfterDataLoad)=\"SetSectionRowCount('mJSearchExecutionLogs', $event.totalRowCount)\"\n >\n </mj-explorer-entity-data-grid>\n </div>\n }\n </mj-collapsible-panel>\n</mj-record-form-container>\n "]}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Custom MJSearchScopeProvider form (P5.5).
3
+ *
4
+ * Plan acceptance criterion: provide a dropdown for `SearchProviderID` so
5
+ * scope authors don't have to look up GUIDs by hand. The dropdown is sourced
6
+ * from the `MJ: Search Providers` table (those rows are the canonical FK
7
+ * targets), and each option is annotated with whether the provider's
8
+ * `DriverClass` is currently registered with the runtime ClassFactory on
9
+ * this MJServer build — so authors can see at a glance whether their pick
10
+ * will actually be available at search time.
11
+ *
12
+ * The runtime registration list comes from the `AvailableSearchProviders`
13
+ * GraphQL query backed by `BaseSearchProvider.GetAvailableProviders()`.
14
+ * That query is the canonical "which providers does this server know
15
+ * about" source — same helper Phase 5.5 of the RAG plan calls out.
16
+ */
17
+ import { OnInit } from '@angular/core';
18
+ import { MJSearchScopeProviderEntity } from '@memberjunction/core-entities';
19
+ import { MJSearchScopeProviderFormComponent } from '../../generated/Entities/MJSearchScopeProvider/mjsearchscopeprovider.form.component';
20
+ import * as i0 from "@angular/core";
21
+ interface SearchProviderOption {
22
+ ID: string;
23
+ Name: string;
24
+ DriverClass: string;
25
+ Status: 'Active' | 'Pending' | 'Terminated';
26
+ /**
27
+ * `true` if `DriverClass` matches a class currently registered with the
28
+ * runtime ClassFactory on this MJServer. `false` means the row exists in
29
+ * `MJ: Search Providers` but no installed package registers that class —
30
+ * picking it would result in `IsAvailable()=false` at search time.
31
+ */
32
+ IsRegisteredOnServer: boolean;
33
+ }
34
+ export declare class MJSearchScopeProviderFormComponentExtended extends MJSearchScopeProviderFormComponent implements OnInit {
35
+ record: MJSearchScopeProviderEntity;
36
+ AvailableProviders: SearchProviderOption[];
37
+ ProvidersLoaded: boolean;
38
+ LoadError: string | null;
39
+ /**
40
+ * Drives the dropdown's `[ngModel]`. Kept in sync with `record.SearchProviderID`
41
+ * via the setter so dirty tracking and the form's save flow continue to work.
42
+ */
43
+ get SelectedSearchProviderID(): string;
44
+ set SelectedSearchProviderID(value: string);
45
+ get SelectedProvider(): SearchProviderOption | null;
46
+ get SelectedProviderUnregisteredOnServer(): boolean;
47
+ ngOnInit(): Promise<void>;
48
+ /**
49
+ * Pulls the `MJ: Search Providers` rows and the server-registered class list
50
+ * in parallel, then merges into one dropdown source. Failures don't block the
51
+ * form — the dropdown just disables itself, leaving the underlying generated
52
+ * textbox accessible via `EditMode`.
53
+ */
54
+ private loadProviderCatalog;
55
+ /**
56
+ * Calls the `AvailableSearchProviders` GraphQL query to learn which
57
+ * `DriverClass` keys are actually registered with `MJGlobal.ClassFactory`
58
+ * on the server. Returns `[]` on any failure — the dropdown still renders
59
+ * from the DB rows; we just lose the "(not registered)" badge.
60
+ */
61
+ private fetchRegisteredDriverClasses;
62
+ static ɵfac: i0.ɵɵFactoryDeclaration<MJSearchScopeProviderFormComponentExtended, never>;
63
+ static ɵcmp: i0.ɵɵComponentDeclaration<MJSearchScopeProviderFormComponentExtended, "mj-searchscopeprovider-form-extended", never, {}, {}, never, never, false, never>;
64
+ }
65
+ export {};
66
+ //# sourceMappingURL=searchscopeprovider-form.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"searchscopeprovider-form.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/custom/SearchScopes/searchscopeprovider-form.component.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAa,MAAM,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,2BAA2B,EAA0B,MAAM,+BAA+B,CAAC;AAIpG,OAAO,EAAE,kCAAkC,EAAE,MAAM,qFAAqF,CAAC;;AAEzI,UAAU,oBAAoB;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,YAAY,CAAC;IAC5C;;;;;OAKG;IACH,oBAAoB,EAAE,OAAO,CAAC;CACjC;AAED,qBAOa,0CAA2C,SAAQ,kCAAmC,YAAW,MAAM;IAChG,MAAM,EAAG,2BAA2B,CAAC;IAE9C,kBAAkB,EAAE,oBAAoB,EAAE,CAAM;IAChD,eAAe,UAAS;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEvC;;;OAGG;IACH,IAAW,wBAAwB,IAAI,MAAM,CAE5C;IACD,IAAW,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAIhD;IAED,IAAW,gBAAgB,IAAI,oBAAoB,GAAG,IAAI,CAIzD;IAED,IAAW,oCAAoC,IAAI,OAAO,CAGzD;IAEc,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAKxC;;;;;OAKG;YACW,mBAAmB;IAmCjC;;;;;OAKG;YACW,4BAA4B;yCAnFjC,0CAA0C;2CAA1C,0CAA0C;CAmGtD"}
@@ -0,0 +1,253 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ /**
8
+ * Custom MJSearchScopeProvider form (P5.5).
9
+ *
10
+ * Plan acceptance criterion: provide a dropdown for `SearchProviderID` so
11
+ * scope authors don't have to look up GUIDs by hand. The dropdown is sourced
12
+ * from the `MJ: Search Providers` table (those rows are the canonical FK
13
+ * targets), and each option is annotated with whether the provider's
14
+ * `DriverClass` is currently registered with the runtime ClassFactory on
15
+ * this MJServer build — so authors can see at a glance whether their pick
16
+ * will actually be available at search time.
17
+ *
18
+ * The runtime registration list comes from the `AvailableSearchProviders`
19
+ * GraphQL query backed by `BaseSearchProvider.GetAvailableProviders()`.
20
+ * That query is the canonical "which providers does this server know
21
+ * about" source — same helper Phase 5.5 of the RAG plan calls out.
22
+ */
23
+ import { Component } from '@angular/core';
24
+ import { LogError, RunView } from '@memberjunction/core';
25
+ import { RegisterClass } from '@memberjunction/global';
26
+ import { BaseFormComponent } from '@memberjunction/ng-base-forms';
27
+ import { MJSearchScopeProviderFormComponent } from '../../generated/Entities/MJSearchScopeProvider/mjsearchscopeprovider.form.component';
28
+ import * as i0 from "@angular/core";
29
+ import * as i1 from "@angular/forms";
30
+ import * as i2 from "@memberjunction/ng-base-forms";
31
+ const _forTrack0 = ($index, $item) => $item.ID;
32
+ function MJSearchScopeProviderFormComponentExtended_Conditional_6_Template(rf, ctx) { if (rf & 1) {
33
+ i0.ɵɵelementStart(0, "p", 5);
34
+ i0.ɵɵelement(1, "i", 20);
35
+ i0.ɵɵtext(2);
36
+ i0.ɵɵelementEnd();
37
+ } if (rf & 2) {
38
+ const ctx_r0 = i0.ɵɵnextContext();
39
+ i0.ɵɵadvance(2);
40
+ i0.ɵɵtextInterpolate1(" Could not load provider catalog \u2014 ", ctx_r0.LoadError, " ");
41
+ } }
42
+ function MJSearchScopeProviderFormComponentExtended_For_11_Template(rf, ctx) { if (rf & 1) {
43
+ i0.ɵɵelementStart(0, "option", 8);
44
+ i0.ɵɵtext(1);
45
+ i0.ɵɵelementEnd();
46
+ } if (rf & 2) {
47
+ const option_r2 = ctx.$implicit;
48
+ i0.ɵɵproperty("value", option_r2.ID);
49
+ i0.ɵɵadvance();
50
+ i0.ɵɵtextInterpolate4(" ", option_r2.Name, " \u2014 ", option_r2.DriverClass, "", option_r2.IsRegisteredOnServer ? "" : " (not registered on this server)", "", option_r2.Status !== "Active" ? " [" + option_r2.Status + "]" : "", " ");
51
+ } }
52
+ function MJSearchScopeProviderFormComponentExtended_Conditional_12_Template(rf, ctx) { if (rf & 1) {
53
+ i0.ɵɵelementStart(0, "p", 9);
54
+ i0.ɵɵelement(1, "i", 21);
55
+ i0.ɵɵtext(2, " The selected provider's ");
56
+ i0.ɵɵelementStart(3, "code");
57
+ i0.ɵɵtext(4, "DriverClass");
58
+ i0.ɵɵelementEnd();
59
+ i0.ɵɵtext(5, " is not registered with this MJServer build. Searches using this ");
60
+ i0.ɵɵelementStart(6, "code");
61
+ i0.ɵɵtext(7, "SearchScopeProvider");
62
+ i0.ɵɵelementEnd();
63
+ i0.ɵɵtext(8, " will return no results until the package that registers ");
64
+ i0.ɵɵelementStart(9, "code");
65
+ i0.ɵɵtext(10);
66
+ i0.ɵɵelementEnd();
67
+ i0.ɵɵtext(11, " is installed. ");
68
+ i0.ɵɵelementEnd();
69
+ } if (rf & 2) {
70
+ const ctx_r0 = i0.ɵɵnextContext();
71
+ i0.ɵɵadvance(10);
72
+ i0.ɵɵtextInterpolate(ctx_r0.SelectedProvider == null ? null : ctx_r0.SelectedProvider.DriverClass);
73
+ } }
74
+ let MJSearchScopeProviderFormComponentExtended = class MJSearchScopeProviderFormComponentExtended extends MJSearchScopeProviderFormComponent {
75
+ constructor() {
76
+ super(...arguments);
77
+ this.AvailableProviders = [];
78
+ this.ProvidersLoaded = false;
79
+ this.LoadError = null;
80
+ }
81
+ /**
82
+ * Drives the dropdown's `[ngModel]`. Kept in sync with `record.SearchProviderID`
83
+ * via the setter so dirty tracking and the form's save flow continue to work.
84
+ */
85
+ get SelectedSearchProviderID() {
86
+ return this.record?.SearchProviderID ?? '';
87
+ }
88
+ set SelectedSearchProviderID(value) {
89
+ if (!this.record)
90
+ return;
91
+ if (this.record.SearchProviderID === value)
92
+ return;
93
+ this.record.SearchProviderID = value;
94
+ }
95
+ get SelectedProvider() {
96
+ const id = this.SelectedSearchProviderID;
97
+ if (!id)
98
+ return null;
99
+ return this.AvailableProviders.find(p => p.ID.toLowerCase() === id.toLowerCase()) ?? null;
100
+ }
101
+ get SelectedProviderUnregisteredOnServer() {
102
+ const sel = this.SelectedProvider;
103
+ return sel != null && !sel.IsRegisteredOnServer;
104
+ }
105
+ async ngOnInit() {
106
+ await super.ngOnInit();
107
+ await this.loadProviderCatalog();
108
+ }
109
+ /**
110
+ * Pulls the `MJ: Search Providers` rows and the server-registered class list
111
+ * in parallel, then merges into one dropdown source. Failures don't block the
112
+ * form — the dropdown just disables itself, leaving the underlying generated
113
+ * textbox accessible via `EditMode`.
114
+ */
115
+ async loadProviderCatalog() {
116
+ try {
117
+ const rv = new RunView();
118
+ const [rowsResult, registeredKeys] = await Promise.all([
119
+ rv.RunView({
120
+ EntityName: 'MJ: Search Providers',
121
+ OrderBy: 'Name',
122
+ ResultType: 'simple',
123
+ }),
124
+ this.fetchRegisteredDriverClasses(),
125
+ ]);
126
+ if (!rowsResult.Success) {
127
+ this.LoadError = rowsResult.ErrorMessage ?? 'Unknown error loading providers';
128
+ LogError(`MJSearchScopeProviderFormExtended: RunView failed: ${this.LoadError}`);
129
+ return;
130
+ }
131
+ const registeredSet = new Set(registeredKeys.map(k => k.toLowerCase()));
132
+ const rows = rowsResult.Results ?? [];
133
+ this.AvailableProviders = rows.map(row => ({
134
+ ID: row.ID,
135
+ Name: row.Name,
136
+ DriverClass: row.DriverClass,
137
+ Status: row.Status,
138
+ IsRegisteredOnServer: registeredSet.has(row.DriverClass.toLowerCase()),
139
+ }));
140
+ this.ProvidersLoaded = true;
141
+ }
142
+ catch (err) {
143
+ const msg = err instanceof Error ? err.message : String(err);
144
+ this.LoadError = msg;
145
+ LogError(`MJSearchScopeProviderFormExtended: catalog load threw: ${msg}`);
146
+ }
147
+ }
148
+ /**
149
+ * Calls the `AvailableSearchProviders` GraphQL query to learn which
150
+ * `DriverClass` keys are actually registered with `MJGlobal.ClassFactory`
151
+ * on the server. Returns `[]` on any failure — the dropdown still renders
152
+ * from the DB rows; we just lose the "(not registered)" badge.
153
+ */
154
+ async fetchRegisteredDriverClasses() {
155
+ try {
156
+ const dataProvider = this.ProviderToUse;
157
+ const response = await dataProvider.ExecuteGQL(`query AvailableSearchProviders { AvailableSearchProviders { DriverClass SourceType } }`, {});
158
+ return (response?.AvailableSearchProviders ?? []).map(r => r.DriverClass);
159
+ }
160
+ catch (err) {
161
+ // Older server build won't have the resolver. The dropdown still
162
+ // works from DB rows; the registration badge just won't appear.
163
+ const msg = err instanceof Error ? err.message : String(err);
164
+ LogError(`MJSearchScopeProviderFormExtended: AvailableSearchProviders query failed (badge disabled): ${msg}`);
165
+ return [];
166
+ }
167
+ }
168
+ static { this.ɵfac = /*@__PURE__*/ (() => { let ɵMJSearchScopeProviderFormComponentExtended_BaseFactory; return function MJSearchScopeProviderFormComponentExtended_Factory(__ngFactoryType__) { return (ɵMJSearchScopeProviderFormComponentExtended_BaseFactory || (ɵMJSearchScopeProviderFormComponentExtended_BaseFactory = i0.ɵɵgetInheritedFactory(MJSearchScopeProviderFormComponentExtended)))(__ngFactoryType__ || MJSearchScopeProviderFormComponentExtended); }; })(); }
169
+ static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJSearchScopeProviderFormComponentExtended, selectors: [["mj-searchscopeprovider-form-extended"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 33, vars: 42, consts: [[3, "Navigate", "DeleteRequested", "FavoriteToggled", "HistoryRequested", "ListManagementRequested", "Record", "FormComponent"], ["SectionKey", "searchConfiguration", "SectionName", "Search Configuration", "Icon", "fa fa-search", 3, "Form", "FormContext"], ["FieldName", "SearchScopeID", "Type", "textbox", "LinkType", "Record", 3, "Record", "ShowLabel", "EditMode", "FormContext"], [1, "provider-picker"], [1, "provider-picker-label"], [1, "provider-picker-error"], [1, "mj-input", "provider-picker-select", 3, "ngModelChange", "disabled", "ngModel"], ["value", ""], [3, "value"], [1, "provider-picker-warning"], [1, "provider-picker-help"], ["SectionKey", "operationalSettings", "SectionName", "Operational Settings", "Icon", "fa fa-sliders-h", 3, "Form", "FormContext"], ["FieldName", "Enabled", "Type", "checkbox", 3, "Record", "ShowLabel", "EditMode", "FormContext"], ["FieldName", "MaxResultsOverride", "Type", "number", 3, "Record", "ShowLabel", "EditMode", "FormContext"], ["FieldName", "ProviderConfigOverride", "Type", "code", 3, "Record", "ShowLabel", "EditMode", "FormContext"], ["SectionKey", "queryProcessing", "SectionName", "Query Processing", "Icon", "fa fa-magic", 3, "Form", "FormContext"], ["FieldName", "QueryTransformTemplateID", "Type", "textbox", "LinkType", "Record", 3, "Record", "ShowLabel", "EditMode", "FormContext"], ["SectionKey", "systemMetadata", "SectionName", "System Metadata", "Icon", "fa fa-cog", 3, "Form", "FormContext"], ["FieldName", "__mj_CreatedAt", "Type", "textbox", 3, "Record", "ShowLabel", "EditMode", "FormContext"], ["FieldName", "__mj_UpdatedAt", "Type", "textbox", 3, "Record", "ShowLabel", "EditMode", "FormContext"], [1, "fa-solid", "fa-circle-exclamation"], [1, "fa-solid", "fa-triangle-exclamation"]], template: function MJSearchScopeProviderFormComponentExtended_Template(rf, ctx) { if (rf & 1) {
170
+ i0.ɵɵelementStart(0, "mj-record-form-container", 0);
171
+ i0.ɵɵlistener("Navigate", function MJSearchScopeProviderFormComponentExtended_Template_mj_record_form_container_Navigate_0_listener($event) { return ctx.OnFormNavigate($event); })("DeleteRequested", function MJSearchScopeProviderFormComponentExtended_Template_mj_record_form_container_DeleteRequested_0_listener() { return ctx.OnDeleteRequested(); })("FavoriteToggled", function MJSearchScopeProviderFormComponentExtended_Template_mj_record_form_container_FavoriteToggled_0_listener() { return ctx.OnFavoriteToggled(); })("HistoryRequested", function MJSearchScopeProviderFormComponentExtended_Template_mj_record_form_container_HistoryRequested_0_listener() { return ctx.OnHistoryRequested(); })("ListManagementRequested", function MJSearchScopeProviderFormComponentExtended_Template_mj_record_form_container_ListManagementRequested_0_listener() { return ctx.OnListManagementRequested(); });
172
+ i0.ɵɵelementStart(1, "mj-collapsible-panel", 1);
173
+ i0.ɵɵelement(2, "mj-form-field", 2);
174
+ i0.ɵɵelementStart(3, "div", 3)(4, "label", 4);
175
+ i0.ɵɵtext(5, "Search Provider");
176
+ i0.ɵɵelementEnd();
177
+ i0.ɵɵconditionalCreate(6, MJSearchScopeProviderFormComponentExtended_Conditional_6_Template, 3, 1, "p", 5);
178
+ i0.ɵɵelementStart(7, "select", 6);
179
+ i0.ɵɵlistener("ngModelChange", function MJSearchScopeProviderFormComponentExtended_Template_select_ngModelChange_7_listener($event) { return ctx.SelectedSearchProviderID = $event; });
180
+ i0.ɵɵelementStart(8, "option", 7);
181
+ i0.ɵɵtext(9, "\u2014 Select a provider \u2014");
182
+ i0.ɵɵelementEnd();
183
+ i0.ɵɵrepeaterCreate(10, MJSearchScopeProviderFormComponentExtended_For_11_Template, 2, 5, "option", 8, _forTrack0);
184
+ i0.ɵɵelementEnd();
185
+ i0.ɵɵconditionalCreate(12, MJSearchScopeProviderFormComponentExtended_Conditional_12_Template, 12, 1, "p", 9);
186
+ i0.ɵɵelementStart(13, "p", 10);
187
+ i0.ɵɵtext(14, " Picks from rows in ");
188
+ i0.ɵɵelementStart(15, "code");
189
+ i0.ɵɵtext(16, "MJ: Search Providers");
190
+ i0.ɵɵelementEnd();
191
+ i0.ɵɵtext(17, ". The \"(not registered on this server)\" suffix comes from the ");
192
+ i0.ɵɵelementStart(18, "code");
193
+ i0.ɵɵtext(19, "AvailableSearchProviders");
194
+ i0.ɵɵelementEnd();
195
+ i0.ɵɵtext(20, " query, which calls ");
196
+ i0.ɵɵelementStart(21, "code");
197
+ i0.ɵɵtext(22, "BaseSearchProvider.GetAvailableProviders()");
198
+ i0.ɵɵelementEnd();
199
+ i0.ɵɵtext(23, " server-side to enumerate ClassFactory registrations. ");
200
+ i0.ɵɵelementEnd()()();
201
+ i0.ɵɵelementStart(24, "mj-collapsible-panel", 11);
202
+ i0.ɵɵelement(25, "mj-form-field", 12)(26, "mj-form-field", 13)(27, "mj-form-field", 14);
203
+ i0.ɵɵelementEnd();
204
+ i0.ɵɵelementStart(28, "mj-collapsible-panel", 15);
205
+ i0.ɵɵelement(29, "mj-form-field", 16);
206
+ i0.ɵɵelementEnd();
207
+ i0.ɵɵelementStart(30, "mj-collapsible-panel", 17);
208
+ i0.ɵɵelement(31, "mj-form-field", 18)(32, "mj-form-field", 19);
209
+ i0.ɵɵelementEnd()();
210
+ } if (rf & 2) {
211
+ i0.ɵɵproperty("Record", ctx.record)("FormComponent", ctx);
212
+ i0.ɵɵadvance();
213
+ i0.ɵɵproperty("Form", ctx)("FormContext", ctx.formContext);
214
+ i0.ɵɵadvance();
215
+ i0.ɵɵproperty("Record", ctx.record)("ShowLabel", true)("EditMode", ctx.EditMode)("FormContext", ctx.formContext);
216
+ i0.ɵɵadvance(4);
217
+ i0.ɵɵconditional(ctx.LoadError ? 6 : -1);
218
+ i0.ɵɵadvance();
219
+ i0.ɵɵproperty("disabled", !ctx.EditMode || !ctx.ProvidersLoaded)("ngModel", ctx.SelectedSearchProviderID);
220
+ i0.ɵɵadvance(3);
221
+ i0.ɵɵrepeater(ctx.AvailableProviders);
222
+ i0.ɵɵadvance(2);
223
+ i0.ɵɵconditional(ctx.SelectedProviderUnregisteredOnServer ? 12 : -1);
224
+ i0.ɵɵadvance(12);
225
+ i0.ɵɵproperty("Form", ctx)("FormContext", ctx.formContext);
226
+ i0.ɵɵadvance();
227
+ i0.ɵɵproperty("Record", ctx.record)("ShowLabel", true)("EditMode", ctx.EditMode)("FormContext", ctx.formContext);
228
+ i0.ɵɵadvance();
229
+ i0.ɵɵproperty("Record", ctx.record)("ShowLabel", true)("EditMode", ctx.EditMode)("FormContext", ctx.formContext);
230
+ i0.ɵɵadvance();
231
+ i0.ɵɵproperty("Record", ctx.record)("ShowLabel", true)("EditMode", ctx.EditMode)("FormContext", ctx.formContext);
232
+ i0.ɵɵadvance();
233
+ i0.ɵɵproperty("Form", ctx)("FormContext", ctx.formContext);
234
+ i0.ɵɵadvance();
235
+ i0.ɵɵproperty("Record", ctx.record)("ShowLabel", false)("EditMode", ctx.EditMode)("FormContext", ctx.formContext);
236
+ i0.ɵɵadvance();
237
+ i0.ɵɵproperty("Form", ctx)("FormContext", ctx.formContext);
238
+ i0.ɵɵadvance();
239
+ i0.ɵɵproperty("Record", ctx.record)("ShowLabel", true)("EditMode", ctx.EditMode)("FormContext", ctx.formContext);
240
+ i0.ɵɵadvance();
241
+ i0.ɵɵproperty("Record", ctx.record)("ShowLabel", true)("EditMode", ctx.EditMode)("FormContext", ctx.formContext);
242
+ } }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i1.SelectControlValueAccessor, i1.NgControlStatus, i1.NgModel, i2.MjFormFieldComponent, i2.MjCollapsiblePanelComponent, i2.MjRecordFormContainerComponent], styles: [".provider-picker[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n padding-top: 0.5rem;\n}\n\n.provider-picker-label[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.provider-picker-select[_ngcontent-%COMP%] {\n width: 100%;\n max-width: 600px;\n}\n\n.provider-picker-error[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 0.875rem;\n color: var(--mj-status-error-text);\n background: var(--mj-status-error-bg);\n padding: 0.5rem 0.75rem;\n border-left: 3px solid var(--mj-status-error-border);\n border-radius: 2px;\n}\n\n.provider-picker-warning[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 0.875rem;\n color: var(--mj-status-warning-text);\n background: var(--mj-status-warning-bg);\n padding: 0.5rem 0.75rem;\n border-left: 3px solid var(--mj-status-warning-border);\n border-radius: 2px;\n}\n\n.provider-picker-warning[_ngcontent-%COMP%] code[_ngcontent-%COMP%], \n.provider-picker-help[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n padding: 0.1rem 0.3rem;\n border-radius: 2px;\n font-family: ui-monospace, SFMono-Regular, monospace;\n font-size: 0.85em;\n}\n\n.provider-picker-help[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 0.8125rem;\n color: var(--mj-text-muted);\n}"] }); }
243
+ };
244
+ MJSearchScopeProviderFormComponentExtended = __decorate([
245
+ RegisterClass(BaseFormComponent, 'MJ: Search Scope Providers')
246
+ ], MJSearchScopeProviderFormComponentExtended);
247
+ export { MJSearchScopeProviderFormComponentExtended };
248
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJSearchScopeProviderFormComponentExtended, [{
249
+ type: Component,
250
+ args: [{ standalone: false, selector: 'mj-searchscopeprovider-form-extended', template: "<mj-record-form-container [Record]=\"record\" [FormComponent]=\"this\"\n (Navigate)=\"OnFormNavigate($event)\"\n (DeleteRequested)=\"OnDeleteRequested()\"\n (FavoriteToggled)=\"OnFavoriteToggled()\"\n (HistoryRequested)=\"OnHistoryRequested()\"\n (ListManagementRequested)=\"OnListManagementRequested()\">\n\n <!-- ========================================\n FIELD PANELS\n ======================================== -->\n <!-- Search Configuration Section -->\n <mj-collapsible-panel\n SectionKey=\"searchConfiguration\"\n SectionName=\"Search Configuration\"\n Icon=\"fa fa-search\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"SearchScopeID\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n LinkType=\"Record\"\n ></mj-form-field>\n\n <!-- P5.5 \u2014 provider picker. Replaces the generated form's plain\n SearchProviderID textbox. Sourced from MJ: Search Providers\n rows; each option is annotated with whether the provider's\n DriverClass is currently registered with the server's\n ClassFactory. -->\n <div class=\"provider-picker\">\n <label class=\"provider-picker-label\">Search Provider</label>\n @if (LoadError) {\n <p class=\"provider-picker-error\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n Could not load provider catalog \u2014 {{ LoadError }}\n </p>\n }\n <select\n class=\"mj-input provider-picker-select\"\n [disabled]=\"!EditMode || !ProvidersLoaded\"\n [ngModel]=\"SelectedSearchProviderID\"\n (ngModelChange)=\"SelectedSearchProviderID = $event\">\n <option value=\"\">\u2014 Select a provider \u2014</option>\n @for (option of AvailableProviders; track option.ID) {\n <option [value]=\"option.ID\">\n {{ option.Name }} \u2014 {{ option.DriverClass }}{{ option.IsRegisteredOnServer ? '' : ' (not registered on this server)' }}{{ option.Status !== 'Active' ? ' [' + option.Status + ']' : '' }}\n </option>\n }\n </select>\n @if (SelectedProviderUnregisteredOnServer) {\n <p class=\"provider-picker-warning\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n The selected provider's <code>DriverClass</code> is not registered with this MJServer build.\n Searches using this <code>SearchScopeProvider</code> will return no results until the\n package that registers <code>{{ SelectedProvider?.DriverClass }}</code> is installed.\n </p>\n }\n <p class=\"provider-picker-help\">\n Picks from rows in <code>MJ: Search Providers</code>. The \"(not registered on this server)\" suffix\n comes from the <code>AvailableSearchProviders</code> query, which calls\n <code>BaseSearchProvider.GetAvailableProviders()</code> server-side to enumerate\n ClassFactory registrations.\n </p>\n </div>\n\n </mj-collapsible-panel>\n\n <!-- Operational Settings Section -->\n <mj-collapsible-panel\n SectionKey=\"operationalSettings\"\n SectionName=\"Operational Settings\"\n Icon=\"fa fa-sliders-h\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"Enabled\"\n Type=\"checkbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"MaxResultsOverride\"\n Type=\"number\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"ProviderConfigOverride\"\n Type=\"code\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n\n <!-- Query Processing Section -->\n <mj-collapsible-panel\n SectionKey=\"queryProcessing\"\n SectionName=\"Query Processing\"\n Icon=\"fa fa-magic\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"false\"\n FieldName=\"QueryTransformTemplateID\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n LinkType=\"Record\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n\n <!-- System Metadata Section -->\n <mj-collapsible-panel\n SectionKey=\"systemMetadata\"\n SectionName=\"System Metadata\"\n Icon=\"fa fa-cog\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"__mj_CreatedAt\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"__mj_UpdatedAt\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n</mj-record-form-container>\n", styles: [".provider-picker {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n padding-top: 0.5rem;\n}\n\n.provider-picker-label {\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.provider-picker-select {\n width: 100%;\n max-width: 600px;\n}\n\n.provider-picker-error {\n margin: 0;\n font-size: 0.875rem;\n color: var(--mj-status-error-text);\n background: var(--mj-status-error-bg);\n padding: 0.5rem 0.75rem;\n border-left: 3px solid var(--mj-status-error-border);\n border-radius: 2px;\n}\n\n.provider-picker-warning {\n margin: 0;\n font-size: 0.875rem;\n color: var(--mj-status-warning-text);\n background: var(--mj-status-warning-bg);\n padding: 0.5rem 0.75rem;\n border-left: 3px solid var(--mj-status-warning-border);\n border-radius: 2px;\n}\n\n.provider-picker-warning code,\n.provider-picker-help code {\n background: var(--mj-bg-surface-sunken);\n padding: 0.1rem 0.3rem;\n border-radius: 2px;\n font-family: ui-monospace, SFMono-Regular, monospace;\n font-size: 0.85em;\n}\n\n.provider-picker-help {\n margin: 0;\n font-size: 0.8125rem;\n color: var(--mj-text-muted);\n}\n"] }]
251
+ }], null, null); })();
252
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJSearchScopeProviderFormComponentExtended, { className: "MJSearchScopeProviderFormComponentExtended", filePath: "src/lib/custom/SearchScopes/searchscopeprovider-form.component.ts", lineNumber: 46 }); })();
253
+ //# sourceMappingURL=searchscopeprovider-form.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"searchscopeprovider-form.component.js","sourceRoot":"","sources":["../../../../src/lib/custom/SearchScopes/searchscopeprovider-form.component.ts","../../../../src/lib/custom/SearchScopes/searchscopeprovider-form.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * Custom MJSearchScopeProvider form (P5.5).\n *\n * Plan acceptance criterion: provide a dropdown for `SearchProviderID` so\n * scope authors don't have to look up GUIDs by hand. The dropdown is sourced\n * from the `MJ: Search Providers` table (those rows are the canonical FK\n * targets), and each option is annotated with whether the provider's\n * `DriverClass` is currently registered with the runtime ClassFactory on\n * this MJServer build — so authors can see at a glance whether their pick\n * will actually be available at search time.\n *\n * The runtime registration list comes from the `AvailableSearchProviders`\n * GraphQL query backed by `BaseSearchProvider.GetAvailableProviders()`.\n * That query is the canonical \"which providers does this server know\n * about\" source — same helper Phase 5.5 of the RAG plan calls out.\n */\nimport { Component, OnInit } from '@angular/core';\nimport { LogError, Metadata, RunView } from '@memberjunction/core';\nimport { MJSearchScopeProviderEntity, MJSearchProviderEntity } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseFormComponent } from '@memberjunction/ng-base-forms';\nimport { GraphQLDataProvider } from '@memberjunction/graphql-dataprovider';\nimport { MJSearchScopeProviderFormComponent } from '../../generated/Entities/MJSearchScopeProvider/mjsearchscopeprovider.form.component';\n\ninterface SearchProviderOption {\n ID: string;\n Name: string;\n DriverClass: string;\n Status: 'Active' | 'Pending' | 'Terminated';\n /**\n * `true` if `DriverClass` matches a class currently registered with the\n * runtime ClassFactory on this MJServer. `false` means the row exists in\n * `MJ: Search Providers` but no installed package registers that class —\n * picking it would result in `IsAvailable()=false` at search time.\n */\n IsRegisteredOnServer: boolean;\n}\n\n@RegisterClass(BaseFormComponent, 'MJ: Search Scope Providers')\n@Component({\n standalone: false,\n selector: 'mj-searchscopeprovider-form-extended',\n templateUrl: './searchscopeprovider-form.component.html',\n styleUrls: ['./searchscopeprovider-form.component.css'],\n})\nexport class MJSearchScopeProviderFormComponentExtended extends MJSearchScopeProviderFormComponent implements OnInit {\n public override record!: MJSearchScopeProviderEntity;\n\n public AvailableProviders: SearchProviderOption[] = [];\n public ProvidersLoaded = false;\n public LoadError: string | null = null;\n\n /**\n * Drives the dropdown's `[ngModel]`. Kept in sync with `record.SearchProviderID`\n * via the setter so dirty tracking and the form's save flow continue to work.\n */\n public get SelectedSearchProviderID(): string {\n return this.record?.SearchProviderID ?? '';\n }\n public set SelectedSearchProviderID(value: string) {\n if (!this.record) return;\n if (this.record.SearchProviderID === value) return;\n this.record.SearchProviderID = value;\n }\n\n public get SelectedProvider(): SearchProviderOption | null {\n const id = this.SelectedSearchProviderID;\n if (!id) return null;\n return this.AvailableProviders.find(p => p.ID.toLowerCase() === id.toLowerCase()) ?? null;\n }\n\n public get SelectedProviderUnregisteredOnServer(): boolean {\n const sel = this.SelectedProvider;\n return sel != null && !sel.IsRegisteredOnServer;\n }\n\n override async ngOnInit(): Promise<void> {\n await super.ngOnInit();\n await this.loadProviderCatalog();\n }\n\n /**\n * Pulls the `MJ: Search Providers` rows and the server-registered class list\n * in parallel, then merges into one dropdown source. Failures don't block the\n * form — the dropdown just disables itself, leaving the underlying generated\n * textbox accessible via `EditMode`.\n */\n private async loadProviderCatalog(): Promise<void> {\n try {\n const rv = new RunView();\n const [rowsResult, registeredKeys] = await Promise.all([\n rv.RunView<MJSearchProviderEntity>({\n EntityName: 'MJ: Search Providers',\n OrderBy: 'Name',\n ResultType: 'simple',\n }),\n this.fetchRegisteredDriverClasses(),\n ]);\n\n if (!rowsResult.Success) {\n this.LoadError = rowsResult.ErrorMessage ?? 'Unknown error loading providers';\n LogError(`MJSearchScopeProviderFormExtended: RunView failed: ${this.LoadError}`);\n return;\n }\n\n const registeredSet = new Set(registeredKeys.map(k => k.toLowerCase()));\n const rows = rowsResult.Results ?? [];\n this.AvailableProviders = rows.map(row => ({\n ID: row.ID,\n Name: row.Name,\n DriverClass: row.DriverClass,\n Status: row.Status,\n IsRegisteredOnServer: registeredSet.has(row.DriverClass.toLowerCase()),\n }));\n this.ProvidersLoaded = true;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n this.LoadError = msg;\n LogError(`MJSearchScopeProviderFormExtended: catalog load threw: ${msg}`);\n }\n }\n\n /**\n * Calls the `AvailableSearchProviders` GraphQL query to learn which\n * `DriverClass` keys are actually registered with `MJGlobal.ClassFactory`\n * on the server. Returns `[]` on any failure — the dropdown still renders\n * from the DB rows; we just lose the \"(not registered)\" badge.\n */\n private async fetchRegisteredDriverClasses(): Promise<string[]> {\n try {\n const dataProvider = this.ProviderToUse as GraphQLDataProvider;\n const response = await dataProvider.ExecuteGQL(\n `query AvailableSearchProviders { AvailableSearchProviders { DriverClass SourceType } }`,\n {}\n ) as { AvailableSearchProviders?: Array<{ DriverClass: string }> };\n return (response?.AvailableSearchProviders ?? []).map(r => r.DriverClass);\n } catch (err) {\n // Older server build won't have the resolver. The dropdown still\n // works from DB rows; the registration badge just won't appear.\n const msg = err instanceof Error ? err.message : String(err);\n LogError(`MJSearchScopeProviderFormExtended: AvailableSearchProviders query failed (badge disabled): ${msg}`);\n return [];\n }\n }\n}\n","<mj-record-form-container [Record]=\"record\" [FormComponent]=\"this\"\n (Navigate)=\"OnFormNavigate($event)\"\n (DeleteRequested)=\"OnDeleteRequested()\"\n (FavoriteToggled)=\"OnFavoriteToggled()\"\n (HistoryRequested)=\"OnHistoryRequested()\"\n (ListManagementRequested)=\"OnListManagementRequested()\">\n\n <!-- ========================================\n FIELD PANELS\n ======================================== -->\n <!-- Search Configuration Section -->\n <mj-collapsible-panel\n SectionKey=\"searchConfiguration\"\n SectionName=\"Search Configuration\"\n Icon=\"fa fa-search\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"SearchScopeID\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n LinkType=\"Record\"\n ></mj-form-field>\n\n <!-- P5.5 — provider picker. Replaces the generated form's plain\n SearchProviderID textbox. Sourced from MJ: Search Providers\n rows; each option is annotated with whether the provider's\n DriverClass is currently registered with the server's\n ClassFactory. -->\n <div class=\"provider-picker\">\n <label class=\"provider-picker-label\">Search Provider</label>\n @if (LoadError) {\n <p class=\"provider-picker-error\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n Could not load provider catalog — {{ LoadError }}\n </p>\n }\n <select\n class=\"mj-input provider-picker-select\"\n [disabled]=\"!EditMode || !ProvidersLoaded\"\n [ngModel]=\"SelectedSearchProviderID\"\n (ngModelChange)=\"SelectedSearchProviderID = $event\">\n <option value=\"\">— Select a provider —</option>\n @for (option of AvailableProviders; track option.ID) {\n <option [value]=\"option.ID\">\n {{ option.Name }} — {{ option.DriverClass }}{{ option.IsRegisteredOnServer ? '' : ' (not registered on this server)' }}{{ option.Status !== 'Active' ? ' [' + option.Status + ']' : '' }}\n </option>\n }\n </select>\n @if (SelectedProviderUnregisteredOnServer) {\n <p class=\"provider-picker-warning\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n The selected provider's <code>DriverClass</code> is not registered with this MJServer build.\n Searches using this <code>SearchScopeProvider</code> will return no results until the\n package that registers <code>{{ SelectedProvider?.DriverClass }}</code> is installed.\n </p>\n }\n <p class=\"provider-picker-help\">\n Picks from rows in <code>MJ: Search Providers</code>. The \"(not registered on this server)\" suffix\n comes from the <code>AvailableSearchProviders</code> query, which calls\n <code>BaseSearchProvider.GetAvailableProviders()</code> server-side to enumerate\n ClassFactory registrations.\n </p>\n </div>\n\n </mj-collapsible-panel>\n\n <!-- Operational Settings Section -->\n <mj-collapsible-panel\n SectionKey=\"operationalSettings\"\n SectionName=\"Operational Settings\"\n Icon=\"fa fa-sliders-h\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"Enabled\"\n Type=\"checkbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"MaxResultsOverride\"\n Type=\"number\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"ProviderConfigOverride\"\n Type=\"code\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n\n <!-- Query Processing Section -->\n <mj-collapsible-panel\n SectionKey=\"queryProcessing\"\n SectionName=\"Query Processing\"\n Icon=\"fa fa-magic\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"false\"\n FieldName=\"QueryTransformTemplateID\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n LinkType=\"Record\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n\n <!-- System Metadata Section -->\n <mj-collapsible-panel\n SectionKey=\"systemMetadata\"\n SectionName=\"System Metadata\"\n Icon=\"fa fa-cog\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"__mj_CreatedAt\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"__mj_UpdatedAt\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n</mj-record-form-container>\n"]}
@@ -66,7 +66,7 @@ let MJTestRubricFormComponentExtended = class MJTestRubricFormComponentExtended
66
66
  i0.ɵɵadvance(4);
67
67
  i0.ɵɵtextInterpolate1(" ", ctx.record.Name || "Test Rubric");
68
68
  i0.ɵɵadvance();
69
- i0.ɵɵstyleProp("background-color", ctx.record.Status === "Active" ? "#4caf50" : "#9e9e9e");
69
+ i0.ɵɵstyleProp("background-color", ctx.record.Status === "Active" ? "var(--mj-status-success)" : "var(--mj-text-disabled)");
70
70
  i0.ɵɵadvance();
71
71
  i0.ɵɵtextInterpolate1(" ", ctx.record.Status, " ");
72
72
  i0.ɵɵadvance(5);
@@ -93,7 +93,7 @@ export { MJTestRubricFormComponentExtended };
93
93
  <div class="rubric-form">
94
94
  <div class="rubric-header">
95
95
  <h2><i class="fas fa-clipboard-list"></i> {{ record.Name || 'Test Rubric' }}</h2>
96
- <span class="status-badge" [style.background-color]="record.Status === 'Active' ? '#4caf50' : '#9e9e9e'">
96
+ <span class="status-badge" [style.background-color]="record.Status === 'Active' ? 'var(--mj-status-success)' : 'var(--mj-text-disabled)'">
97
97
  {{ record.Status }}
98
98
  </span>
99
99
  </div>
@@ -1 +1 @@
1
- {"version":3,"file":"test-rubric-form.component.js","sourceRoot":"","sources":["../../../../src/lib/custom/Tests/test-rubric-form.component.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,SAAS,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAEnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,mEAAmE,CAAC;;;;AAuDvG,IAAM,iCAAiC,GAAvC,MAAM,iCAAkC,SAAQ,yBAAyB;wTAAnE,iCAAiC,yBAAjC,iCAAiC;oEAAjC,iCAAiC;YA9CtC,AADF,AADF,8BAAyB,aACI,SACrB;YAAA,uBAAqC;YAAC,YAAkC;YAAA,iBAAK;YACjF,+BAAyG;YACvG,YACF;YACF,AADE,iBAAO,EACH;YAGF,AADF,AADF,8BAA4B,aACD,YAChB;YAAA,qBAAI;YAAA,iBAAQ;YACnB,iCAA+C;YAA5B,kOAAyB;YAC9C,AADE,iBAA+C,EAC3C;YAEJ,AADF,+BAAyB,aAChB;YAAA,4BAAW;YAAA,iBAAQ;YAC1B,oCAAoD;YAA1C,mPAAgC;YAC5C,AADsD,iBAAW,EAC3D;YAEJ,AADF,+BAAyB,aAChB;YAAA,gCAAe;YAAA,iBAAQ;YAC9B,oCAA4E;YAAlE,yPAAmC;YAC/C,AAD8E,iBAAW,EACnF;YAEJ,AADF,+BAAyB,aAChB;YAAA,uBAAM;YAAA,iBAAQ;YACrB,kCAAoC;YAA5B,uOAA2B;YACjC,mCAAuB;YAAA,uBAAM;YAAA,iBAAS;YACtC,mCAAyB;YAAA,yBAAQ;YAErC,AADE,AADmC,iBAAS,EACnC,EACL;YAEC,AAAL,AADF,gCAAsB,WACf,cAAQ;YAAA,yBAAQ;YAAA,iBAAS;YAAC,aAA2C;;YAAA,iBAAM;YAC3E,AAAL,4BAAK,cAAQ;YAAA,yBAAQ;YAAA,iBAAS;YAAC,aAA2C;;YAGhF,AADE,AADE,AAD4E,iBAAM,EAC5E,EACF,EACF;;YA9BwC,eAAkC;YAAlC,4DAAkC;YACjD,cAA6E;YAA7E,0FAA6E;YACtG,cACF;YADE,kDACF;YAKqB,eAAyB;YAAzB,+CAAyB;YAIlC,eAAgC;YAAhC,sDAAgC;YAIhC,eAAmC;YAAnC,yDAAmC;YAIrC,eAA2B;YAA3B,iDAA2B;YAMJ,eAA2C;YAA3C,uFAA2C;YAC3C,eAA2C;YAA3C,uFAA2C;;;AAmBvE,iCAAiC;IArD7C,aAAa,CAAC,iBAAiB,EAAE,kBAAkB,CAAC;GAqDxC,iCAAiC,CAE7C;;iFAFY,iCAAiC;cApD7C,SAAS;6BACI,KAAK,YACP,qBAAqB,YACrB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCT,mBAagB,uBAAuB,CAAC,MAAM;;kFAEpC,iCAAiC","sourcesContent":["import { Component, ChangeDetectionStrategy } from '@angular/core';\nimport { MJTestRubricEntity } from '@memberjunction/core-entities';\nimport { BaseFormComponent } from '@memberjunction/ng-base-forms';\nimport { RegisterClass } from '@memberjunction/global';\nimport { MJTestRubricFormComponent } from '../../generated/Entities/MJTestRubric/mjtestrubric.form.component';\n\n@RegisterClass(BaseFormComponent, 'MJ: Test Rubrics')\n@Component({\n standalone: false,\n selector: 'mj-test-rubric-form',\n template: `\n <div class=\"rubric-form\">\n <div class=\"rubric-header\">\n <h2><i class=\"fas fa-clipboard-list\"></i> {{ record.Name || 'Test Rubric' }}</h2>\n <span class=\"status-badge\" [style.background-color]=\"record.Status === 'Active' ? '#4caf50' : '#9e9e9e'\">\n {{ record.Status }}\n </span>\n </div>\n <div class=\"rubric-content\">\n <div class=\"field-group\">\n <label>Name</label>\n <input type=\"text\" [(ngModel)]=\"record.Name\" />\n </div>\n <div class=\"field-group\">\n <label>Description</label>\n <textarea [(ngModel)]=\"record.Description\" rows=\"4\"></textarea>\n </div>\n <div class=\"field-group\">\n <label>Prompt Template</label>\n <textarea [(ngModel)]=\"record.PromptTemplate\" rows=\"12\" class=\"json-editor\"></textarea>\n </div>\n <div class=\"field-group\">\n <label>Status</label>\n <select [(ngModel)]=\"record.Status\">\n <option value=\"Active\">Active</option>\n <option value=\"Disabled\">Disabled</option>\n </select>\n </div>\n <div class=\"metadata\">\n <div><strong>Created:</strong> {{ record.__mj_CreatedAt | date:'medium' }}</div>\n <div><strong>Updated:</strong> {{ record.__mj_UpdatedAt | date:'medium' }}</div>\n </div>\n </div>\n </div>\n `,\n styles: [`\n .rubric-form { padding: 20px; }\n .rubric-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px; }\n .rubric-header h2 { margin: 0; font-size: 20px; display: flex; align-items: center; gap: 12px; }\n .status-badge { padding: 4px 12px; border-radius: 12px; color: var(--mj-text-inverse); font-size: 12px; font-weight: 600; }\n .rubric-content { background: var(--mj-bg-surface); padding: 24px; border-radius: 8px; }\n .field-group { margin-bottom: 20px; }\n .field-group label { display: block; margin-bottom: 8px; font-weight: 600; color: var(--mj-text-primary); }\n .field-group input, .field-group textarea, .field-group select { width: 100%; padding: 8px 12px; border: 1px solid var(--mj-border-default); border-radius: 4px; }\n .json-editor { font-family: 'Courier New', monospace; font-size: 13px; }\n .metadata { margin-top: 24px; padding-top: 16px; border-top: 1px solid var(--mj-border-default); display: flex; gap: 24px; font-size: 13px; color: var(--mj-text-secondary); }\n `],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class MJTestRubricFormComponentExtended extends MJTestRubricFormComponent {\n public override record!: MJTestRubricEntity;\n}\n"]}
1
+ {"version":3,"file":"test-rubric-form.component.js","sourceRoot":"","sources":["../../../../src/lib/custom/Tests/test-rubric-form.component.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,SAAS,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAEnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,mEAAmE,CAAC;;;;AAuDvG,IAAM,iCAAiC,GAAvC,MAAM,iCAAkC,SAAQ,yBAAyB;wTAAnE,iCAAiC,yBAAjC,iCAAiC;oEAAjC,iCAAiC;YA9CtC,AADF,AADF,8BAAyB,aACI,SACrB;YAAA,uBAAqC;YAAC,YAAkC;YAAA,iBAAK;YACjF,+BAA0I;YACxI,YACF;YACF,AADE,iBAAO,EACH;YAGF,AADF,AADF,8BAA4B,aACD,YAChB;YAAA,qBAAI;YAAA,iBAAQ;YACnB,iCAA+C;YAA5B,kOAAyB;YAC9C,AADE,iBAA+C,EAC3C;YAEJ,AADF,+BAAyB,aAChB;YAAA,4BAAW;YAAA,iBAAQ;YAC1B,oCAAoD;YAA1C,mPAAgC;YAC5C,AADsD,iBAAW,EAC3D;YAEJ,AADF,+BAAyB,aAChB;YAAA,gCAAe;YAAA,iBAAQ;YAC9B,oCAA4E;YAAlE,yPAAmC;YAC/C,AAD8E,iBAAW,EACnF;YAEJ,AADF,+BAAyB,aAChB;YAAA,uBAAM;YAAA,iBAAQ;YACrB,kCAAoC;YAA5B,uOAA2B;YACjC,mCAAuB;YAAA,uBAAM;YAAA,iBAAS;YACtC,mCAAyB;YAAA,yBAAQ;YAErC,AADE,AADmC,iBAAS,EACnC,EACL;YAEC,AAAL,AADF,gCAAsB,WACf,cAAQ;YAAA,yBAAQ;YAAA,iBAAS;YAAC,aAA2C;;YAAA,iBAAM;YAC3E,AAAL,4BAAK,cAAQ;YAAA,yBAAQ;YAAA,iBAAS;YAAC,aAA2C;;YAGhF,AADE,AADE,AAD4E,iBAAM,EAC5E,EACF,EACF;;YA9BwC,eAAkC;YAAlC,4DAAkC;YACjD,cAA8G;YAA9G,2HAA8G;YACvI,cACF;YADE,kDACF;YAKqB,eAAyB;YAAzB,+CAAyB;YAIlC,eAAgC;YAAhC,sDAAgC;YAIhC,eAAmC;YAAnC,yDAAmC;YAIrC,eAA2B;YAA3B,iDAA2B;YAMJ,eAA2C;YAA3C,uFAA2C;YAC3C,eAA2C;YAA3C,uFAA2C;;;AAmBvE,iCAAiC;IArD7C,aAAa,CAAC,iBAAiB,EAAE,kBAAkB,CAAC;GAqDxC,iCAAiC,CAE7C;;iFAFY,iCAAiC;cApD7C,SAAS;6BACI,KAAK,YACP,qBAAqB,YACrB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCT,mBAagB,uBAAuB,CAAC,MAAM;;kFAEpC,iCAAiC","sourcesContent":["import { Component, ChangeDetectionStrategy } from '@angular/core';\nimport { MJTestRubricEntity } from '@memberjunction/core-entities';\nimport { BaseFormComponent } from '@memberjunction/ng-base-forms';\nimport { RegisterClass } from '@memberjunction/global';\nimport { MJTestRubricFormComponent } from '../../generated/Entities/MJTestRubric/mjtestrubric.form.component';\n\n@RegisterClass(BaseFormComponent, 'MJ: Test Rubrics')\n@Component({\n standalone: false,\n selector: 'mj-test-rubric-form',\n template: `\n <div class=\"rubric-form\">\n <div class=\"rubric-header\">\n <h2><i class=\"fas fa-clipboard-list\"></i> {{ record.Name || 'Test Rubric' }}</h2>\n <span class=\"status-badge\" [style.background-color]=\"record.Status === 'Active' ? 'var(--mj-status-success)' : 'var(--mj-text-disabled)'\">\n {{ record.Status }}\n </span>\n </div>\n <div class=\"rubric-content\">\n <div class=\"field-group\">\n <label>Name</label>\n <input type=\"text\" [(ngModel)]=\"record.Name\" />\n </div>\n <div class=\"field-group\">\n <label>Description</label>\n <textarea [(ngModel)]=\"record.Description\" rows=\"4\"></textarea>\n </div>\n <div class=\"field-group\">\n <label>Prompt Template</label>\n <textarea [(ngModel)]=\"record.PromptTemplate\" rows=\"12\" class=\"json-editor\"></textarea>\n </div>\n <div class=\"field-group\">\n <label>Status</label>\n <select [(ngModel)]=\"record.Status\">\n <option value=\"Active\">Active</option>\n <option value=\"Disabled\">Disabled</option>\n </select>\n </div>\n <div class=\"metadata\">\n <div><strong>Created:</strong> {{ record.__mj_CreatedAt | date:'medium' }}</div>\n <div><strong>Updated:</strong> {{ record.__mj_UpdatedAt | date:'medium' }}</div>\n </div>\n </div>\n </div>\n `,\n styles: [`\n .rubric-form { padding: 20px; }\n .rubric-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px; }\n .rubric-header h2 { margin: 0; font-size: 20px; display: flex; align-items: center; gap: 12px; }\n .status-badge { padding: 4px 12px; border-radius: 12px; color: var(--mj-text-inverse); font-size: 12px; font-weight: 600; }\n .rubric-content { background: var(--mj-bg-surface); padding: 24px; border-radius: 8px; }\n .field-group { margin-bottom: 20px; }\n .field-group label { display: block; margin-bottom: 8px; font-weight: 600; color: var(--mj-text-primary); }\n .field-group input, .field-group textarea, .field-group select { width: 100%; padding: 8px 12px; border: 1px solid var(--mj-border-default); border-radius: 4px; }\n .json-editor { font-family: 'Courier New', monospace; font-size: 13px; }\n .metadata { margin-top: 24px; padding-top: 16px; border-top: 1px solid var(--mj-border-default); display: flex; gap: 24px; font-size: 13px; color: var(--mj-text-secondary); }\n `],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class MJTestRubricFormComponentExtended extends MJTestRubricFormComponent {\n public override record!: MJTestRubricEntity;\n}\n"]}