@vue-skuilder/platform-ui 0.2.36 → 0.2.37

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 (146) hide show
  1. package/dist/assets/{About-74htcNLT.js → About-BkMENQtD.js} +2 -2
  2. package/dist/assets/{About-74htcNLT.js.map → About-BkMENQtD.js.map} +1 -1
  3. package/dist/assets/{AdminDashboard-B00qno2M.js → AdminDashboard-5R-xgY-M.js} +2 -2
  4. package/dist/assets/{AdminDashboard-B00qno2M.js.map → AdminDashboard-5R-xgY-M.js.map} +1 -1
  5. package/dist/assets/{AdminLearner-SJNtSyJ_.js → AdminLearner-Br10DFSt.js} +2 -2
  6. package/dist/assets/{AdminLearner-SJNtSyJ_.js.map → AdminLearner-Br10DFSt.js.map} +1 -1
  7. package/dist/assets/BaseUserDB-BRgNfdWx.js +1 -0
  8. package/dist/assets/{ClassroomCtrlPanel-BSAG3h8B.js → ClassroomCtrlPanel-DQJQ0B7M.js} +2 -2
  9. package/dist/assets/{ClassroomCtrlPanel-BSAG3h8B.js.map → ClassroomCtrlPanel-DQJQ0B7M.js.map} +1 -1
  10. package/dist/assets/{Classrooms-DXNEbtsM.js → Classrooms-B5tQPFEE.js} +2 -2
  11. package/dist/assets/{Classrooms-DXNEbtsM.js.map → Classrooms-B5tQPFEE.js.map} +1 -1
  12. package/dist/assets/CouchDBSyncStrategy-0EgX8AAz.js +1 -0
  13. package/dist/assets/{CourseRouter-CsVa_92r.js → CourseRouter-W6S7DpZN.js} +2 -2
  14. package/dist/assets/{CourseRouter-CsVa_92r.js.map → CourseRouter-W6S7DpZN.js.map} +1 -1
  15. package/dist/assets/CourseSyncService-CrHp0wsl.js +1 -0
  16. package/dist/assets/{CourseWare-BTFRjgBR-DBp_fIwH.js → CourseWare-BTFRjgBR-lpqcYpAW.js} +3 -3
  17. package/dist/assets/{CourseWare-BTFRjgBR-DBp_fIwH.js.map → CourseWare-BTFRjgBR-lpqcYpAW.js.map} +1 -1
  18. package/dist/assets/{Courses-CB6GGtdm.js → Courses-TzwgFdwn.js} +2 -2
  19. package/dist/assets/{Courses-CB6GGtdm.js.map → Courses-TzwgFdwn.js.map} +1 -1
  20. package/dist/assets/{EloModeration-DUBgs-Vh.js → EloModeration-BCz7VKla.js} +2 -2
  21. package/dist/assets/{EloModeration-DUBgs-Vh.js.map → EloModeration-BCz7VKla.js.map} +1 -1
  22. package/dist/assets/{JoinCode-BBvYapCA.js → JoinCode-CEeZkFOp.js} +2 -2
  23. package/dist/assets/{JoinCode-BBvYapCA.js.map → JoinCode-CEeZkFOp.js.map} +1 -1
  24. package/dist/assets/{NewCourseDialog-DBgFVnt3.js → NewCourseDialog-DNzvvz_H.js} +2 -2
  25. package/dist/assets/{NewCourseDialog-DBgFVnt3.js.map → NewCourseDialog-DNzvvz_H.js.map} +1 -1
  26. package/dist/assets/{PipelineDebugger-BHaqzqZw.js → PipelineDebugger-DhnKlMgD.js} +3 -3
  27. package/dist/assets/{PipelineDebugger-BHaqzqZw.js.map → PipelineDebugger-DhnKlMgD.js.map} +1 -1
  28. package/dist/assets/PouchDataLayerProvider-CAuhZYIc.js +2 -0
  29. package/dist/assets/PouchDataLayerProvider-CAuhZYIc.js.map +1 -0
  30. package/dist/assets/{ReleaseNotes-Dg6mLL1C.js → ReleaseNotes-Bvw24QDI.js} +2 -2
  31. package/dist/assets/{ReleaseNotes-Dg6mLL1C.js.map → ReleaseNotes-Bvw24QDI.js.map} +1 -1
  32. package/dist/assets/{RequestPasswordReset-CcFMTnTc.js → RequestPasswordReset-YOq1JJ_o.js} +2 -2
  33. package/dist/assets/{RequestPasswordReset-CcFMTnTc.js.map → RequestPasswordReset-YOq1JJ_o.js.map} +1 -1
  34. package/dist/assets/{ResetPassword-Dw_cBJU2.js → ResetPassword-CQCb3B_Z.js} +2 -2
  35. package/dist/assets/{ResetPassword-Dw_cBJU2.js.map → ResetPassword-CQCb3B_Z.js.map} +1 -1
  36. package/dist/assets/{StaticDataLayerProvider-CtgU3VBh.js → StaticDataLayerProvider-DbGLKpb1.js} +2 -2
  37. package/dist/assets/{StaticDataLayerProvider-CtgU3VBh.js.map → StaticDataLayerProvider-DbGLKpb1.js.map} +1 -1
  38. package/dist/assets/{Study-DDsGQCTJ.js → Study-D2mXR27s.js} +2 -2
  39. package/dist/assets/{Study-DDsGQCTJ.js.map → Study-D2mXR27s.js.map} +1 -1
  40. package/dist/assets/{TagInformation-DBLoXA2a.js → TagInformation-DHw5jRNt.js} +2 -2
  41. package/dist/assets/{TagInformation-DBLoXA2a.js.map → TagInformation-DHw5jRNt.js.map} +1 -1
  42. package/dist/assets/{User-DfXUXjFb.js → User-C0xEcKaU.js} +2 -2
  43. package/dist/assets/{User-DfXUXjFb.js.map → User-C0xEcKaU.js.map} +1 -1
  44. package/dist/assets/{UserDBDebugger-DPqlc4O_.js → UserDBDebugger-BXLoT28w.js} +2 -2
  45. package/dist/assets/{UserDBDebugger-DPqlc4O_.js.map → UserDBDebugger-BXLoT28w.js.map} +1 -1
  46. package/dist/assets/UserDBDebugger-DHONc_-t.js +1 -0
  47. package/dist/assets/{UserStats-C04YVYv7.js → UserStats-Blm_daoT.js} +2 -2
  48. package/dist/assets/{UserStats-C04YVYv7.js.map → UserStats-Blm_daoT.js.map} +1 -1
  49. package/dist/assets/{VerifyEmail-Y05BSR57.js → VerifyEmail-DTwA6sFY.js} +2 -2
  50. package/dist/assets/{VerifyEmail-Y05BSR57.js.map → VerifyEmail-DTwA6sFY.js.map} +1 -1
  51. package/dist/assets/{admin-DcFjvYJw.js → admin-hzNSXp0o.js} +2 -2
  52. package/dist/assets/{admin-DcFjvYJw.js.map → admin-hzNSXp0o.js.map} +1 -1
  53. package/dist/assets/{chess-E2uOAyQS-BZi0vihz.js → chess-E2uOAyQS-DDTgqZMJ.js} +2 -2
  54. package/dist/assets/{chess-E2uOAyQS-BZi0vihz.js.map → chess-E2uOAyQS-DDTgqZMJ.js.map} +1 -1
  55. package/dist/assets/chess-Lfm7Fsvs-RaFhFnIh.js +1 -0
  56. package/dist/assets/{contentSource-DwznMSMs.js → contentSource-FGhM_ge8.js} +8 -8
  57. package/dist/assets/contentSource-FGhM_ge8.js.map +1 -0
  58. package/dist/assets/dist-5Z6GjIpR.js +1 -0
  59. package/dist/assets/{dist-CAHkbl3M.js → dist-BJLhyG8r.js} +3 -3
  60. package/dist/assets/{dist-CAHkbl3M.js.map → dist-BJLhyG8r.js.map} +1 -1
  61. package/dist/assets/dist-C5-_1l75.js +1 -0
  62. package/dist/assets/{dist-BsRvt0gH.js → dist-C8EQUxWW.js} +3 -3
  63. package/dist/assets/{dist-BsRvt0gH.js.map → dist-C8EQUxWW.js.map} +1 -1
  64. package/dist/assets/{dist-Dp6eBE2S.js → dist-DGbpjpKB.js} +2 -2
  65. package/dist/assets/{dist-Dp6eBE2S.js.map → dist-DGbpjpKB.js.map} +1 -1
  66. package/dist/assets/dist-M4o-5YLq.js +1 -0
  67. package/dist/assets/edit-ui.es-BT7ftsox.js +1 -0
  68. package/dist/assets/{edit-ui.es-UaQFL_My.js → edit-ui.es-DJgikaS7.js} +2 -2
  69. package/dist/assets/{edit-ui.es-UaQFL_My.js.map → edit-ui.es-DJgikaS7.js.map} +1 -1
  70. package/dist/assets/elo-5Z2qkwtw.js +1 -0
  71. package/dist/assets/{elo-COgu6Hu5.js → elo-C4ZdbMIJ.js} +2 -2
  72. package/dist/assets/{elo-COgu6Hu5.js.map → elo-C4ZdbMIJ.js.map} +1 -1
  73. package/dist/assets/{eloDistance-BV7vfiK5.js → eloDistance-CRxxdYPJ.js} +2 -2
  74. package/dist/assets/{eloDistance-BV7vfiK5.js.map → eloDistance-CRxxdYPJ.js.map} +1 -1
  75. package/dist/assets/eloDistance-DF4pmPOI.js +1 -0
  76. package/dist/assets/{french-Dk7YG8Td-CD7Hms2j.js → french-Dk7YG8Td-C2awfrzV.js} +2 -2
  77. package/dist/assets/{french-Dk7YG8Td-CD7Hms2j.js.map → french-Dk7YG8Td-C2awfrzV.js.map} +1 -1
  78. package/dist/assets/french-evUMlbbq-4izQyIk4.js +1 -0
  79. package/dist/assets/{hierarchyDefinition-DLC5DjaA.js → hierarchyDefinition-BbqnGEfR.js} +2 -2
  80. package/dist/assets/{hierarchyDefinition-DLC5DjaA.js.map → hierarchyDefinition-BbqnGEfR.js.map} +1 -1
  81. package/dist/assets/{index-CK-rfSIx.js → index-BRaeVAZb.js} +4 -4
  82. package/dist/assets/{index-CK-rfSIx.js.map → index-BRaeVAZb.js.map} +1 -1
  83. package/dist/assets/{interferenceMitigator-D78KgOxz.js → interferenceMitigator-BtAQm-0d.js} +2 -2
  84. package/dist/assets/{interferenceMitigator-D78KgOxz.js.map → interferenceMitigator-BtAQm-0d.js.map} +1 -1
  85. package/dist/assets/math-DR3fXDcX-Bj6dcLDF.js +1 -0
  86. package/dist/assets/{math-D_8HiEQR-E4QDLrWp.js → math-D_8HiEQR-CQynsoTm.js} +2 -2
  87. package/dist/assets/{math-D_8HiEQR-E4QDLrWp.js.map → math-D_8HiEQR-CQynsoTm.js.map} +1 -1
  88. package/dist/assets/piano-BN5Btq91-onBUnVgA.js +1 -0
  89. package/dist/assets/{piano-DF1g6yaX-Ck3BH5EK.js → piano-DF1g6yaX-vXbP1jX_.js} +2 -2
  90. package/dist/assets/{piano-DF1g6yaX-Ck3BH5EK.js.map → piano-DF1g6yaX-vXbP1jX_.js.map} +1 -1
  91. package/dist/assets/{pitch-CgGJFkZ1-Dd0LzmEe.js → pitch-CgGJFkZ1-DVzOpIVa.js} +2 -2
  92. package/dist/assets/{pitch-CgGJFkZ1-Dd0LzmEe.js.map → pitch-CgGJFkZ1-DVzOpIVa.js.map} +1 -1
  93. package/dist/assets/pitch-Dn0iNqiS-L2k4d66s.js +1 -0
  94. package/dist/assets/prescribed-Cjutx2ct.js +2 -0
  95. package/dist/assets/prescribed-Cjutx2ct.js.map +1 -0
  96. package/dist/assets/{relativePriority-DwPMECAp.js → relativePriority-fx6BMJm9.js} +2 -2
  97. package/dist/assets/{relativePriority-DwPMECAp.js.map → relativePriority-fx6BMJm9.js.map} +1 -1
  98. package/dist/assets/{server-CqR7xtQy.js → server-CUqWbXPL.js} +2 -2
  99. package/dist/assets/{server-CqR7xtQy.js.map → server-CUqWbXPL.js.map} +1 -1
  100. package/dist/assets/{sightsing-BFQ7HRig-DV69ELZf.js → sightsing-BFQ7HRig-CYuNcd8z.js} +2 -2
  101. package/dist/assets/{sightsing-BFQ7HRig-DV69ELZf.js.map → sightsing-BFQ7HRig-CYuNcd8z.js.map} +1 -1
  102. package/dist/assets/sightsing-CJX3k0Fd-C4-zGBSZ.js +1 -0
  103. package/dist/assets/{srs-DOsG9Y-i.js → srs-B3R2C3TU.js} +2 -2
  104. package/dist/assets/{srs-DOsG9Y-i.js.map → srs-B3R2C3TU.js.map} +1 -1
  105. package/dist/assets/srs-BD4FD2rw.js +1 -0
  106. package/dist/assets/{typing-BevtfWlp-CvStu5BY.js → typing-BevtfWlp-C0NbuTKI.js} +2 -2
  107. package/dist/assets/{typing-BevtfWlp-CvStu5BY.js.map → typing-BevtfWlp-C0NbuTKI.js.map} +1 -1
  108. package/dist/assets/typing-k-ojjO7G-gZjZ4YQx.js +1 -0
  109. package/dist/assets/{userDBKeys-DYLGKnVC.js → userDBKeys-3SQjNVdK.js} +4 -4
  110. package/dist/assets/{userDBKeys-DYLGKnVC.js.map → userDBKeys-3SQjNVdK.js.map} +1 -1
  111. package/dist/assets/{userTagPreference-cZCPqadC.js → userTagPreference-B23ZX5J4.js} +2 -2
  112. package/dist/assets/{userTagPreference-cZCPqadC.js.map → userTagPreference-B23ZX5J4.js.map} +1 -1
  113. package/dist/assets/validators-CnxSFY0I.js +2 -0
  114. package/dist/assets/{validators-lpYAHmRR.js.map → validators-CnxSFY0I.js.map} +1 -1
  115. package/dist/assets/{word-work-BOnRlZgd-CCGZdwyf.js → word-work-BOnRlZgd-CsMkeNdI.js} +2 -2
  116. package/dist/assets/{word-work-BOnRlZgd-CCGZdwyf.js.map → word-work-BOnRlZgd-CsMkeNdI.js.map} +1 -1
  117. package/dist/assets/word-work-Dd6tIKrt-WI45cKxO.js +1 -0
  118. package/dist/index.html +9 -9
  119. package/dist/sw.js +1 -1
  120. package/dist/sw.js.map +1 -1
  121. package/package.json +7 -7
  122. package/dist/assets/BaseUserDB-CV2ZPZOR.js +0 -1
  123. package/dist/assets/CouchDBSyncStrategy-BjM7ROXC.js +0 -1
  124. package/dist/assets/CourseSyncService-CPU_Ll1h.js +0 -1
  125. package/dist/assets/PouchDataLayerProvider-DxsnSIKd.js +0 -2
  126. package/dist/assets/PouchDataLayerProvider-DxsnSIKd.js.map +0 -1
  127. package/dist/assets/UserDBDebugger-xmycWjck.js +0 -1
  128. package/dist/assets/chess-Lfm7Fsvs-DgN08Qx9.js +0 -1
  129. package/dist/assets/contentSource-DwznMSMs.js.map +0 -1
  130. package/dist/assets/dist-BcwaOf54.js +0 -1
  131. package/dist/assets/dist-CgW7D_Gh.js +0 -1
  132. package/dist/assets/dist-Dnehy0sn.js +0 -1
  133. package/dist/assets/edit-ui.es-BWqvElsJ.js +0 -1
  134. package/dist/assets/elo-Cwa8a3Yo.js +0 -1
  135. package/dist/assets/eloDistance-MReQeAuj.js +0 -1
  136. package/dist/assets/french-evUMlbbq-nGCjilG6.js +0 -1
  137. package/dist/assets/math-DR3fXDcX-C9KfHLHP.js +0 -1
  138. package/dist/assets/piano-BN5Btq91-CnKhyLGE.js +0 -1
  139. package/dist/assets/pitch-Dn0iNqiS-BxAdpDDb.js +0 -1
  140. package/dist/assets/prescribed-BWO17Gan.js +0 -2
  141. package/dist/assets/prescribed-BWO17Gan.js.map +0 -1
  142. package/dist/assets/sightsing-CJX3k0Fd-CG94OiDr.js +0 -1
  143. package/dist/assets/srs-DGscV6W4.js +0 -1
  144. package/dist/assets/typing-k-ojjO7G-AF8vU_q7.js +0 -1
  145. package/dist/assets/validators-lpYAHmRR.js +0 -2
  146. package/dist/assets/word-work-Dd6tIKrt-BNTSCq5F.js +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"NewCourseDialog-DBgFVnt3.js","names":[],"sources":["../../src/components/Courses/NewCourseDialog.vue","../../src/components/Courses/NewCourseDialog.vue"],"sourcesContent":["<template>\n <v-card>\n <v-toolbar flat color=\"primary\" dark>\n <v-card-title class=\"text-h6 font-weight-regular\"> Start a New Quilt </v-card-title>\n <v-spacer></v-spacer>\n <v-btn icon @click=\"clearFormAndDismiss\">\n <v-icon icon=\"mdi-close\"></v-icon>\n </v-btn>\n </v-toolbar>\n <v-form>\n <v-container>\n <v-row class=\"cols sm md\">\n <v-text-field\n v-model=\"courseName\"\n counter=\"30\"\n :rules=\"nameRules\"\n label=\"Quilt Name\"\n required\n hint=\"Short and descriptive\"\n data-cy=\"course-name-input\"\n ></v-text-field>\n </v-row>\n <v-row class=\"cols sm md\">\n <v-textarea\n v-model=\"description\"\n variant=\"outlined\"\n counter=\"300\"\n auto-grow\n label=\"Quilt Description\"\n hint=\"Describe the course. What subject is covered? Who might be interested?\"\n data-cy=\"course-description-input\"\n >\n </v-textarea>\n </v-row>\n <v-row class=\"cols sm md\">\n <label>Public or private quilt?</label>\n <v-radio-group\n v-model=\"publicCourse\"\n required\n hint=\"Private quilts can be shared and collaborated on with other individual users, but will not be accessable without an invitation. A private quilt can be made public later.\"\n persistent-hint\n inline\n data-cy=\"course-visibility-radio\"\n >\n <v-radio label=\"Public\" :value=\"true\" data-cy=\"public-radio\"></v-radio>\n <v-radio label=\"Private\" :value=\"false\" data-cy=\"private-radio\"></v-radio>\n </v-radio-group>\n </v-row>\n <v-row class=\"cols sm md\">\n <v-btn :loading=\"updatePending\" color=\"primary\" data-cy=\"save-course-button\" @click=\"submit\">\n Save Course Changes\n </v-btn>\n </v-row>\n </v-container>\n </v-form>\n </v-card>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent } from 'vue';\nimport Mousetrap from 'mousetrap';\nimport serverRequest from '../../server';\nimport { CourseConfig, CreateCourse, DataShape55, QuestionType55, ServerRequestType } from '@vue-skuilder/common';\nimport { alertUser, getCurrentUser } from '@vue-skuilder/common-ui';\n\nexport default defineComponent({\n name: 'NewCourseDialog',\n\n props: {\n name: {\n type: String,\n required: false,\n default: '',\n },\n },\n\n emits: ['CourseEditingComplete'],\n\n data() {\n return {\n mousetrap: new Mousetrap(this.$el),\n id: '',\n courseName: '',\n description: '',\n publicCourse: false,\n deleted: false,\n admins: [] as string[],\n moderators: [] as string[],\n dataShapes: [] as DataShape55[],\n questionTypes: [] as QuestionType55[],\n banner: undefined as Blob | undefined,\n thumb: undefined as Blob | undefined,\n updatePending: false,\n nameRules: [\n (value: string): string | boolean => {\n const max = 30;\n if (value.length > max) {\n return `Course name must be ${max} characters or less`;\n } else {\n return true;\n }\n },\n ],\n };\n },\n\n created() {\n this.mousetrap.bind('esc', this.clearFormAndDismiss);\n },\n\n methods: {\n async submit() {\n this.updatePending = true;\n\n const u = await getCurrentUser();\n\n const config: CourseConfig = {\n name: this.courseName,\n description: this.description,\n public: this.publicCourse,\n deleted: this.deleted,\n creator: u.getUsername(),\n admins: this.admins,\n moderators: this.moderators,\n dataShapes: this.dataShapes,\n questionTypes: this.questionTypes,\n };\n\n const result = await serverRequest<CreateCourse>({\n data: config,\n type: ServerRequestType.CREATE_COURSE,\n response: null,\n user: u.getUsername(),\n });\n\n if (result.response && result.response.ok) {\n alertUser({\n text: `Course ${this.courseName} created.`,\n status: result.response!.status,\n });\n this.clearFormAndDismiss();\n } else {\n alertUser({\n text: `Failed to create course ${this.courseName}.`,\n status: result.response!.status,\n });\n console.warn(`Resp: ${JSON.stringify(result.response)}`);\n }\n\n this.updatePending = false;\n },\n\n clearFormAndDismiss() {\n this.description = '';\n this.publicCourse = false;\n this.deleted = false;\n this.admins = [];\n this.moderators = [];\n\n this.$emit('CourseEditingComplete');\n },\n },\n});\n</script>\n","<template>\n <v-card>\n <v-toolbar flat color=\"primary\" dark>\n <v-card-title class=\"text-h6 font-weight-regular\"> Start a New Quilt </v-card-title>\n <v-spacer></v-spacer>\n <v-btn icon @click=\"clearFormAndDismiss\">\n <v-icon icon=\"mdi-close\"></v-icon>\n </v-btn>\n </v-toolbar>\n <v-form>\n <v-container>\n <v-row class=\"cols sm md\">\n <v-text-field\n v-model=\"courseName\"\n counter=\"30\"\n :rules=\"nameRules\"\n label=\"Quilt Name\"\n required\n hint=\"Short and descriptive\"\n data-cy=\"course-name-input\"\n ></v-text-field>\n </v-row>\n <v-row class=\"cols sm md\">\n <v-textarea\n v-model=\"description\"\n variant=\"outlined\"\n counter=\"300\"\n auto-grow\n label=\"Quilt Description\"\n hint=\"Describe the course. What subject is covered? Who might be interested?\"\n data-cy=\"course-description-input\"\n >\n </v-textarea>\n </v-row>\n <v-row class=\"cols sm md\">\n <label>Public or private quilt?</label>\n <v-radio-group\n v-model=\"publicCourse\"\n required\n hint=\"Private quilts can be shared and collaborated on with other individual users, but will not be accessable without an invitation. A private quilt can be made public later.\"\n persistent-hint\n inline\n data-cy=\"course-visibility-radio\"\n >\n <v-radio label=\"Public\" :value=\"true\" data-cy=\"public-radio\"></v-radio>\n <v-radio label=\"Private\" :value=\"false\" data-cy=\"private-radio\"></v-radio>\n </v-radio-group>\n </v-row>\n <v-row class=\"cols sm md\">\n <v-btn :loading=\"updatePending\" color=\"primary\" data-cy=\"save-course-button\" @click=\"submit\">\n Save Course Changes\n </v-btn>\n </v-row>\n </v-container>\n </v-form>\n </v-card>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent } from 'vue';\nimport Mousetrap from 'mousetrap';\nimport serverRequest from '../../server';\nimport { CourseConfig, CreateCourse, DataShape55, QuestionType55, ServerRequestType } from '@vue-skuilder/common';\nimport { alertUser, getCurrentUser } from '@vue-skuilder/common-ui';\n\nexport default defineComponent({\n name: 'NewCourseDialog',\n\n props: {\n name: {\n type: String,\n required: false,\n default: '',\n },\n },\n\n emits: ['CourseEditingComplete'],\n\n data() {\n return {\n mousetrap: new Mousetrap(this.$el),\n id: '',\n courseName: '',\n description: '',\n publicCourse: false,\n deleted: false,\n admins: [] as string[],\n moderators: [] as string[],\n dataShapes: [] as DataShape55[],\n questionTypes: [] as QuestionType55[],\n banner: undefined as Blob | undefined,\n thumb: undefined as Blob | undefined,\n updatePending: false,\n nameRules: [\n (value: string): string | boolean => {\n const max = 30;\n if (value.length > max) {\n return `Course name must be ${max} characters or less`;\n } else {\n return true;\n }\n },\n ],\n };\n },\n\n created() {\n this.mousetrap.bind('esc', this.clearFormAndDismiss);\n },\n\n methods: {\n async submit() {\n this.updatePending = true;\n\n const u = await getCurrentUser();\n\n const config: CourseConfig = {\n name: this.courseName,\n description: this.description,\n public: this.publicCourse,\n deleted: this.deleted,\n creator: u.getUsername(),\n admins: this.admins,\n moderators: this.moderators,\n dataShapes: this.dataShapes,\n questionTypes: this.questionTypes,\n };\n\n const result = await serverRequest<CreateCourse>({\n data: config,\n type: ServerRequestType.CREATE_COURSE,\n response: null,\n user: u.getUsername(),\n });\n\n if (result.response && result.response.ok) {\n alertUser({\n text: `Course ${this.courseName} created.`,\n status: result.response!.status,\n });\n this.clearFormAndDismiss();\n } else {\n alertUser({\n text: `Failed to create course ${this.courseName}.`,\n status: result.response!.status,\n });\n console.warn(`Resp: ${JSON.stringify(result.response)}`);\n }\n\n this.updatePending = false;\n },\n\n clearFormAndDismiss() {\n this.description = '';\n this.publicCourse = false;\n this.deleted = false;\n this.admins = [];\n this.moderators = [];\n\n this.$emit('CourseEditingComplete');\n },\n },\n});\n</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"NewCourseDialog-DNzvvz_H.js","names":[],"sources":["../../src/components/Courses/NewCourseDialog.vue","../../src/components/Courses/NewCourseDialog.vue"],"sourcesContent":["<template>\n <v-card>\n <v-toolbar flat color=\"primary\" dark>\n <v-card-title class=\"text-h6 font-weight-regular\"> Start a New Quilt </v-card-title>\n <v-spacer></v-spacer>\n <v-btn icon @click=\"clearFormAndDismiss\">\n <v-icon icon=\"mdi-close\"></v-icon>\n </v-btn>\n </v-toolbar>\n <v-form>\n <v-container>\n <v-row class=\"cols sm md\">\n <v-text-field\n v-model=\"courseName\"\n counter=\"30\"\n :rules=\"nameRules\"\n label=\"Quilt Name\"\n required\n hint=\"Short and descriptive\"\n data-cy=\"course-name-input\"\n ></v-text-field>\n </v-row>\n <v-row class=\"cols sm md\">\n <v-textarea\n v-model=\"description\"\n variant=\"outlined\"\n counter=\"300\"\n auto-grow\n label=\"Quilt Description\"\n hint=\"Describe the course. What subject is covered? Who might be interested?\"\n data-cy=\"course-description-input\"\n >\n </v-textarea>\n </v-row>\n <v-row class=\"cols sm md\">\n <label>Public or private quilt?</label>\n <v-radio-group\n v-model=\"publicCourse\"\n required\n hint=\"Private quilts can be shared and collaborated on with other individual users, but will not be accessable without an invitation. A private quilt can be made public later.\"\n persistent-hint\n inline\n data-cy=\"course-visibility-radio\"\n >\n <v-radio label=\"Public\" :value=\"true\" data-cy=\"public-radio\"></v-radio>\n <v-radio label=\"Private\" :value=\"false\" data-cy=\"private-radio\"></v-radio>\n </v-radio-group>\n </v-row>\n <v-row class=\"cols sm md\">\n <v-btn :loading=\"updatePending\" color=\"primary\" data-cy=\"save-course-button\" @click=\"submit\">\n Save Course Changes\n </v-btn>\n </v-row>\n </v-container>\n </v-form>\n </v-card>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent } from 'vue';\nimport Mousetrap from 'mousetrap';\nimport serverRequest from '../../server';\nimport { CourseConfig, CreateCourse, DataShape55, QuestionType55, ServerRequestType } from '@vue-skuilder/common';\nimport { alertUser, getCurrentUser } from '@vue-skuilder/common-ui';\n\nexport default defineComponent({\n name: 'NewCourseDialog',\n\n props: {\n name: {\n type: String,\n required: false,\n default: '',\n },\n },\n\n emits: ['CourseEditingComplete'],\n\n data() {\n return {\n mousetrap: new Mousetrap(this.$el),\n id: '',\n courseName: '',\n description: '',\n publicCourse: false,\n deleted: false,\n admins: [] as string[],\n moderators: [] as string[],\n dataShapes: [] as DataShape55[],\n questionTypes: [] as QuestionType55[],\n banner: undefined as Blob | undefined,\n thumb: undefined as Blob | undefined,\n updatePending: false,\n nameRules: [\n (value: string): string | boolean => {\n const max = 30;\n if (value.length > max) {\n return `Course name must be ${max} characters or less`;\n } else {\n return true;\n }\n },\n ],\n };\n },\n\n created() {\n this.mousetrap.bind('esc', this.clearFormAndDismiss);\n },\n\n methods: {\n async submit() {\n this.updatePending = true;\n\n const u = await getCurrentUser();\n\n const config: CourseConfig = {\n name: this.courseName,\n description: this.description,\n public: this.publicCourse,\n deleted: this.deleted,\n creator: u.getUsername(),\n admins: this.admins,\n moderators: this.moderators,\n dataShapes: this.dataShapes,\n questionTypes: this.questionTypes,\n };\n\n const result = await serverRequest<CreateCourse>({\n data: config,\n type: ServerRequestType.CREATE_COURSE,\n response: null,\n user: u.getUsername(),\n });\n\n if (result.response && result.response.ok) {\n alertUser({\n text: `Course ${this.courseName} created.`,\n status: result.response!.status,\n });\n this.clearFormAndDismiss();\n } else {\n alertUser({\n text: `Failed to create course ${this.courseName}.`,\n status: result.response!.status,\n });\n console.warn(`Resp: ${JSON.stringify(result.response)}`);\n }\n\n this.updatePending = false;\n },\n\n clearFormAndDismiss() {\n this.description = '';\n this.publicCourse = false;\n this.deleted = false;\n this.admins = [];\n this.moderators = [];\n\n this.$emit('CourseEditingComplete');\n },\n },\n});\n</script>\n","<template>\n <v-card>\n <v-toolbar flat color=\"primary\" dark>\n <v-card-title class=\"text-h6 font-weight-regular\"> Start a New Quilt </v-card-title>\n <v-spacer></v-spacer>\n <v-btn icon @click=\"clearFormAndDismiss\">\n <v-icon icon=\"mdi-close\"></v-icon>\n </v-btn>\n </v-toolbar>\n <v-form>\n <v-container>\n <v-row class=\"cols sm md\">\n <v-text-field\n v-model=\"courseName\"\n counter=\"30\"\n :rules=\"nameRules\"\n label=\"Quilt Name\"\n required\n hint=\"Short and descriptive\"\n data-cy=\"course-name-input\"\n ></v-text-field>\n </v-row>\n <v-row class=\"cols sm md\">\n <v-textarea\n v-model=\"description\"\n variant=\"outlined\"\n counter=\"300\"\n auto-grow\n label=\"Quilt Description\"\n hint=\"Describe the course. What subject is covered? Who might be interested?\"\n data-cy=\"course-description-input\"\n >\n </v-textarea>\n </v-row>\n <v-row class=\"cols sm md\">\n <label>Public or private quilt?</label>\n <v-radio-group\n v-model=\"publicCourse\"\n required\n hint=\"Private quilts can be shared and collaborated on with other individual users, but will not be accessable without an invitation. A private quilt can be made public later.\"\n persistent-hint\n inline\n data-cy=\"course-visibility-radio\"\n >\n <v-radio label=\"Public\" :value=\"true\" data-cy=\"public-radio\"></v-radio>\n <v-radio label=\"Private\" :value=\"false\" data-cy=\"private-radio\"></v-radio>\n </v-radio-group>\n </v-row>\n <v-row class=\"cols sm md\">\n <v-btn :loading=\"updatePending\" color=\"primary\" data-cy=\"save-course-button\" @click=\"submit\">\n Save Course Changes\n </v-btn>\n </v-row>\n </v-container>\n </v-form>\n </v-card>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent } from 'vue';\nimport Mousetrap from 'mousetrap';\nimport serverRequest from '../../server';\nimport { CourseConfig, CreateCourse, DataShape55, QuestionType55, ServerRequestType } from '@vue-skuilder/common';\nimport { alertUser, getCurrentUser } from '@vue-skuilder/common-ui';\n\nexport default defineComponent({\n name: 'NewCourseDialog',\n\n props: {\n name: {\n type: String,\n required: false,\n default: '',\n },\n },\n\n emits: ['CourseEditingComplete'],\n\n data() {\n return {\n mousetrap: new Mousetrap(this.$el),\n id: '',\n courseName: '',\n description: '',\n publicCourse: false,\n deleted: false,\n admins: [] as string[],\n moderators: [] as string[],\n dataShapes: [] as DataShape55[],\n questionTypes: [] as QuestionType55[],\n banner: undefined as Blob | undefined,\n thumb: undefined as Blob | undefined,\n updatePending: false,\n nameRules: [\n (value: string): string | boolean => {\n const max = 30;\n if (value.length > max) {\n return `Course name must be ${max} characters or less`;\n } else {\n return true;\n }\n },\n ],\n };\n },\n\n created() {\n this.mousetrap.bind('esc', this.clearFormAndDismiss);\n },\n\n methods: {\n async submit() {\n this.updatePending = true;\n\n const u = await getCurrentUser();\n\n const config: CourseConfig = {\n name: this.courseName,\n description: this.description,\n public: this.publicCourse,\n deleted: this.deleted,\n creator: u.getUsername(),\n admins: this.admins,\n moderators: this.moderators,\n dataShapes: this.dataShapes,\n questionTypes: this.questionTypes,\n };\n\n const result = await serverRequest<CreateCourse>({\n data: config,\n type: ServerRequestType.CREATE_COURSE,\n response: null,\n user: u.getUsername(),\n });\n\n if (result.response && result.response.ok) {\n alertUser({\n text: `Course ${this.courseName} created.`,\n status: result.response!.status,\n });\n this.clearFormAndDismiss();\n } else {\n alertUser({\n text: `Failed to create course ${this.courseName}.`,\n status: result.response!.status,\n });\n console.warn(`Resp: ${JSON.stringify(result.response)}`);\n }\n\n this.updatePending = false;\n },\n\n clearFormAndDismiss() {\n this.description = '';\n this.publicCourse = false;\n this.deleted = false;\n this.admins = [];\n this.moderators = [];\n\n this.$emit('CourseEditingComplete');\n },\n },\n});\n</script>\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/elo-Cwa8a3Yo.js","assets/elo-COgu6Hu5.js","assets/defineProperty-y9rbOPYz.js","assets/chunk-D6hFPZc3.js","assets/elo-B5qCwvSC.js","assets/tagRoles-jR-PJAgj.js","assets/srs-DGscV6W4.js","assets/moment-DbT30ZpG.js","assets/srs-DOsG9Y-i.js","assets/prescribed-BWO17Gan.js","assets/hierarchyDefinition-DLC5DjaA.js","assets/interferenceMitigator-D78KgOxz.js","assets/relativePriority-DwPMECAp.js","assets/userTagPreference-cZCPqadC.js","assets/eloDistance-MReQeAuj.js","assets/eloDistance-BV7vfiK5.js"])))=>i.map(i=>d[i]);
2
- import"./chunk-D6hFPZc3.js";import{t as e}from"./defineProperty-y9rbOPYz.js";var t=`modulepreload`,assetsURL=function(e){return`/`+e},n={},r=function preload(e,r,i){let a=Promise.resolve();if(r&&r.length>0){let e=document.getElementsByTagName(`link`),o=document.querySelector(`meta[property=csp-nonce]`),s=o?.nonce||o?.getAttribute(`nonce`);function allSettled(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}a=allSettled(r.map(r=>{if(r=assetsURL(r,i),r in n)return;n[r]=!0;let a=r.endsWith(`.css`),o=a?`[rel="stylesheet"]`:``;if(i)for(let t=e.length-1;t>=0;t--){let n=e[t];if(n.href===r&&(!a||n.rel===`stylesheet`))return}else if(document.querySelector(`link[href="${r}"]${o}`))return;let c=document.createElement(`link`);if(c.rel=a?`stylesheet`:t,a||(c.as=`script`),c.crossOrigin=``,c.href=r,s&&c.setAttribute(`nonce`,s),document.head.appendChild(c),a)return new Promise((e,t)=>{c.addEventListener(`load`,e),c.addEventListener(`error`,()=>t(Error(`Unable to preload CSS for ${r}`)))})}))}function handlePreloadError(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return a.then(t=>{for(let e of t||[])e.status===`rejected`&&handlePreloadError(e.reason);return e().catch(handlePreloadError)})};Object.defineProperty;var i=`diversityRerank`,a=`DIVERSITY_RERANK`,o=`Diversity Re-rank`;function diversityRerank(e,t={}){let n=t.strength??.6,r=t.floor??.3,s=e.length;if(s<=1)return e;let c=new Map;for(let t of e)for(let e of t.tags??[])c.set(e,(c.get(e)??0)+1);let l=new Map;for(let[e,t]of c)l.set(e,Math.log(s/t));let u=[...e],d=new Map,f=[],repetitionLoad=e=>{let t=0;for(let n of e.tags??[]){let e=d.get(n);e&&(t+=(l.get(n)??0)*e)}return t};for(;u.length>0;){let e=0,t=-1/0,s=1,c=0;for(let i=0;i<u.length;i++){let a=u[i],o=repetitionLoad(a),l=o>0?Math.max(r,1/(1+n*o)):1,d=a.score*l;d>t&&(t=d,e=i,s=l,c=o)}let[l]=u.splice(e,1);if(Number.isFinite(l.score)&&s<1){let e=l.score*s;f.push({...l,score:e,provenance:[...l.provenance,{strategy:i,strategyId:a,strategyName:o,action:`penalized`,score:e,reason:`repeated tags (load ${c.toFixed(2)}) → ×${s.toFixed(2)}`}]})}else f.push(l);for(let e of l.tags??[])d.set(e,(d.get(e)??0)+1)}return f}var s,c={debug:0,info:1,warn:2,error:3,silent:4},l=`sk.logLevel`,u=typeof window<`u`;function isLevel(e){return typeof e==`string`&&e in c}function initialLevel(){if(u){try{let e=window.localStorage?.getItem(l);if(isLevel(e))return e}catch{}return`warn`}if(typeof process<`u`){let e={GITHUB_STATE:`/home/runner/work/_temp/_runner_file_commands/save_state_3988287d-bb8f-43db-9bf6-1aa57225de97`,DOTNET_NOLOGO:`1`,USER:`runner`,npm_config_user_agent:`yarn/4.12.0 npm/? node/v22.23.4 linux x64`,CI:`true`,USE_BAZEL_FALLBACK_VERSION:`silent:`,RUNNER_ENVIRONMENT:`github-hosted`,GITHUB_ENV:`/home/runner/work/_temp/_runner_file_commands/set_env_3988287d-bb8f-43db-9bf6-1aa57225de97`,PIPX_HOME:`/opt/pipx`,npm_node_execpath:`/tmp/xfs-32bb278b/node`,NODE_AUTH_TOKEN:`XXXXX-XXXXX-XXXXX-XXXXX`,SHLVL:`1`,HCA_CLOUD_PROVIDER:`azure`,HOME:`/home/runner`,RUNNER_TEMP:`/home/runner/work/_temp`,GITHUB_EVENT_PATH:`/home/runner/work/_temp/_github_workflow/event.json`,npm_package_json:`/home/runner/work/vue-skuilder/vue-skuilder/packages/platform-ui/package.json`,JAVA_HOME_11_X64:`/usr/lib/jvm/temurin-11-jdk-amd64`,PIPX_BIN_DIR:`/opt/pipx_bin`,GITHUB_REPOSITORY_OWNER:`patched-network`,COREPACK_ROOT:`/opt/hostedtoolcache/node/22.23.4/x64/lib/node_modules/corepack`,GRADLE_HOME:`/usr/share/gradle-9.8.2`,ANDROID_NDK_LATEST_HOME:`/usr/local/lib/android/sdk/ndk/30.0.16248370`,JAVA_HOME_21_X64:`/usr/lib/jvm/temurin-21-jdk-amd64`,GITHUB_RETENTION_DAYS:`90`,GITHUB_REPOSITORY_OWNER_ID:`200830069`,POWERSHELL_DISTRIBUTION_CHANNEL:`GitHub-Actions-Linux`,AZURE_EXTENSION_DIR:`/opt/az/azcliextensions`,GITHUB_HEAD_REF:``,SYSTEMD_EXEC_PID:`1972`,ACTIONS_ORCHESTRATION_ID:`4e7f1981-a7d2-8f5e-bac6-a99cdf3c4db6.publish.__default`,GITHUB_GRAPHQL_URL:`https://api.github.com/graphql`,JAVA_HOME_25_X64:`/usr/lib/jvm/temurin-25-jdk-amd64`,NVM_DIR:`/home/runner/.nvm`,DOTNET_SKIP_FIRST_TIME_EXPERIENCE:`1`,JAVA_HOME_17_X64:`/usr/lib/jvm/temurin-17-jdk-amd64`,ImageVersion:`20261101.186.1`,COREPACK_ENABLE_DOWNLOAD_PROMPT:`1`,LOGNAME:`runner`,RUNNER_OS:`Linux`,GITHUB_API_URL:`https://api.github.com`,GITHUB_ARTIFACTS:`/home/runner/work/_temp/_runner_file_commands/artifacts_3988287d-bb8f-43db-9bf6-1aa57225de97`,SWIFT_PATH:`/usr/share/swift/usr/bin`,CHROMEWEBDRIVER:`/usr/local/share/chromedriver-linux64`,JOURNAL_STREAM:`10:17719`,GITHUB_WORKFLOW:`Publish to NPM`,_:`/opt/hostedtoolcache/node/22.23.4/x64/bin/yarn`,MEMORY_PRESSURE_WATCH:`/sys/fs/cgroup/system.slice/hosted-compute-agent.service/memory.pressure`,GOROOT_1_24_X64:`/opt/hostedtoolcache/go/1.24.13/x64`,ACTIONS_RUNNER_ACTION_ARCHIVE_CACHE:`/opt/actionarchivecache`,GOROOT_1_25_X64:`/opt/hostedtoolcache/go/1.25.14/x64`,GITHUB_RUN_ID:`42146212139`,GITHUB_REF_TYPE:`tag`,BOOTSTRAP_HASKELL_NONINTERACTIVE:`1`,GITHUB_WORKFLOW_SHA:`86b1ebd9a05816f60daa81986bae5a580ba5dcb9`,GOROOT_1_26_X64:`/opt/hostedtoolcache/go/1.26.10/x64`,GITHUB_BASE_REF:``,ImageOS:`ubuntu26`,GITHUB_WORKFLOW_REF:`patched-network/vue-skuilder/.github/workflows/publish-npm.yml@refs/tags/v0.2.36`,ACTIONS_ID_TOKEN_REQUEST_TOKEN:`eyJhbGciOiJSUzI1NiIsImtpZCI6IjM4ODI2YjE3LTZhMzAtNWY5Yi1iMTY5LThiZWI4MjAyZjcyMyIsInR5cCI6IkpXVCIsIng1dCI6InlrTmFZNHFNX3RhNGsyVGdaT0NFWUxrY1lsQSJ9.eyJJZGVudGl0eVR5cGVDbGFpbSI6IlN5c3RlbTpTZXJ2aWNlSWRlbnRpdHkiLCJhYyI6Ilt7XCJTY29wZVwiOlwicmVmcy9oZWFkcy9yZWZzL3RhZ3MvdjAuMi4zNlwiLFwiUGVybWlzc2lvblwiOjN9LHtcIlNjb3BlXCI6XCJyZWZzL2hlYWRzL21hc3RlclwiLFwiUGVybWlzc2lvblwiOjF9XSIsImFjc2wiOiIxMCIsImF1ZCI6InZzbzphNjljOTEzYS1mYzg4LTRkOTktYjllZi1mOTYxZTc2ZGYyMjkiLCJiaWxsaW5nX293bmVyX2lkIjoiT19rZ0RPQ19oc2RRIiwiZXhwIjoxNzkzOTUxODg4LCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3ByaW1hcnlzaWQiOiJkZGRkZGRkZC1kZGRkLWRkZGQtZGRkZC1kZGRkZGRkZGRkZGQiLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9zaWQiOiJkZGRkZGRkZC1kZGRkLWRkZGQtZGRkZC1kZGRkZGRkZGRkZGQiLCJpYXQiOjE3OTM5Mjk2ODgsImlzcyI6Imh0dHBzOi8vdG9rZW4uYWN0aW9ucy5naXRodWJ1c2VyY29udGVudC5jb20iLCJqb2JfaWQiOiJlODU1MzU2OC01NzRiLTVkZTgtYWE0ZS01YzgzMWI3Yjk3ODMiLCJqb2Jfd29ya2Zsb3dfcmVmIjoicGF0Y2hlZC1uZXR3b3JrL3Z1ZS1za3VpbGRlci8uZ2l0aHViL3dvcmtmbG93cy9wdWJsaXNoLW5wbS55bWxAcmVmcy90YWdzL3YwLjIuMzYiLCJqb2Jfd29ya2Zsb3dfc2hhIjoiODZiMWViZDlhMDU4MTZmNjBkYWE4MTk4NmJhZTVhNTgwYmE1ZGNiOSIsIm5hbWVpZCI6ImRkZGRkZGRkLWRkZGQtZGRkZC1kZGRkLWRkZGRkZGRkZGRkZCIsIm5iZiI6MTc5MzkyOTM4OCwib2lkY19leHRyYSI6IntcImFjdG9yXCI6XCJOaWxvQ0tcIixcImFjdG9yX2lkXCI6XCIxMDc4MDU5MFwiLFwiYmFzZV9yZWZcIjpcIlwiLFwiY2hlY2tfcnVuX2lkXCI6XCIxMjc2NTgxOTc0MTVcIixcImV2ZW50X25hbWVcIjpcInB1c2hcIixcImhlYWRfcmVmXCI6XCJcIixcImpvYl93b3JrZmxvd19yZWZcIjpcInBhdGNoZWQtbmV0d29yay92dWUtc2t1aWxkZXIvLmdpdGh1Yi93b3JrZmxvd3MvcHVibGlzaC1ucG0ueW1sQHJlZnMvdGFncy92MC4yLjM2XCIsXCJqb2Jfd29ya2Zsb3dfc2hhXCI6XCI4NmIxZWJkOWEwNTgxNmY2MGRhYTgxOTg2YmFlNWE1ODBiYTVkY2I5XCIsXCJyZWZcIjpcInJlZnMvdGFncy92MC4yLjM2XCIsXCJyZWZfcHJvdGVjdGVkXCI6XCJmYWxzZVwiLFwicmVmX3R5cGVcIjpcInRhZ1wiLFwicmVwb3NpdG9yeVwiOlwicGF0Y2hlZC1uZXR3b3JrL3Z1ZS1za3VpbGRlclwiLFwicmVwb3NpdG9yeV9pZFwiOlwiMTIyODg2MTczXCIsXCJyZXBvc2l0b3J5X293bmVyXCI6XCJwYXRjaGVkLW5ldHdvcmtcIixcInJlcG9zaXRvcnlfb3duZXJfaWRcIjpcIjIwMDgzMDA2OVwiLFwicmVwb3NpdG9yeV92aXNpYmlsaXR5XCI6XCJwdWJsaWNcIixcInJ1bl9hdHRlbXB0XCI6XCIxXCIsXCJydW5faWRcIjpcIjQyMTQ2MjEyMTM5XCIsXCJydW5fbnVtYmVyXCI6XCIxNjVcIixcInJ1bm5lcl9lbnZpcm9ubWVudFwiOlwiZ2l0aHViLWhvc3RlZFwiLFwic2hhXCI6XCI4NmIxZWJkOWEwNTgxNmY2MGRhYTgxOTg2YmFlNWE1ODBiYTVkY2I5XCIsXCJ3b3JrZmxvd1wiOlwiUHVibGlzaCB0byBOUE1cIixcIndvcmtmbG93X3JlZlwiOlwicGF0Y2hlZC1uZXR3b3JrL3Z1ZS1za3VpbGRlci8uZ2l0aHViL3dvcmtmbG93cy9wdWJsaXNoLW5wbS55bWxAcmVmcy90YWdzL3YwLjIuMzZcIixcIndvcmtmbG93X3NoYVwiOlwiODZiMWViZDlhMDU4MTZmNjBkYWE4MTk4NmJhZTVhNTgwYmE1ZGNiOVwifSIsIm9pZGNfc3ViIjoicmVwbzpwYXRjaGVkLW5ldHdvcmsvdnVlLXNrdWlsZGVyOnJlZjpyZWZzL3RhZ3MvdjAuMi4zNiIsIm9yY2hfaWQiOiI0ZTdmMTk4MS1hN2QyLThmNWUtYmFjNi1hOTljZGYzYzRkYjYucHVibGlzaC5fX2RlZmF1bHQiLCJvd25lcl9pZCI6Ik9fa2dET0NfaHNkUSIsInBsYW5faWQiOiI0ZTdmMTk4MS1hN2QyLThmNWUtYmFjNi1hOTljZGYzYzRkYjYiLCJyZXBvc2l0b3J5X2lkIjoiMTIyODg2MTczIiwicmVwb3NpdG9yeV9vd25lcl9pZCI6IjIwMDgzMDA2OSIsInJlcG9zaXRvcnlfdmlzaWJpbGl0eSI6InB1YmxpYyIsInJ1bl9pZCI6IjQyMTQ2MjEyMTM5IiwicnVuX251bWJlciI6IjE2NSIsInJ1bl90eXBlIjoiZnVsbCIsInJ1bm5lcl9pZCI6IjEwMDAwMTYyMTgiLCJydW5uZXJfdHlwZSI6Imhvc3RlZCIsInNjcCI6IkFjdGlvbnMuUmVzdWx0czo0ZTdmMTk4MS1hN2QyLThmNWUtYmFjNi1hOTljZGYzYzRkYjY6ZTg1NTM1NjgtNTc0Yi01ZGU4LWFhNGUtNWM4MzFiN2I5NzgzIEFjdGlvbnMuUnVubmVyOjRlN2YxOTgxLWE3ZDItOGY1ZS1iYWM2LWE5OWNkZjNjNGRiNjplODU1MzU2OC01NzRiLTVkZTgtYWE0ZS01YzgzMWI3Yjk3ODMgQWN0aW9ucy5VcGxvYWRBcnRpZmFjdHM6NGU3ZjE5ODEtYTdkMi04ZjVlLWJhYzYtYTk5Y2RmM2M0ZGI2OmU4NTUzNTY4LTU3NGItNWRlOC1hYTRlLTVjODMxYjdiOTc4MyBnZW5lcmF0ZV9pZF90b2tlbjo0ZTdmMTk4MS1hN2QyLThmNWUtYmFjNi1hOTljZGYzYzRkYjY6ZTg1NTM1NjgtNTc0Yi01ZGU4LWFhNGUtNWM4MzFiN2I5NzgzIEFjdGlvbnMuR2VuZXJpY1JlYWQ6MDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwIiwic2hhIjoiODZiMWViZDlhMDU4MTZmNjBkYWE4MTk4NmJhZTVhNTgwYmE1ZGNiOSIsInRydXN0X3RpZXIiOiIyIn0.zt3SN_pxG_vfZSUaRbmIHbhGskEM8r_q69ZxEEQAcNHO64q5lxLV1WdQFNgvmIoWzNJM0FzKdvwul1PWHgIKj9tvu3qZpJqWSHfZvOJqggBMSYJve7yHJdSa24USoFFux_egyTMDwhTIjw6tdo4M2vF-JJxXTSFgzAnfxZMu9ZqIHK4ZBlga77aZQnkhxC5DGD70axKdH5ZZEeGGqV9C-Ts2xXCk0EGWXNSLcEDFlXoY9C5xopaoaZlAUob-fUnJSuYa1uORoyvR7x-gk1YZ9ZdSObw5Ommk1OwvAJhLf2y_ZrEcuezy04rGGLUxZD8EOu5NB2bR9xQZ9pE9M17bQg`,GITHUB_ACTION_REPOSITORY:``,ENABLE_RUNNER_TRACING:`true`,PATH:`/tmp/xfs-32bb278b:/opt/hostedtoolcache/node/22.23.4/x64/bin:/snap/bin:/home/runner/.local/bin:/opt/pipx_bin:/home/runner/.cargo/bin:/home/runner/.config/composer/vendor/bin:/usr/local/.ghcup/bin:/home/runner/.dotnet/tools:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin`,ANT_HOME:`/usr/share/ant`,DOTNET_MULTILEVEL_LOOKUP:`0`,RUNNER_TRACKING_ID:`github_e119fc80-8428-4fa1-8d00-75f75c299cc4`,INVOCATION_ID:`37076ba8db9849858177891bd7ecf711`,NPM_CONFIG_USERCONFIG:`/home/runner/work/_temp/.npmrc`,RUNNER_TOOL_CACHE:`/opt/hostedtoolcache`,npm_package_name:`@vue-skuilder/platform-ui`,GITHUB_ACTION:`__run_5`,GITHUB_RUN_NUMBER:`165`,GITHUB_TRIGGERING_ACTOR:`NiloCK`,RUNNER_ARCH:`X64`,XDG_RUNTIME_DIR:`/run/user/1001`,AGENT_TOOLSDIRECTORY:`/opt/hostedtoolcache`,LANG:`C.UTF-8`,VCPKG_INSTALLATION_ROOT:`/usr/local/share/vcpkg`,RUNNER_NAME:`GitHub Actions 1000016218`,XDG_CONFIG_HOME:`/home/runner/.config`,GITHUB_REF_NAME:`v0.2.36`,GITHUB_REPOSITORY:`patched-network/vue-skuilder`,ANDROID_NDK_ROOT:`/usr/local/lib/android/sdk/ndk/27.3.13750724`,GITHUB_ACTION_REF:``,DEBIAN_FRONTEND:`noninteractive`,PROJECT_CWD:`/home/runner/work/vue-skuilder/vue-skuilder`,SHELL:`/bin/bash`,GITHUB_REPOSITORY_ID:`122886173`,GITHUB_ACTIONS:`true`,npm_package_version:`0.2.36`,npm_lifecycle_event:`build`,GITHUB_REF_PROTECTED:`false`,GITHUB_WORKSPACE:`/home/runner/work/vue-skuilder/vue-skuilder`,ACCEPT_EULA:`Y`,GITHUB_JOB:`publish`,GITHUB_SHA:`86b1ebd9a05816f60daa81986bae5a580ba5dcb9`,GITHUB_RUN_ATTEMPT:`1`,ACTIONS_RUNNER_RETURN_JOB_RESULT_FOR_HOSTED:`1`,GITHUB_REF:`refs/tags/v0.2.36`,GITHUB_ACTOR:`NiloCK`,ANDROID_SDK_ROOT:`/usr/local/lib/android/sdk`,GITHUB_PATH:`/home/runner/work/_temp/_runner_file_commands/add_path_3988287d-bb8f-43db-9bf6-1aa57225de97`,JAVA_HOME:`/usr/lib/jvm/temurin-25-jdk-amd64`,PWD:`/home/runner/work/vue-skuilder/vue-skuilder/packages/platform-ui`,GITHUB_ACTOR_ID:`10780590`,RUNNER_WORKSPACE:`/home/runner/work/vue-skuilder`,BERRY_BIN_FOLDER:`/tmp/xfs-32bb278b`,npm_execpath:`/tmp/xfs-32bb278b/yarn`,HOMEBREW_CLEANUP_PERIODIC_FULL_DAYS:`3650`,GITHUB_EVENT_NAME:`push`,HOMEBREW_NO_AUTO_UPDATE:`1`,ANDROID_HOME:`/usr/local/lib/android/sdk`,GITHUB_SERVER_URL:`https://github.com`,GECKOWEBDRIVER:`/usr/local/share/gecko_driver`,ACTIONS_ID_TOKEN_REQUEST_URL:`https://run-actions-1-azure-eastus.actions.githubusercontent.com/10//idtoken/4e7f1981-a7d2-8f5e-bac6-a99cdf3c4db6/e8553568-574b-5de8-aa4e-5c831b7b9783?api-version=2.0`,GHCUP_INSTALL_BASE_PREFIX:`/usr/local`,GITHUB_OUTPUT:`/home/runner/work/_temp/_runner_file_commands/set_output_3988287d-bb8f-43db-9bf6-1aa57225de97`,EDGEWEBDRIVER:`/usr/local/share/edge_driver`,ANDROID_NDK:`/usr/local/lib/android/sdk/ndk/27.3.13750724`,GITHUB_ARTIFACTS_LIST:`/home/runner/work/_temp/_runner_file_commands/artifacts_list_3988287d-bb8f-43db-9bf6-1aa57225de97`,SGX_AESM_ADDR:`1`,PSModulePath:`/root/.local/share/powershell/Modules:/usr/local/share/powershell/Modules:/opt/microsoft/powershell/7/Modules:/usr/share/az_15.6.1`,CHROME_BIN:`/usr/bin/google-chrome`,SELENIUM_JAR_PATH:`/usr/share/java/selenium-server.jar`,MEMORY_PRESSURE_WRITE:`c29tZSAyMDAwMDAgMjAwMDAwMAA=`,ANDROID_NDK_HOME:`/usr/local/lib/android/sdk/ndk/27.3.13750724`,GITHUB_STEP_SUMMARY:`/home/runner/work/_temp/_runner_file_commands/step_summary_3988287d-bb8f-43db-9bf6-1aa57225de97`,INIT_CWD:`/home/runner/work/vue-skuilder/vue-skuilder/packages/platform-ui`,NODE_ENV:`production`}.SK_LOG_LEVEL;if(isLevel(e))return e}return`info`}var d=(s=globalThis).__skuilderDbLog??(s.__skuilderDbLog={level:initialLevel()});function getLogLevel(){return d.level}function setLogLevel(e,t=!0){if(!isLevel(e)){console.warn(`[DB] Unknown log level '${e}'. Use one of: ${Object.keys(c).join(`, `)}`);return}if(d.level=e,u&&t)try{window.localStorage?.setItem(l,e)}catch{}}var f={debug:(e,...t)=>{c[d.level]<=c.debug&&console.debug(`[DB:DEBUG] ${e}`,...t)},info:(e,...t)=>{c[d.level]<=c.info&&console.info(`[DB:INFO] ${e}`,...t)},warn:(e,...t)=>{c[d.level]<=c.warn&&console.warn(`[DB:WARN] ${e}`,...t)},error:(e,...t)=>{c[d.level]<=c.error&&console.error(`[DB:ERROR] ${e}`,...t)},log:(e,...t)=>{c[d.level]<=c.debug&&console.log(`[DB:LOG] ${e}`,...t)},print:(e,...t)=>{console.log(e,...t)}};function mountLogLevelControl(){if(!u)return;let e=window;e.skuilder=e.skuilder||{},e.skuilder.logLevel=e=>(e!==void 0&&setLogLevel(e),getLogLevel())}mountLogLevelControl();var p=new Map;function captureSrsBacklog(e){p.set(e.courseId,e)}function noteReviewPressure(e,t){let n=p.get(e);n&&p.set(e,{...n,reviewMass:t.mass,healthyBacklog:t.healthyMass,backlogGrowthRate:t.rate,backlogMultiplier:t.multiplier})}function getSrsBacklogDebug(){return[...p.values()].sort((e,t)=>t.timestamp-e.timestamp)}function clearSrsBacklogDebug(){p.clear()}var m=new Map;function captureStrategyPressure(e){m.set(`${e.source}:${e.courseId}`,e)}function getStrategyPressureDebug(){return[...m.values()].sort((e,t)=>t.timestamp-e.timestamp)}function clearStrategyPressureDebug(){m.clear()}var h=new Map;function registerNavigator(e,t,n){h.set(e,{constructor:t,role:n}),f.debug(`[NavigatorRegistry] Registered: ${e}${n?` (${n})`:``}`)}function getRegisteredNavigator(e){return h.get(e)?.constructor}function getRegisteredNavigatorRole(e){return h.get(e)?.role}function getRegisteredFilterKind(e){return h.get(e)?.constructor?.kind}function getRegisteredNavigatorNames(){return Array.from(h.keys())}async function initializeNavigatorRegistry(){f.debug(`[NavigatorRegistry] Initializing built-in navigators...`);let[e,t]=await Promise.all([r(()=>import(`./elo-Cwa8a3Yo.js`),__vite__mapDeps([0,1,2,3,4,5])),r(()=>import(`./srs-DGscV6W4.js`),__vite__mapDeps([6,7,3,8,2]))]),n=await r(()=>import(`./prescribed-BWO17Gan.js`),__vite__mapDeps([9,2,3,5]));registerNavigator(`elo`,e.default),registerNavigator(`srs`,t.default),registerNavigator(`prescribed`,n.default);let[i,a,o,s,c]=await Promise.all([r(()=>import(`./hierarchyDefinition-DLC5DjaA.js`),__vite__mapDeps([10,2,3,4,5])),r(()=>import(`./interferenceMitigator-D78KgOxz.js`),__vite__mapDeps([11,2,3,4,5])),r(()=>import(`./relativePriority-DwPMECAp.js`),__vite__mapDeps([12,2,3])),r(()=>import(`./userTagPreference-cZCPqadC.js`),__vite__mapDeps([13,2,3])),r(()=>import(`./eloDistance-MReQeAuj.js`),__vite__mapDeps([14,15,2,3,5]))]);registerNavigator(`hierarchyDefinition`,i.default),registerNavigator(`interferenceMitigator`,a.default),registerNavigator(`relativePriority`,o.default),registerNavigator(`userTagPreference`,s.default),registerNavigator(`eloDistance`,c.default),f.debug(`[NavigatorRegistry] Initialized ${h.size} navigators: ${getRegisteredNavigatorNames().join(`, `)}`)}function getCardOrigin(e){if(e.provenance.length===0)throw Error(`Card has no provenance - cannot determine origin`);let t=e.provenance[0].reason.toLowerCase();return t.includes(`failed`)?`failed`:t.includes(`review`)?`review`:`new`}var g=function(e){return e.ELO=`elo`,e.SRS=`srs`,e.PRESCRIBED=`prescribed`,e.HIERARCHY=`hierarchyDefinition`,e.INTERFERENCE=`interferenceMitigator`,e.RELATIVE_PRIORITY=`relativePriority`,e.USER_TAG_PREFERENCE=`userTagPreference`,e.ELO_DISTANCE=`eloDistance`,e}({}),_=function(e){return e.GENERATOR=`generator`,e.FILTER=`filter`,e}({}),v={[g.ELO]:_.GENERATOR,[g.SRS]:_.GENERATOR,[g.PRESCRIBED]:_.GENERATOR,[g.HIERARCHY]:_.FILTER,[g.INTERFERENCE]:_.FILTER,[g.RELATIVE_PRIORITY]:_.FILTER,[g.USER_TAG_PREFERENCE]:_.FILTER,[g.ELO_DISTANCE]:_.FILTER};function isGenerator(e){return v[e]===_.GENERATOR?!0:getRegisteredNavigatorRole(e)===_.GENERATOR}function isFilter(e){return v[e]===_.FILTER?!0:getRegisteredNavigatorRole(e)===_.FILTER}var ContentNavigator=class{constructor(t,n,r){e(this,`user`,void 0),e(this,`course`,void 0),e(this,`strategyName`,void 0),e(this,`strategyId`,void 0),e(this,`learnable`,void 0),e(this,`staticWeight`,void 0),this.user=t,this.course=n,r&&(this.strategyName=r.name,this.strategyId=r._id,this.learnable=r.learnable,this.staticWeight=r.staticWeight)}get strategyKey(){return this.constructor.name}async getStrategyState(){if(!this.user||!this.course)throw Error(`Cannot get strategy state: navigator not properly initialized. Ensure user and course are provided to constructor.`);return this.user.getStrategyState(this.course.getCourseID(),this.strategyKey)}async putStrategyState(e){if(!this.user||!this.course)throw Error(`Cannot put strategy state: navigator not properly initialized. Ensure user and course are provided to constructor.`);return this.user.putStrategyState(this.course.getCourseID(),this.strategyKey,e)}static async create(e,t,n){let i=n.implementingClass,a=getRegisteredNavigator(i);if(a)return f.debug(`[ContentNavigator.create] Using registered navigator: ${i}`),new a(e,t,n);f.debug(`[ContentNavigator.create] Navigator not in registry, attempting dynamic import: ${i}`);let o,load=e=>r(()=>import(e),[]);for(let e of[`.ts`,`.js`,``]){try{if(o=(await load(`./generators/${i}${e}`)).default,o)break}catch(t){f.debug(`Failed to load generator ${i}${e}:`,t)}try{if(o=(await load(`./filters/${i}${e}`)).default,o)break}catch(t){f.debug(`Failed to load filter ${i}${e}:`,t)}try{if(o=(await load(`./${i}${e}`)).default,o)break}catch(t){f.debug(`Failed to load legacy ${i}${e}:`,t)}if(o)break}if(!o)throw Error(`Could not load navigator implementation for: ${i}`);return new o(e,t,n)}async getWeightedCards(e){throw Error(`${this.constructor.name} must implement getWeightedCards(). `)}setEphemeralHints(e){}},y=null;function registerPipelineForDebug(e){y=e}var b=10,x=[],S;function setDebugSessionId(e){S=e}var C=[];function drainCapturedRuns(){let e=C;return C=[],e}var w=25;function clearRunHistory(){x.length=0,C=[]}function getOrigin(e){return e.reviewID?`review`:`new`}function requiredBy(e){return e.provenance.find(e=>e.strategy===`ephemeralHint`&&e.score===1/0)?.strategyName}function captureRun(e){let t={...e,runId:`run-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,sessionId:S,timestamp:new Date};return x.unshift(t),x.length>b&&x.pop(),C.push(t),t}function parseCardElo(e){let t=e.find(e=>e.strategy===`elo`);if(!t?.reason)return;let n=t.reason.match(/card:\s*(\d+)/);return n?parseInt(n[1],10):void 0}function buildRunReport(e,t,n,r,i,a,o,s,c,l,u,d){let f=new Set(s.map(e=>e.cardId)),toReport=e=>{let t=requiredBy(e),n=e.provenance[0],r=n&&n.strategy!==`ephemeralHint`?n.strategyName||n.strategy:void 0;return{cardId:e.cardId,courseId:e.courseId,origin:getOrigin(e),...r?{generator:r}:{},...t?{required:t}:{},finalScore:e.score,cardElo:e.cardElo??parseCardElo(e.provenance),provenance:e.provenance,tags:e.tags,selected:f.has(e.cardId)}},p=[],m=[],h=[],g=0;for(let e of o)f.has(e.cardId)?p.push(toReport(e)):g<w?(m.push(toReport(e)),g++):h.push(e);let _=[...p,...m],v;if(h.length>0){let e=1/0,t=-1/0,n=1/0,r=-1/0,i=!1;for(let a of h){a.score<e&&(e=a.score),a.score>t&&(t=a.score);let o=parseCardElo(a.provenance);o!==void 0&&(i=!0,o<n&&(n=o),o>r&&(r=o))}let a=i?`, ELO ${n}–${r}`:``;v={count:h.length,scoreRange:[e,t],eloRange:i?[n,r]:void 0,note:`${h.length} additional candidate(s) scored below the top ${w} near-misses and were not retained (score ${e.toExponential(2)}–${t.toExponential(2)}${a}). Likely ELO-window pull remnants filtered out by hierarchy/lesson/priority gates.`}}let isUnselectedNew=e=>!e.reviewID&&!f.has(e.cardId),generatorScore=e=>e.provenance[0]?.score??0,y=new Set(o.map(e=>e.cardId)),hintExcluded=e=>e.score>0&&!y.has(e.cardId),b;for(let e of o)isUnselectedNew(e)&&(!b||e.score>b.score)&&(b=e);let x;for(let e of u??o)!isUnselectedNew(e)||hintExcluded(e)||(!x||generatorScore(e)>generatorScore(x))&&(x=e);let S=b||x?{...b?{nextInLine:toReport(b)}:{},...x&&x.cardId!==b?.cardId?{topGenerated:toReport(x)}:{}}:void 0,C=s.filter(e=>getOrigin(e)===`review`).length,T=s.filter(e=>getOrigin(e)===`new`).length;return{courseId:e,courseName:t,userElo:c,generatorName:n,generators:r,generatedCount:i,filters:a,hints:l,finalCount:s.length,reviewsSelected:C,newSelected:T,cards:_,unselectedNew:S,discardedTail:v,...d?{regulators:d}:{}}}function formatProvenance(e){return e.map(e=>` ${e.action===`generated`?`🎲`:e.action===`boosted`?`⬆️`:e.action===`penalized`?`⬇️`:`➡️`} ${e.strategyName}: ${e.score.toFixed(3)} - ${e.reason}`).join(`
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/elo-5Z2qkwtw.js","assets/elo-C4ZdbMIJ.js","assets/defineProperty-y9rbOPYz.js","assets/chunk-D6hFPZc3.js","assets/elo-B5qCwvSC.js","assets/tagRoles-jR-PJAgj.js","assets/srs-BD4FD2rw.js","assets/moment-DbT30ZpG.js","assets/srs-B3R2C3TU.js","assets/prescribed-Cjutx2ct.js","assets/hierarchyDefinition-BbqnGEfR.js","assets/interferenceMitigator-BtAQm-0d.js","assets/relativePriority-fx6BMJm9.js","assets/userTagPreference-B23ZX5J4.js","assets/eloDistance-DF4pmPOI.js","assets/eloDistance-CRxxdYPJ.js"])))=>i.map(i=>d[i]);
2
+ import"./chunk-D6hFPZc3.js";import{t as e}from"./defineProperty-y9rbOPYz.js";var t=`modulepreload`,assetsURL=function(e){return`/`+e},n={},r=function preload(e,r,i){let a=Promise.resolve();if(r&&r.length>0){let e=document.getElementsByTagName(`link`),o=document.querySelector(`meta[property=csp-nonce]`),s=o?.nonce||o?.getAttribute(`nonce`);function allSettled(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}a=allSettled(r.map(r=>{if(r=assetsURL(r,i),r in n)return;n[r]=!0;let a=r.endsWith(`.css`),o=a?`[rel="stylesheet"]`:``;if(i)for(let t=e.length-1;t>=0;t--){let n=e[t];if(n.href===r&&(!a||n.rel===`stylesheet`))return}else if(document.querySelector(`link[href="${r}"]${o}`))return;let c=document.createElement(`link`);if(c.rel=a?`stylesheet`:t,a||(c.as=`script`),c.crossOrigin=``,c.href=r,s&&c.setAttribute(`nonce`,s),document.head.appendChild(c),a)return new Promise((e,t)=>{c.addEventListener(`load`,e),c.addEventListener(`error`,()=>t(Error(`Unable to preload CSS for ${r}`)))})}))}function handlePreloadError(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return a.then(t=>{for(let e of t||[])e.status===`rejected`&&handlePreloadError(e.reason);return e().catch(handlePreloadError)})};Object.defineProperty;var i=`diversityRerank`,a=`DIVERSITY_RERANK`,o=`Diversity Re-rank`;function diversityRerank(e,t={}){let n=t.strength??.6,r=t.floor??.3,s=e.length;if(s<=1)return e;let c=new Map;for(let t of e)for(let e of t.tags??[])c.set(e,(c.get(e)??0)+1);let l=new Map;for(let[e,t]of c)l.set(e,Math.log(s/t));let u=[...e],d=new Map,f=[],repetitionLoad=e=>{let t=0;for(let n of e.tags??[]){let e=d.get(n);e&&(t+=(l.get(n)??0)*e)}return t};for(;u.length>0;){let e=0,t=-1/0,s=1,c=0;for(let i=0;i<u.length;i++){let a=u[i],o=repetitionLoad(a),l=o>0?Math.max(r,1/(1+n*o)):1,d=a.score*l;d>t&&(t=d,e=i,s=l,c=o)}let[l]=u.splice(e,1);if(Number.isFinite(l.score)&&s<1){let e=l.score*s;f.push({...l,score:e,provenance:[...l.provenance,{strategy:i,strategyId:a,strategyName:o,action:`penalized`,score:e,reason:`repeated tags (load ${c.toFixed(2)}) → ×${s.toFixed(2)}`}]})}else f.push(l);for(let e of l.tags??[])d.set(e,(d.get(e)??0)+1)}return f}var s,c={debug:0,info:1,warn:2,error:3,silent:4},l=`sk.logLevel`,u=typeof window<`u`;function isLevel(e){return typeof e==`string`&&e in c}function initialLevel(){if(u){try{let e=window.localStorage?.getItem(l);if(isLevel(e))return e}catch{}return`warn`}if(typeof process<`u`){let e={GITHUB_STATE:`/home/runner/work/_temp/_runner_file_commands/save_state_bae6c427-af65-4412-a1ab-475b100d7bb6`,DOTNET_NOLOGO:`1`,USER:`runner`,npm_config_user_agent:`yarn/4.12.0 npm/? node/v22.23.4 linux x64`,CI:`true`,USE_BAZEL_FALLBACK_VERSION:`silent:`,RUNNER_ENVIRONMENT:`github-hosted`,GITHUB_ENV:`/home/runner/work/_temp/_runner_file_commands/set_env_bae6c427-af65-4412-a1ab-475b100d7bb6`,PIPX_HOME:`/opt/pipx`,npm_node_execpath:`/tmp/xfs-45191981/node`,NODE_AUTH_TOKEN:`XXXXX-XXXXX-XXXXX-XXXXX`,SHLVL:`1`,HCA_CLOUD_PROVIDER:`azure`,HOME:`/home/runner`,RUNNER_TEMP:`/home/runner/work/_temp`,GITHUB_EVENT_PATH:`/home/runner/work/_temp/_github_workflow/event.json`,npm_package_json:`/home/runner/work/vue-skuilder/vue-skuilder/packages/platform-ui/package.json`,JAVA_HOME_11_X64:`/usr/lib/jvm/temurin-11-jdk-amd64`,PIPX_BIN_DIR:`/opt/pipx_bin`,GITHUB_REPOSITORY_OWNER:`patched-network`,COREPACK_ROOT:`/opt/hostedtoolcache/node/22.23.4/x64/lib/node_modules/corepack`,GRADLE_HOME:`/usr/share/gradle-9.8.2`,ANDROID_NDK_LATEST_HOME:`/usr/local/lib/android/sdk/ndk/30.0.16248370`,JAVA_HOME_21_X64:`/usr/lib/jvm/temurin-21-jdk-amd64`,GITHUB_RETENTION_DAYS:`90`,GITHUB_REPOSITORY_OWNER_ID:`200830069`,POWERSHELL_DISTRIBUTION_CHANNEL:`GitHub-Actions-Linux`,AZURE_EXTENSION_DIR:`/opt/az/azcliextensions`,GITHUB_HEAD_REF:``,SYSTEMD_EXEC_PID:`1954`,ACTIONS_ORCHESTRATION_ID:`855e2996-58b3-8b0e-9e78-f76988461839.publish.__default`,GITHUB_GRAPHQL_URL:`https://api.github.com/graphql`,JAVA_HOME_25_X64:`/usr/lib/jvm/temurin-25-jdk-amd64`,NVM_DIR:`/home/runner/.nvm`,DOTNET_SKIP_FIRST_TIME_EXPERIENCE:`1`,JAVA_HOME_17_X64:`/usr/lib/jvm/temurin-17-jdk-amd64`,ImageVersion:`20261101.186.1`,COREPACK_ENABLE_DOWNLOAD_PROMPT:`1`,LOGNAME:`runner`,RUNNER_OS:`Linux`,GITHUB_API_URL:`https://api.github.com`,GITHUB_ARTIFACTS:`/home/runner/work/_temp/_runner_file_commands/artifacts_bae6c427-af65-4412-a1ab-475b100d7bb6`,SWIFT_PATH:`/usr/share/swift/usr/bin`,CHROMEWEBDRIVER:`/usr/local/share/chromedriver-linux64`,JOURNAL_STREAM:`10:15594`,GITHUB_WORKFLOW:`Publish to NPM`,_:`/opt/hostedtoolcache/node/22.23.4/x64/bin/yarn`,MEMORY_PRESSURE_WATCH:`/sys/fs/cgroup/system.slice/hosted-compute-agent.service/memory.pressure`,GOROOT_1_24_X64:`/opt/hostedtoolcache/go/1.24.13/x64`,ACTIONS_RUNNER_ACTION_ARCHIVE_CACHE:`/opt/actionarchivecache`,GOROOT_1_25_X64:`/opt/hostedtoolcache/go/1.25.14/x64`,GITHUB_RUN_ID:`42217014802`,GITHUB_REF_TYPE:`tag`,BOOTSTRAP_HASKELL_NONINTERACTIVE:`1`,GITHUB_WORKFLOW_SHA:`bf9d3f31867061cb5b223af617361f5ad9e7ce2f`,GOROOT_1_26_X64:`/opt/hostedtoolcache/go/1.26.10/x64`,GITHUB_BASE_REF:``,ImageOS:`ubuntu26`,GITHUB_WORKFLOW_REF:`patched-network/vue-skuilder/.github/workflows/publish-npm.yml@refs/tags/v0.2.37`,ACTIONS_ID_TOKEN_REQUEST_TOKEN:`eyJhbGciOiJSUzI1NiIsImtpZCI6IjM4ODI2YjE3LTZhMzAtNWY5Yi1iMTY5LThiZWI4MjAyZjcyMyIsInR5cCI6IkpXVCIsIng1dCI6InlrTmFZNHFNX3RhNGsyVGdaT0NFWUxrY1lsQSJ9.eyJJZGVudGl0eVR5cGVDbGFpbSI6IlN5c3RlbTpTZXJ2aWNlSWRlbnRpdHkiLCJhYyI6Ilt7XCJTY29wZVwiOlwicmVmcy9oZWFkcy9yZWZzL3RhZ3MvdjAuMi4zN1wiLFwiUGVybWlzc2lvblwiOjN9LHtcIlNjb3BlXCI6XCJyZWZzL2hlYWRzL21hc3RlclwiLFwiUGVybWlzc2lvblwiOjF9XSIsImFjc2wiOiIxMCIsImF1ZCI6InZzbzphNjljOTEzYS1mYzg4LTRkOTktYjllZi1mOTYxZTc2ZGYyMjkiLCJiaWxsaW5nX293bmVyX2lkIjoiT19rZ0RPQ19oc2RRIiwiZXhwIjoxNzkzOTg5ODc3LCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3ByaW1hcnlzaWQiOiJkZGRkZGRkZC1kZGRkLWRkZGQtZGRkZC1kZGRkZGRkZGRkZGQiLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9zaWQiOiJkZGRkZGRkZC1kZGRkLWRkZGQtZGRkZC1kZGRkZGRkZGRkZGQiLCJpYXQiOjE3OTM5Njc2NzcsImlzcyI6Imh0dHBzOi8vdG9rZW4uYWN0aW9ucy5naXRodWJ1c2VyY29udGVudC5jb20iLCJqb2JfaWQiOiIyOTg5NTE3Ni0xOTU1LTVkZGQtOGM3Yi05MzkyOTE4YmQyYzUiLCJqb2Jfd29ya2Zsb3dfcmVmIjoicGF0Y2hlZC1uZXR3b3JrL3Z1ZS1za3VpbGRlci8uZ2l0aHViL3dvcmtmbG93cy9wdWJsaXNoLW5wbS55bWxAcmVmcy90YWdzL3YwLjIuMzciLCJqb2Jfd29ya2Zsb3dfc2hhIjoiYmY5ZDNmMzE4NjcwNjFjYjViMjIzYWY2MTczNjFmNWFkOWU3Y2UyZiIsIm5hbWVpZCI6ImRkZGRkZGRkLWRkZGQtZGRkZC1kZGRkLWRkZGRkZGRkZGRkZCIsIm5iZiI6MTc5Mzk2NzM3Nywib2lkY19leHRyYSI6IntcImFjdG9yXCI6XCJOaWxvQ0tcIixcImFjdG9yX2lkXCI6XCIxMDc4MDU5MFwiLFwiYmFzZV9yZWZcIjpcIlwiLFwiY2hlY2tfcnVuX2lkXCI6XCIxMjc4ODk0NDM2OTNcIixcImV2ZW50X25hbWVcIjpcInB1c2hcIixcImhlYWRfcmVmXCI6XCJcIixcImpvYl93b3JrZmxvd19yZWZcIjpcInBhdGNoZWQtbmV0d29yay92dWUtc2t1aWxkZXIvLmdpdGh1Yi93b3JrZmxvd3MvcHVibGlzaC1ucG0ueW1sQHJlZnMvdGFncy92MC4yLjM3XCIsXCJqb2Jfd29ya2Zsb3dfc2hhXCI6XCJiZjlkM2YzMTg2NzA2MWNiNWIyMjNhZjYxNzM2MWY1YWQ5ZTdjZTJmXCIsXCJyZWZcIjpcInJlZnMvdGFncy92MC4yLjM3XCIsXCJyZWZfcHJvdGVjdGVkXCI6XCJmYWxzZVwiLFwicmVmX3R5cGVcIjpcInRhZ1wiLFwicmVwb3NpdG9yeVwiOlwicGF0Y2hlZC1uZXR3b3JrL3Z1ZS1za3VpbGRlclwiLFwicmVwb3NpdG9yeV9pZFwiOlwiMTIyODg2MTczXCIsXCJyZXBvc2l0b3J5X293bmVyXCI6XCJwYXRjaGVkLW5ldHdvcmtcIixcInJlcG9zaXRvcnlfb3duZXJfaWRcIjpcIjIwMDgzMDA2OVwiLFwicmVwb3NpdG9yeV92aXNpYmlsaXR5XCI6XCJwdWJsaWNcIixcInJ1bl9hdHRlbXB0XCI6XCIxXCIsXCJydW5faWRcIjpcIjQyMjE3MDE0ODAyXCIsXCJydW5fbnVtYmVyXCI6XCIxNjZcIixcInJ1bm5lcl9lbnZpcm9ubWVudFwiOlwiZ2l0aHViLWhvc3RlZFwiLFwic2hhXCI6XCJiZjlkM2YzMTg2NzA2MWNiNWIyMjNhZjYxNzM2MWY1YWQ5ZTdjZTJmXCIsXCJ3b3JrZmxvd1wiOlwiUHVibGlzaCB0byBOUE1cIixcIndvcmtmbG93X3JlZlwiOlwicGF0Y2hlZC1uZXR3b3JrL3Z1ZS1za3VpbGRlci8uZ2l0aHViL3dvcmtmbG93cy9wdWJsaXNoLW5wbS55bWxAcmVmcy90YWdzL3YwLjIuMzdcIixcIndvcmtmbG93X3NoYVwiOlwiYmY5ZDNmMzE4NjcwNjFjYjViMjIzYWY2MTczNjFmNWFkOWU3Y2UyZlwifSIsIm9pZGNfc3ViIjoicmVwbzpwYXRjaGVkLW5ldHdvcmsvdnVlLXNrdWlsZGVyOnJlZjpyZWZzL3RhZ3MvdjAuMi4zNyIsIm9yY2hfaWQiOiI4NTVlMjk5Ni01OGIzLThiMGUtOWU3OC1mNzY5ODg0NjE4MzkucHVibGlzaC5fX2RlZmF1bHQiLCJvd25lcl9pZCI6Ik9fa2dET0NfaHNkUSIsInBsYW5faWQiOiI4NTVlMjk5Ni01OGIzLThiMGUtOWU3OC1mNzY5ODg0NjE4MzkiLCJyZXBvc2l0b3J5X2lkIjoiMTIyODg2MTczIiwicmVwb3NpdG9yeV9vd25lcl9pZCI6IjIwMDgzMDA2OSIsInJlcG9zaXRvcnlfdmlzaWJpbGl0eSI6InB1YmxpYyIsInJ1bl9pZCI6IjQyMjE3MDE0ODAyIiwicnVuX251bWJlciI6IjE2NiIsInJ1bl90eXBlIjoiZnVsbCIsInJ1bm5lcl9pZCI6IjEwMDAwMTYyOTgiLCJydW5uZXJfdHlwZSI6Imhvc3RlZCIsInNjcCI6IkFjdGlvbnMuUmVzdWx0czo4NTVlMjk5Ni01OGIzLThiMGUtOWU3OC1mNzY5ODg0NjE4Mzk6Mjk4OTUxNzYtMTk1NS01ZGRkLThjN2ItOTM5MjkxOGJkMmM1IEFjdGlvbnMuUnVubmVyOjg1NWUyOTk2LTU4YjMtOGIwZS05ZTc4LWY3Njk4ODQ2MTgzOToyOTg5NTE3Ni0xOTU1LTVkZGQtOGM3Yi05MzkyOTE4YmQyYzUgQWN0aW9ucy5VcGxvYWRBcnRpZmFjdHM6ODU1ZTI5OTYtNThiMy04YjBlLTllNzgtZjc2OTg4NDYxODM5OjI5ODk1MTc2LTE5NTUtNWRkZC04YzdiLTkzOTI5MThiZDJjNSBnZW5lcmF0ZV9pZF90b2tlbjo4NTVlMjk5Ni01OGIzLThiMGUtOWU3OC1mNzY5ODg0NjE4Mzk6Mjk4OTUxNzYtMTk1NS01ZGRkLThjN2ItOTM5MjkxOGJkMmM1IEFjdGlvbnMuR2VuZXJpY1JlYWQ6MDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwIiwic2hhIjoiYmY5ZDNmMzE4NjcwNjFjYjViMjIzYWY2MTczNjFmNWFkOWU3Y2UyZiIsInRydXN0X3RpZXIiOiIyIn0.eBCc9bbavCZxJ-LGl62aQooFvnudP38kvPbEBgiHGMKhm6xv36gAUg7TYUOLEmdJEs5xAFq_MLHKoiHbdlqWt-XfI3UpHjFGZH81eCe-4OeJRUVULoygIC_dTYfj9lwqPTP4v8IRZNoYJBXqrsPB0VzTbmyifFzsv0lmHAicaG-h94qa4PQwbYsHY-GDdSyXUyTNyvwDz2wCnG4-YvAu2GsAlgv_7WT_UWMvUKK3VSloVQCOX2ilRXFOUaky15r0OocI5LKEmMut68hjmrw8DADtnPWGFGJsjZPNWjoR1RnXYqZ-wz2cufli47S3IW4-x1hivyE1t3Jo-THiJE9Tmw`,GITHUB_ACTION_REPOSITORY:``,ENABLE_RUNNER_TRACING:`true`,PATH:`/tmp/xfs-45191981:/opt/hostedtoolcache/node/22.23.4/x64/bin:/snap/bin:/home/runner/.local/bin:/opt/pipx_bin:/home/runner/.cargo/bin:/home/runner/.config/composer/vendor/bin:/usr/local/.ghcup/bin:/home/runner/.dotnet/tools:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin`,ANT_HOME:`/usr/share/ant`,DOTNET_MULTILEVEL_LOOKUP:`0`,RUNNER_TRACKING_ID:`github_c6b9407c-829e-4812-a4e1-340f275fcc20`,INVOCATION_ID:`2c522065497e4b61ad90b221ed5bfb8a`,NPM_CONFIG_USERCONFIG:`/home/runner/work/_temp/.npmrc`,RUNNER_TOOL_CACHE:`/opt/hostedtoolcache`,npm_package_name:`@vue-skuilder/platform-ui`,GITHUB_ACTION:`__run_5`,GITHUB_RUN_NUMBER:`166`,GITHUB_TRIGGERING_ACTOR:`NiloCK`,RUNNER_ARCH:`X64`,XDG_RUNTIME_DIR:`/run/user/1001`,AGENT_TOOLSDIRECTORY:`/opt/hostedtoolcache`,LANG:`C.UTF-8`,VCPKG_INSTALLATION_ROOT:`/usr/local/share/vcpkg`,RUNNER_NAME:`GitHub Actions 1000016298`,XDG_CONFIG_HOME:`/home/runner/.config`,GITHUB_REF_NAME:`v0.2.37`,GITHUB_REPOSITORY:`patched-network/vue-skuilder`,ANDROID_NDK_ROOT:`/usr/local/lib/android/sdk/ndk/27.3.13750724`,GITHUB_ACTION_REF:``,DEBIAN_FRONTEND:`noninteractive`,PROJECT_CWD:`/home/runner/work/vue-skuilder/vue-skuilder`,SHELL:`/bin/bash`,GITHUB_REPOSITORY_ID:`122886173`,GITHUB_ACTIONS:`true`,npm_package_version:`0.2.37`,npm_lifecycle_event:`build`,GITHUB_REF_PROTECTED:`false`,GITHUB_WORKSPACE:`/home/runner/work/vue-skuilder/vue-skuilder`,ACCEPT_EULA:`Y`,GITHUB_JOB:`publish`,GITHUB_SHA:`bf9d3f31867061cb5b223af617361f5ad9e7ce2f`,GITHUB_RUN_ATTEMPT:`1`,ACTIONS_RUNNER_RETURN_JOB_RESULT_FOR_HOSTED:`1`,GITHUB_REF:`refs/tags/v0.2.37`,GITHUB_ACTOR:`NiloCK`,ANDROID_SDK_ROOT:`/usr/local/lib/android/sdk`,GITHUB_PATH:`/home/runner/work/_temp/_runner_file_commands/add_path_bae6c427-af65-4412-a1ab-475b100d7bb6`,JAVA_HOME:`/usr/lib/jvm/temurin-25-jdk-amd64`,PWD:`/home/runner/work/vue-skuilder/vue-skuilder/packages/platform-ui`,GITHUB_ACTOR_ID:`10780590`,RUNNER_WORKSPACE:`/home/runner/work/vue-skuilder`,BERRY_BIN_FOLDER:`/tmp/xfs-45191981`,npm_execpath:`/tmp/xfs-45191981/yarn`,HOMEBREW_CLEANUP_PERIODIC_FULL_DAYS:`3650`,GITHUB_EVENT_NAME:`push`,HOMEBREW_NO_AUTO_UPDATE:`1`,ANDROID_HOME:`/usr/local/lib/android/sdk`,GITHUB_SERVER_URL:`https://github.com`,GECKOWEBDRIVER:`/usr/local/share/gecko_driver`,ACTIONS_ID_TOKEN_REQUEST_URL:`https://run-actions-2-azure-eastus.actions.githubusercontent.com/170//idtoken/855e2996-58b3-8b0e-9e78-f76988461839/29895176-1955-5ddd-8c7b-9392918bd2c5?api-version=2.0`,GHCUP_INSTALL_BASE_PREFIX:`/usr/local`,GITHUB_OUTPUT:`/home/runner/work/_temp/_runner_file_commands/set_output_bae6c427-af65-4412-a1ab-475b100d7bb6`,EDGEWEBDRIVER:`/usr/local/share/edge_driver`,ANDROID_NDK:`/usr/local/lib/android/sdk/ndk/27.3.13750724`,GITHUB_ARTIFACTS_LIST:`/home/runner/work/_temp/_runner_file_commands/artifacts_list_bae6c427-af65-4412-a1ab-475b100d7bb6`,SGX_AESM_ADDR:`1`,PSModulePath:`/root/.local/share/powershell/Modules:/usr/local/share/powershell/Modules:/opt/microsoft/powershell/7/Modules:/usr/share/az_15.6.1`,CHROME_BIN:`/usr/bin/google-chrome`,SELENIUM_JAR_PATH:`/usr/share/java/selenium-server.jar`,MEMORY_PRESSURE_WRITE:`c29tZSAyMDAwMDAgMjAwMDAwMAA=`,ANDROID_NDK_HOME:`/usr/local/lib/android/sdk/ndk/27.3.13750724`,GITHUB_STEP_SUMMARY:`/home/runner/work/_temp/_runner_file_commands/step_summary_bae6c427-af65-4412-a1ab-475b100d7bb6`,INIT_CWD:`/home/runner/work/vue-skuilder/vue-skuilder/packages/platform-ui`,NODE_ENV:`production`}.SK_LOG_LEVEL;if(isLevel(e))return e}return`info`}var d=(s=globalThis).__skuilderDbLog??(s.__skuilderDbLog={level:initialLevel()});function getLogLevel(){return d.level}function setLogLevel(e,t=!0){if(!isLevel(e)){console.warn(`[DB] Unknown log level '${e}'. Use one of: ${Object.keys(c).join(`, `)}`);return}if(d.level=e,u&&t)try{window.localStorage?.setItem(l,e)}catch{}}var f={debug:(e,...t)=>{c[d.level]<=c.debug&&console.debug(`[DB:DEBUG] ${e}`,...t)},info:(e,...t)=>{c[d.level]<=c.info&&console.info(`[DB:INFO] ${e}`,...t)},warn:(e,...t)=>{c[d.level]<=c.warn&&console.warn(`[DB:WARN] ${e}`,...t)},error:(e,...t)=>{c[d.level]<=c.error&&console.error(`[DB:ERROR] ${e}`,...t)},log:(e,...t)=>{c[d.level]<=c.debug&&console.log(`[DB:LOG] ${e}`,...t)},print:(e,...t)=>{console.log(e,...t)}};function mountLogLevelControl(){if(!u)return;let e=window;e.skuilder=e.skuilder||{},e.skuilder.logLevel=e=>(e!==void 0&&setLogLevel(e),getLogLevel())}mountLogLevelControl();var p=new Map;function captureSrsBacklog(e){p.set(e.courseId,e)}function noteReviewPressure(e,t){let n=p.get(e);n&&p.set(e,{...n,reviewMass:t.mass,healthyBacklog:t.healthyMass,backlogGrowthRate:t.rate,backlogMultiplier:t.multiplier})}function getSrsBacklogDebug(){return[...p.values()].sort((e,t)=>t.timestamp-e.timestamp)}function clearSrsBacklogDebug(){p.clear()}var m=new Map;function captureStrategyPressure(e){m.set(`${e.source}:${e.courseId}`,e)}function getStrategyPressureDebug(){return[...m.values()].sort((e,t)=>t.timestamp-e.timestamp)}function clearStrategyPressureDebug(){m.clear()}var h=new Map;function registerNavigator(e,t,n){h.set(e,{constructor:t,role:n}),f.debug(`[NavigatorRegistry] Registered: ${e}${n?` (${n})`:``}`)}function getRegisteredNavigator(e){return h.get(e)?.constructor}function getRegisteredNavigatorRole(e){return h.get(e)?.role}function getRegisteredFilterKind(e){return h.get(e)?.constructor?.kind}function getRegisteredNavigatorNames(){return Array.from(h.keys())}async function initializeNavigatorRegistry(){f.debug(`[NavigatorRegistry] Initializing built-in navigators...`);let[e,t]=await Promise.all([r(()=>import(`./elo-5Z2qkwtw.js`),__vite__mapDeps([0,1,2,3,4,5])),r(()=>import(`./srs-BD4FD2rw.js`),__vite__mapDeps([6,7,3,8,2]))]),n=await r(()=>import(`./prescribed-Cjutx2ct.js`),__vite__mapDeps([9,2,3,5]));registerNavigator(`elo`,e.default),registerNavigator(`srs`,t.default),registerNavigator(`prescribed`,n.default);let[i,a,o,s,c]=await Promise.all([r(()=>import(`./hierarchyDefinition-BbqnGEfR.js`),__vite__mapDeps([10,2,3,4,5])),r(()=>import(`./interferenceMitigator-BtAQm-0d.js`),__vite__mapDeps([11,2,3,4,5])),r(()=>import(`./relativePriority-fx6BMJm9.js`),__vite__mapDeps([12,2,3])),r(()=>import(`./userTagPreference-B23ZX5J4.js`),__vite__mapDeps([13,2,3])),r(()=>import(`./eloDistance-DF4pmPOI.js`),__vite__mapDeps([14,15,2,3,5]))]);registerNavigator(`hierarchyDefinition`,i.default),registerNavigator(`interferenceMitigator`,a.default),registerNavigator(`relativePriority`,o.default),registerNavigator(`userTagPreference`,s.default),registerNavigator(`eloDistance`,c.default),f.debug(`[NavigatorRegistry] Initialized ${h.size} navigators: ${getRegisteredNavigatorNames().join(`, `)}`)}function getCardOrigin(e){if(e.provenance.length===0)throw Error(`Card has no provenance - cannot determine origin`);let t=e.provenance[0].reason.toLowerCase();return t.includes(`failed`)?`failed`:t.includes(`review`)?`review`:`new`}var g=function(e){return e.ELO=`elo`,e.SRS=`srs`,e.PRESCRIBED=`prescribed`,e.HIERARCHY=`hierarchyDefinition`,e.INTERFERENCE=`interferenceMitigator`,e.RELATIVE_PRIORITY=`relativePriority`,e.USER_TAG_PREFERENCE=`userTagPreference`,e.ELO_DISTANCE=`eloDistance`,e}({}),_=function(e){return e.GENERATOR=`generator`,e.FILTER=`filter`,e}({}),v={[g.ELO]:_.GENERATOR,[g.SRS]:_.GENERATOR,[g.PRESCRIBED]:_.GENERATOR,[g.HIERARCHY]:_.FILTER,[g.INTERFERENCE]:_.FILTER,[g.RELATIVE_PRIORITY]:_.FILTER,[g.USER_TAG_PREFERENCE]:_.FILTER,[g.ELO_DISTANCE]:_.FILTER};function isGenerator(e){return v[e]===_.GENERATOR?!0:getRegisteredNavigatorRole(e)===_.GENERATOR}function isFilter(e){return v[e]===_.FILTER?!0:getRegisteredNavigatorRole(e)===_.FILTER}var ContentNavigator=class{constructor(t,n,r){e(this,`user`,void 0),e(this,`course`,void 0),e(this,`strategyName`,void 0),e(this,`strategyId`,void 0),e(this,`learnable`,void 0),e(this,`staticWeight`,void 0),this.user=t,this.course=n,r&&(this.strategyName=r.name,this.strategyId=r._id,this.learnable=r.learnable,this.staticWeight=r.staticWeight)}get strategyKey(){return this.constructor.name}async getStrategyState(){if(!this.user||!this.course)throw Error(`Cannot get strategy state: navigator not properly initialized. Ensure user and course are provided to constructor.`);return this.user.getStrategyState(this.course.getCourseID(),this.strategyKey)}async putStrategyState(e){if(!this.user||!this.course)throw Error(`Cannot put strategy state: navigator not properly initialized. Ensure user and course are provided to constructor.`);return this.user.putStrategyState(this.course.getCourseID(),this.strategyKey,e)}static async create(e,t,n){let i=n.implementingClass,a=getRegisteredNavigator(i);if(a)return f.debug(`[ContentNavigator.create] Using registered navigator: ${i}`),new a(e,t,n);f.debug(`[ContentNavigator.create] Navigator not in registry, attempting dynamic import: ${i}`);let o,load=e=>r(()=>import(e),[]);for(let e of[`.ts`,`.js`,``]){try{if(o=(await load(`./generators/${i}${e}`)).default,o)break}catch(t){f.debug(`Failed to load generator ${i}${e}:`,t)}try{if(o=(await load(`./filters/${i}${e}`)).default,o)break}catch(t){f.debug(`Failed to load filter ${i}${e}:`,t)}try{if(o=(await load(`./${i}${e}`)).default,o)break}catch(t){f.debug(`Failed to load legacy ${i}${e}:`,t)}if(o)break}if(!o)throw Error(`Could not load navigator implementation for: ${i}`);return new o(e,t,n)}async getWeightedCards(e){throw Error(`${this.constructor.name} must implement getWeightedCards(). `)}setEphemeralHints(e){}},y=null;function registerPipelineForDebug(e){y=e}var b=10,x=[],S;function setDebugSessionId(e){S=e}var C=[];function drainCapturedRuns(){let e=C;return C=[],e}var w=25;function clearRunHistory(){x.length=0,C=[]}function getOrigin(e){return e.reviewID?`review`:`new`}function requiredBy(e){return e.provenance.find(e=>e.strategy===`ephemeralHint`&&e.score===1/0)?.strategyName}function captureRun(e){let t={...e,runId:`run-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,sessionId:S,timestamp:new Date};return x.unshift(t),x.length>b&&x.pop(),C.push(t),t}function parseCardElo(e){let t=e.find(e=>e.strategy===`elo`);if(!t?.reason)return;let n=t.reason.match(/card:\s*(\d+)/);return n?parseInt(n[1],10):void 0}function buildRunReport(e,t,n,r,i,a,o,s,c,l,u,d){let f=new Set(s.map(e=>e.cardId)),toReport=e=>{let t=requiredBy(e),n=e.provenance[0],r=n&&n.strategy!==`ephemeralHint`?n.strategyName||n.strategy:void 0;return{cardId:e.cardId,courseId:e.courseId,origin:getOrigin(e),...r?{generator:r}:{},...t?{required:t}:{},finalScore:e.score,cardElo:e.cardElo??parseCardElo(e.provenance),provenance:e.provenance,tags:e.tags,selected:f.has(e.cardId)}},p=[],m=[],h=[],g=0;for(let e of o)f.has(e.cardId)?p.push(toReport(e)):g<w?(m.push(toReport(e)),g++):h.push(e);let _=[...p,...m],v;if(h.length>0){let e=1/0,t=-1/0,n=1/0,r=-1/0,i=!1;for(let a of h){a.score<e&&(e=a.score),a.score>t&&(t=a.score);let o=parseCardElo(a.provenance);o!==void 0&&(i=!0,o<n&&(n=o),o>r&&(r=o))}let a=i?`, ELO ${n}–${r}`:``;v={count:h.length,scoreRange:[e,t],eloRange:i?[n,r]:void 0,note:`${h.length} additional candidate(s) scored below the top ${w} near-misses and were not retained (score ${e.toExponential(2)}–${t.toExponential(2)}${a}). Likely ELO-window pull remnants filtered out by hierarchy/lesson/priority gates.`}}let isUnselectedNew=e=>!e.reviewID&&!f.has(e.cardId),generatorScore=e=>e.provenance[0]?.score??0,y=new Set(o.map(e=>e.cardId)),hintExcluded=e=>e.score>0&&!y.has(e.cardId),b;for(let e of o)isUnselectedNew(e)&&(!b||e.score>b.score)&&(b=e);let x;for(let e of u??o)!isUnselectedNew(e)||hintExcluded(e)||(!x||generatorScore(e)>generatorScore(x))&&(x=e);let S=b||x?{...b?{nextInLine:toReport(b)}:{},...x&&x.cardId!==b?.cardId?{topGenerated:toReport(x)}:{}}:void 0,C=s.filter(e=>getOrigin(e)===`review`).length,T=s.filter(e=>getOrigin(e)===`new`).length;return{courseId:e,courseName:t,userElo:c,generatorName:n,generators:r,generatedCount:i,filters:a,hints:l,finalCount:s.length,reviewsSelected:C,newSelected:T,cards:_,unselectedNew:S,discardedTail:v,...d?{regulators:d}:{}}}function formatProvenance(e){return e.map(e=>` ${e.action===`generated`?`🎲`:e.action===`boosted`?`⬆️`:e.action===`penalized`?`⬇️`:`➡️`} ${e.strategyName}: ${e.score.toFixed(3)} - ${e.reason}`).join(`
3
3
  `)}function printRunSummary(e){if(console.group(`🔍 Pipeline Run: ${e.courseId} (${e.courseName||`unnamed`})`),f.print(`Run ID: ${e.runId}`),f.print(`Time: ${e.timestamp.toISOString()}`),f.print(`User ELO: ${e.userElo??`unknown`}`),f.print(`Generator: ${e.generatorName} → ${e.generatedCount} candidates`),e.generators&&e.generators.length>0){console.group(`Generator breakdown:`);for(let t of e.generators)f.print(` ${t.name}: ${t.cardCount} cards (${t.newCount} new, ${t.reviewCount} reviews, top: ${t.topScore.toFixed(2)})`);console.groupEnd()}if(e.filters.length>0){console.group(`Filter impact:`);for(let t of e.filters)f.print(` ${t.name}: ↑${t.boosted} ↓${t.penalized} =${t.passed} ✕${t.removed}`);console.groupEnd()}f.print(`Result: ${e.finalCount} cards selected (${e.newSelected} new, ${e.reviewsSelected} reviews)`),console.groupEnd()}var T=null,E=null,D=``;function escapeHtml(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`)}function escapeAttr(e){return escapeHtml(e).replace(/"/g,`&quot;`)}function copyTextToClipboard(e,t){let done=()=>{if(!t)return;let e=t.textContent??`Copy`;t.textContent=`Copied!`,t.classList.add(`copied`),setTimeout(()=>{t.textContent=e,t.classList.remove(`copied`)},1200)},fallback=()=>{let t=document.createElement(`textarea`);t.value=e,t.style.position=`fixed`,t.style.opacity=`0`,document.body.appendChild(t),t.select();try{document.execCommand(`copy`)}catch(e){f.warn(`[Pipeline Debug] Copy failed: ${e}`)}document.body.removeChild(t),done()};navigator.clipboard?.writeText?navigator.clipboard.writeText(e).then(done).catch(fallback):fallback()}function renderUI(){if(!T)return;let e=x,t=E===null?null:e[E],n=e.length===0?`<div style="padding: 1rem;">No runs captured yet.</div>`:e.map((e,t)=>`
4
4
  <div class="run-item ${t===E?`active`:``}" onclick="window.skuilder.pipeline._selectRun(${t})">
5
5
  <strong>${e.timestamp.toLocaleTimeString()}</strong><br/>
@@ -174,4 +174,4 @@ Example:
174
174
  window.skuilder.pipeline.showRun(1)
175
175
  await window.skuilder.pipeline.diagnoseCardSpace()
176
176
  `)}};function mountPipelineDebugger(){if(typeof window>`u`)return;let e=window;e.skuilder=e.skuilder||{},e.skuilder.pipeline=O}mountPipelineDebugger();export{diversityRerank as A,clearStrategyPressureDebug as C,getSrsBacklogDebug as D,clearSrsBacklogDebug as E,noteReviewPressure as O,captureStrategyPressure as S,captureSrsBacklog as T,getRegisteredNavigatorRole as _,mountPipelineDebugger as a,isGenerator as b,setDebugSessionId as c,v as d,g as f,getRegisteredNavigatorNames as g,getRegisteredNavigator as h,drainCapturedRuns as i,r as j,f as k,ContentNavigator as l,getRegisteredFilterKind as m,captureRun as n,O as o,getCardOrigin as p,clearRunHistory as r,registerPipelineForDebug as s,buildRunReport as t,_ as u,initializeNavigatorRegistry as v,getStrategyPressureDebug as w,registerNavigator as x,isFilter as y};
177
- //# sourceMappingURL=PipelineDebugger-BHaqzqZw.js.map
177
+ //# sourceMappingURL=PipelineDebugger-DhnKlMgD.js.map
@@ -1 +1 @@
1
- {"version":3,"mappings":"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","names":["snapshots"],"ignoreList":[],"sources":["../../../db/dist/_virtual/_rolldown/runtime.mjs","../../../db/dist/core/navigators/diversityRerank.mjs","../../../db/dist/util/logger.mjs","../../../db/dist/core/navigators/SrsDebugger.mjs","../../../db/dist/core/navigators/StrategyPressureDebugger.mjs","../../../db/dist/core/navigators/index.mjs","../../../db/dist/core/navigators/PipelineDebugger.mjs"],"sourcesContent":["//#region \\0rolldown/runtime.js\nvar __defProp = Object.defineProperty;\nvar __name = (target, value) => __defProp(target, \"name\", {\n\tvalue,\n\tconfigurable: true\n});\n//#endregion\nexport { __name };\n","import \"../../_virtual/_rolldown/runtime.mjs\";\n//#region src/core/navigators/diversityRerank.ts\n/** Default repetition strength. See DiversityRerankOptions.strength. */\nconst DIVERSITY_STRENGTH = .6;\n/** Default penalty floor. See DiversityRerankOptions.floor. */\nconst DIVERSITY_FLOOR = .3;\nconst STRATEGY = \"diversityRerank\";\nconst STRATEGY_ID = \"DIVERSITY_RERANK\";\nconst STRATEGY_NAME = \"Diversity Re-rank\";\n/**\n* Re-rank a scored candidate pool for answer/concept variety.\n*\n* Pure: returns a new array (diversified order, adjusted scores, appended\n* provenance) and does not mutate the input cards. Cards entering are assumed\n* to have score > 0 (the Pipeline strips zero-score cards before this stage).\n* Non-finite scores (mandatory `requireCards`, score = +Infinity) are emitted\n* untouched and still count toward repetition for later cards.\n*\n* @param cards - Post-filter, post-hint candidates.\n* @param opts - Optional strength/floor overrides (defaults are sane and\n* course-general; promote to strategy config if you ever want\n* this learnable under the orchestration layer).\n* @returns Cards in diversified order with penalised scores.\n*/\nfunction diversityRerank(cards, opts = {}) {\n\tconst strength = opts.strength ?? .6;\n\tconst floor = opts.floor ?? .3;\n\tconst n = cards.length;\n\tif (n <= 1) return cards;\n\tconst df = /* @__PURE__ */ new Map();\n\tfor (const card of cards) for (const tag of card.tags ?? []) df.set(tag, (df.get(tag) ?? 0) + 1);\n\tconst idf = /* @__PURE__ */ new Map();\n\tfor (const [tag, freq] of df) idf.set(tag, Math.log(n / freq));\n\tconst remaining = [...cards];\n\tconst emittedCount = /* @__PURE__ */ new Map();\n\tconst out = [];\n\tconst repetitionLoad = (card) => {\n\t\tlet load = 0;\n\t\tfor (const tag of card.tags ?? []) {\n\t\t\tconst seen = emittedCount.get(tag);\n\t\t\tif (seen) load += (idf.get(tag) ?? 0) * seen;\n\t\t}\n\t\treturn load;\n\t};\n\twhile (remaining.length > 0) {\n\t\tlet bestIdx = 0;\n\t\tlet bestValue = -Infinity;\n\t\tlet bestPenalty = 1;\n\t\tlet bestLoad = 0;\n\t\tfor (let i = 0; i < remaining.length; i++) {\n\t\t\tconst card = remaining[i];\n\t\t\tconst load = repetitionLoad(card);\n\t\t\tconst penalty = load > 0 ? Math.max(floor, 1 / (1 + strength * load)) : 1;\n\t\t\tconst value = card.score * penalty;\n\t\t\tif (value > bestValue) {\n\t\t\t\tbestValue = value;\n\t\t\t\tbestIdx = i;\n\t\t\t\tbestPenalty = penalty;\n\t\t\t\tbestLoad = load;\n\t\t\t}\n\t\t}\n\t\tconst [picked] = remaining.splice(bestIdx, 1);\n\t\tif (Number.isFinite(picked.score) && bestPenalty < 1) {\n\t\t\tconst newScore = picked.score * bestPenalty;\n\t\t\tout.push({\n\t\t\t\t...picked,\n\t\t\t\tscore: newScore,\n\t\t\t\tprovenance: [...picked.provenance, {\n\t\t\t\t\tstrategy: STRATEGY,\n\t\t\t\t\tstrategyId: STRATEGY_ID,\n\t\t\t\t\tstrategyName: STRATEGY_NAME,\n\t\t\t\t\taction: \"penalized\",\n\t\t\t\t\tscore: newScore,\n\t\t\t\t\treason: `repeated tags (load ${bestLoad.toFixed(2)}) → ×${bestPenalty.toFixed(2)}`\n\t\t\t\t}]\n\t\t\t});\n\t\t} else out.push(picked);\n\t\tfor (const tag of picked.tags ?? []) emittedCount.set(tag, (emittedCount.get(tag) ?? 0) + 1);\n\t}\n\treturn out;\n}\n//#endregion\nexport { DIVERSITY_FLOOR, DIVERSITY_STRENGTH, diversityRerank };\n\n//# sourceMappingURL=diversityRerank.mjs.map","import \"../_virtual/_rolldown/runtime.mjs\";\n//#region src/util/logger.ts\nconst LEVELS = {\n\tdebug: 0,\n\tinfo: 1,\n\twarn: 2,\n\terror: 3,\n\tsilent: 4\n};\nconst STORAGE_KEY = \"sk.logLevel\";\nconst isBrowser = typeof window !== \"undefined\";\nfunction isLevel(v) {\n\treturn typeof v === \"string\" && v in LEVELS;\n}\nfunction initialLevel() {\n\tif (isBrowser) {\n\t\ttry {\n\t\t\tconst stored = window.localStorage?.getItem(STORAGE_KEY);\n\t\t\tif (isLevel(stored)) return stored;\n\t\t} catch {}\n\t\treturn \"warn\";\n\t}\n\tif (typeof process !== \"undefined\") {\n\t\tconst env = process.env.SK_LOG_LEVEL;\n\t\tif (isLevel(env)) return env;\n\t}\n\treturn \"info\";\n}\nconst shared = globalThis.__skuilderDbLog ??= { level: initialLevel() };\nfunction getLogLevel() {\n\treturn shared.level;\n}\n/**\n* Set the active log level. In the browser this persists across reloads\n* unless `persist` is false.\n*/\nfunction setLogLevel(level, persist = true) {\n\tif (!isLevel(level)) {\n\t\tconsole.warn(`[DB] Unknown log level '${level}'. Use one of: ${Object.keys(LEVELS).join(\", \")}`);\n\t\treturn;\n\t}\n\tshared.level = level;\n\tif (isBrowser && persist) try {\n\t\twindow.localStorage?.setItem(STORAGE_KEY, level);\n\t} catch {}\n}\nconst logger = {\n\tdebug: (message, ...args) => {\n\t\tif (LEVELS[shared.level] <= LEVELS.debug) console.debug(`[DB:DEBUG] ${message}`, ...args);\n\t},\n\tinfo: (message, ...args) => {\n\t\tif (LEVELS[shared.level] <= LEVELS.info) console.info(`[DB:INFO] ${message}`, ...args);\n\t},\n\twarn: (message, ...args) => {\n\t\tif (LEVELS[shared.level] <= LEVELS.warn) console.warn(`[DB:WARN] ${message}`, ...args);\n\t},\n\terror: (message, ...args) => {\n\t\tif (LEVELS[shared.level] <= LEVELS.error) console.error(`[DB:ERROR] ${message}`, ...args);\n\t},\n\tlog: (message, ...args) => {\n\t\tif (LEVELS[shared.level] <= LEVELS.debug) console.log(`[DB:LOG] ${message}`, ...args);\n\t},\n\tprint: (message, ...args) => {\n\t\tconsole.log(message, ...args);\n\t}\n};\n/**\n* Mount the level control on window.skuilder.logLevel\n*\n* window.skuilder.logLevel() // current level\n* window.skuilder.logLevel('info') // set + persist\n*/\nfunction mountLogLevelControl() {\n\tif (!isBrowser) return;\n\tconst win = window;\n\twin.skuilder = win.skuilder || {};\n\twin.skuilder.logLevel = (level) => {\n\t\tif (level !== void 0) setLogLevel(level);\n\t\treturn getLogLevel();\n\t};\n}\nmountLogLevelControl();\n//#endregion\nexport { logger };\n\n//# sourceMappingURL=logger.mjs.map","import \"../../_virtual/_rolldown/runtime.mjs\";\n//#region src/core/navigators/SrsDebugger.ts\nconst snapshots = /* @__PURE__ */ new Map();\n/** Called by the SRS generator once per run. Latest snapshot per course wins. */\nfunction captureSrsBacklog(snapshot) {\n\tsnapshots.set(snapshot.courseId, snapshot);\n}\n/**\n* Called by the pipeline's regulator stage once per run: the review mass and\n* the multiplier it set. Patches the course's latest SRS snapshot.\n*/\nfunction noteReviewPressure(courseId, pressure) {\n\tconst snapshot = snapshots.get(courseId);\n\tif (!snapshot) return;\n\tsnapshots.set(courseId, {\n\t\t...snapshot,\n\t\treviewMass: pressure.mass,\n\t\thealthyBacklog: pressure.healthyMass,\n\t\tbacklogGrowthRate: pressure.rate,\n\t\tbacklogMultiplier: pressure.multiplier\n\t});\n}\n/** Current backlog snapshot for every course seen, newest-first. */\nfunction getSrsBacklogDebug() {\n\treturn [...snapshots.values()].sort((a, b) => b.timestamp - a.timestamp);\n}\n/** Drop all captured snapshots (called on session start, alongside pipeline history). */\nfunction clearSrsBacklogDebug() {\n\tsnapshots.clear();\n}\n//#endregion\nexport { captureSrsBacklog, clearSrsBacklogDebug, getSrsBacklogDebug, noteReviewPressure };\n\n//# sourceMappingURL=SrsDebugger.mjs.map","import \"../../_virtual/_rolldown/runtime.mjs\";\n//#region src/core/navigators/StrategyPressureDebugger.ts\nconst snapshots = /* @__PURE__ */ new Map();\n/** Called by a strategy once per run. Latest snapshot per (source, course) wins. */\nfunction captureStrategyPressure(snapshot) {\n\tsnapshots.set(`${snapshot.source}:${snapshot.courseId}`, snapshot);\n}\n/** Current pressure snapshot for every source seen, newest-first. */\nfunction getStrategyPressureDebug() {\n\treturn [...snapshots.values()].sort((a, b) => b.timestamp - a.timestamp);\n}\n/** Drop all captured snapshots (called on session start, alongside pipeline history). */\nfunction clearStrategyPressureDebug() {\n\tsnapshots.clear();\n}\n//#endregion\nexport { captureStrategyPressure, clearStrategyPressureDebug, getStrategyPressureDebug };\n\n//# sourceMappingURL=StrategyPressureDebugger.mjs.map","import \"../../_virtual/_rolldown/runtime.mjs\";\nimport { logger } from \"../../util/logger.mjs\";\nimport \"./diversityRerank.mjs\";\nimport \"./PipelineDebugger.mjs\";\nimport \"./SrsDebugger.mjs\";\nimport \"./StrategyPressureDebugger.mjs\";\n//#region src/core/navigators/index.ts\n/**\n* Registry mapping implementingClass names to navigator entries.\n* Populated by registerNavigator() and used by ContentNavigator.create().\n*/\nconst navigatorRegistry = /* @__PURE__ */ new Map();\n/**\n* Register a navigator implementation.\n*\n* Call this to make a navigator available for instantiation by\n* ContentNavigator.create() without relying on dynamic imports.\n*\n* Passing a `role` is optional for built-in navigators (whose roles are in\n* the hardcoded `NavigatorRoles` record), but **required** for consumer-\n* defined navigators that need to participate in pipeline assembly.\n*\n* @param implementingClass - The class name (e.g., 'elo', 'letterGatingFilter')\n* @param constructor - The navigator class constructor\n* @param role - Optional pipeline role (GENERATOR or FILTER)\n*/\nfunction registerNavigator(implementingClass, constructor, role) {\n\tnavigatorRegistry.set(implementingClass, {\n\t\tconstructor,\n\t\trole\n\t});\n\tlogger.debug(`[NavigatorRegistry] Registered: ${implementingClass}${role ? ` (${role})` : \"\"}`);\n}\n/**\n* Get a navigator constructor from the registry.\n*\n* @param implementingClass - The class name to look up\n* @returns The constructor, or undefined if not registered\n*/\nfunction getRegisteredNavigator(implementingClass) {\n\treturn navigatorRegistry.get(implementingClass)?.constructor;\n}\n/**\n* Check if a navigator is registered.\n*\n* @param implementingClass - The class name to check\n* @returns true if registered, false otherwise\n*/\nfunction hasRegisteredNavigator(implementingClass) {\n\treturn navigatorRegistry.has(implementingClass);\n}\n/**\n* Get the registered role for a navigator, if one was provided at registration.\n*\n* @param implementingClass - The class name to look up\n* @returns The role, or undefined if not registered or no role was specified\n*/\nfunction getRegisteredNavigatorRole(implementingClass) {\n\treturn navigatorRegistry.get(implementingClass)?.role;\n}\n/**\n* A registered filter's declared kind (see `CardFilter.kind`): the static\n* `kind` on its class. Undefined if unregistered or undeclared; undeclared\n* filters count as gates at run time.\n* @param implementingClass - The class name to look up\n*/\nfunction getRegisteredFilterKind(implementingClass) {\n\treturn (navigatorRegistry.get(implementingClass)?.constructor)?.kind;\n}\n/**\n* Get all registered navigator names.\n* Useful for debugging and testing.\n*/\nfunction getRegisteredNavigatorNames() {\n\treturn Array.from(navigatorRegistry.keys());\n}\n/**\n* Initialize the navigator registry with all built-in navigators.\n*\n* This function dynamically imports all standard navigator implementations\n* and registers them. Call this once at application startup to ensure\n* all navigators are available.\n*\n* In test environments, this may need to be called explicitly before\n* using ContentNavigator.create().\n*/\nasync function initializeNavigatorRegistry() {\n\tlogger.debug(\"[NavigatorRegistry] Initializing built-in navigators...\");\n\tconst [eloModule, srsModule] = await Promise.all([import(\"./generators/elo.mjs\"), import(\"./generators/srs.mjs\")]);\n\tconst prescribedModule = await import(\"./generators/prescribed.mjs\");\n\tregisterNavigator(\"elo\", eloModule.default);\n\tregisterNavigator(\"srs\", srsModule.default);\n\tregisterNavigator(\"prescribed\", prescribedModule.default);\n\tconst [hierarchyModule, interferenceModule, relativePriorityModule, userTagPreferenceModule, eloDistanceModule] = await Promise.all([\n\t\timport(\"./filters/hierarchyDefinition.mjs\"),\n\t\timport(\"./filters/interferenceMitigator.mjs\"),\n\t\timport(\"./filters/relativePriority.mjs\"),\n\t\timport(\"./filters/userTagPreference.mjs\"),\n\t\timport(\"./filters/eloDistance.mjs\")\n\t]);\n\tregisterNavigator(\"hierarchyDefinition\", hierarchyModule.default);\n\tregisterNavigator(\"interferenceMitigator\", interferenceModule.default);\n\tregisterNavigator(\"relativePriority\", relativePriorityModule.default);\n\tregisterNavigator(\"userTagPreference\", userTagPreferenceModule.default);\n\tregisterNavigator(\"eloDistance\", eloDistanceModule.default);\n\tlogger.debug(`[NavigatorRegistry] Initialized ${navigatorRegistry.size} navigators: ${getRegisteredNavigatorNames().join(\", \")}`);\n}\n/**\n* Extract card origin from provenance trail.\n*\n* The first provenance entry (from the generator) indicates whether\n* this is a new card, review, or failed card. We parse the reason\n* string to extract this information.\n*\n* @param card - Card with provenance trail\n* @returns Card origin ('new', 'review', or 'failed')\n*/\nfunction getCardOrigin(card) {\n\tif (card.provenance.length === 0) throw new Error(\"Card has no provenance - cannot determine origin\");\n\tconst reason = card.provenance[0].reason.toLowerCase();\n\tif (reason.includes(\"failed\")) return \"failed\";\n\tif (reason.includes(\"review\")) return \"review\";\n\treturn \"new\";\n}\nlet Navigators = /* @__PURE__ */ function(Navigators) {\n\tNavigators[\"ELO\"] = \"elo\";\n\tNavigators[\"SRS\"] = \"srs\";\n\tNavigators[\"PRESCRIBED\"] = \"prescribed\";\n\tNavigators[\"HIERARCHY\"] = \"hierarchyDefinition\";\n\tNavigators[\"INTERFERENCE\"] = \"interferenceMitigator\";\n\tNavigators[\"RELATIVE_PRIORITY\"] = \"relativePriority\";\n\tNavigators[\"USER_TAG_PREFERENCE\"] = \"userTagPreference\";\n\tNavigators[\"ELO_DISTANCE\"] = \"eloDistance\";\n\treturn Navigators;\n}({});\n/**\n* Role classification for navigation strategies.\n*\n* - GENERATOR: Produces candidate cards with initial scores\n* - FILTER: Transforms cards with score multipliers\n*/\nlet NavigatorRole = /* @__PURE__ */ function(NavigatorRole) {\n\tNavigatorRole[\"GENERATOR\"] = \"generator\";\n\tNavigatorRole[\"FILTER\"] = \"filter\";\n\treturn NavigatorRole;\n}({});\n/**\n* Registry mapping navigator implementations to their roles.\n*/\nconst NavigatorRoles = {\n\t[Navigators.ELO]: NavigatorRole.GENERATOR,\n\t[Navigators.SRS]: NavigatorRole.GENERATOR,\n\t[Navigators.PRESCRIBED]: NavigatorRole.GENERATOR,\n\t[Navigators.HIERARCHY]: NavigatorRole.FILTER,\n\t[Navigators.INTERFERENCE]: NavigatorRole.FILTER,\n\t[Navigators.RELATIVE_PRIORITY]: NavigatorRole.FILTER,\n\t[Navigators.USER_TAG_PREFERENCE]: NavigatorRole.FILTER,\n\t[Navigators.ELO_DISTANCE]: NavigatorRole.FILTER\n};\n/**\n* Check if a navigator implementation is a generator.\n*\n* @param impl - Navigator implementation name (e.g., 'elo', 'hierarchyDefinition')\n* @returns true if the navigator is a generator, false otherwise\n*/\nfunction isGenerator(impl) {\n\tif (NavigatorRoles[impl] === NavigatorRole.GENERATOR) return true;\n\treturn getRegisteredNavigatorRole(impl) === NavigatorRole.GENERATOR;\n}\n/**\n* Check if a navigator implementation is a filter.\n*\n* Checks the built-in NavigatorRoles enum first, then falls back to the\n* navigator registry for consumer-registered navigators.\n*\n* @param impl - Navigator implementation name (e.g., 'elo', 'letterGatingFilter')\n* @returns true if the navigator is a filter, false otherwise\n*/\nfunction isFilter(impl) {\n\tif (NavigatorRoles[impl] === NavigatorRole.FILTER) return true;\n\treturn getRegisteredNavigatorRole(impl) === NavigatorRole.FILTER;\n}\n/**\n* Abstract base class for navigation strategies.\n*\n* This class exists primarily for backward compatibility with legacy code.\n* New code should use CardGenerator or CardFilter interfaces directly.\n*\n* The class implements StudyContentSource for compatibility with SessionController.\n* Once SessionController migrates to use getWeightedCards() exclusively,\n* the legacy methods can be removed.\n*/\nvar ContentNavigator = class {\n\t/** User interface for this navigation session */\n\tuser;\n\t/** Course interface for this navigation session */\n\tcourse;\n\t/** Human-readable name for this strategy instance (from ContentNavigationStrategyData.name) */\n\tstrategyName;\n\t/** Unique document ID for this strategy instance (from ContentNavigationStrategyData._id) */\n\tstrategyId;\n\t/** Evolutionary weighting configuration */\n\tlearnable;\n\t/** Whether to bypass deviation (manual/static weighting) */\n\tstaticWeight;\n\t/**\n\t* Constructor for standard navigators.\n\t* Call this from subclass constructors to initialize common fields.\n\t*\n\t* Note: CompositeGenerator and Pipeline call super() without args, then set\n\t* user/course fields directly if needed.\n\t*/\n\tconstructor(user, course, strategyData) {\n\t\tthis.user = user;\n\t\tthis.course = course;\n\t\tif (strategyData) {\n\t\t\tthis.strategyName = strategyData.name;\n\t\t\tthis.strategyId = strategyData._id;\n\t\t\tthis.learnable = strategyData.learnable;\n\t\t\tthis.staticWeight = strategyData.staticWeight;\n\t\t}\n\t}\n\t/**\n\t* Unique key identifying this strategy for state storage.\n\t*\n\t* Defaults to the constructor name (e.g., \"UserTagPreferenceFilter\").\n\t* Override in subclasses if multiple instances of the same strategy type\n\t* need separate state storage.\n\t*/\n\tget strategyKey() {\n\t\treturn this.constructor.name;\n\t}\n\t/**\n\t* Get this strategy's persisted state for the current course.\n\t*\n\t* @returns The strategy's data payload, or null if no state exists\n\t* @throws Error if user or course is not initialized\n\t*/\n\tasync getStrategyState() {\n\t\tif (!this.user || !this.course) throw new Error(\"Cannot get strategy state: navigator not properly initialized. Ensure user and course are provided to constructor.\");\n\t\treturn this.user.getStrategyState(this.course.getCourseID(), this.strategyKey);\n\t}\n\t/**\n\t* Persist this strategy's state for the current course.\n\t*\n\t* @param data - The strategy's data payload to store\n\t* @throws Error if user or course is not initialized\n\t*/\n\tasync putStrategyState(data) {\n\t\tif (!this.user || !this.course) throw new Error(\"Cannot put strategy state: navigator not properly initialized. Ensure user and course are provided to constructor.\");\n\t\treturn this.user.putStrategyState(this.course.getCourseID(), this.strategyKey, data);\n\t}\n\t/**\n\t* Factory method to create navigator instances.\n\t*\n\t* First checks the navigator registry for a pre-registered constructor.\n\t* If not found, falls back to dynamic import (for custom navigators).\n\t*\n\t* For reliable operation in test environments, call initializeNavigatorRegistry()\n\t* before using this method.\n\t*\n\t* @param user - User interface\n\t* @param course - Course interface\n\t* @param strategyData - Strategy configuration document\n\t* @returns the runtime object used to steer a study session.\n\t*/\n\tstatic async create(user, course, strategyData) {\n\t\tconst implementingClass = strategyData.implementingClass;\n\t\tconst RegisteredImpl = getRegisteredNavigator(implementingClass);\n\t\tif (RegisteredImpl) {\n\t\t\tlogger.debug(`[ContentNavigator.create] Using registered navigator: ${implementingClass}`);\n\t\t\treturn new RegisteredImpl(user, course, strategyData);\n\t\t}\n\t\tlogger.debug(`[ContentNavigator.create] Navigator not in registry, attempting dynamic import: ${implementingClass}`);\n\t\tlet NavigatorImpl;\n\t\tconst load = (specifier) => import(\n\t\t\t/* @vite-ignore */\n\t\t\tspecifier\n);\n\t\tfor (const ext of [\n\t\t\t\".ts\",\n\t\t\t\".js\",\n\t\t\t\"\"\n\t\t]) {\n\t\t\ttry {\n\t\t\t\tNavigatorImpl = (await load(`./generators/${implementingClass}${ext}`)).default;\n\t\t\t\tif (NavigatorImpl) break;\n\t\t\t} catch (e) {\n\t\t\t\tlogger.debug(`Failed to load generator ${implementingClass}${ext}:`, e);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tNavigatorImpl = (await load(`./filters/${implementingClass}${ext}`)).default;\n\t\t\t\tif (NavigatorImpl) break;\n\t\t\t} catch (e) {\n\t\t\t\tlogger.debug(`Failed to load filter ${implementingClass}${ext}:`, e);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tNavigatorImpl = (await load(`./${implementingClass}${ext}`)).default;\n\t\t\t\tif (NavigatorImpl) break;\n\t\t\t} catch (e) {\n\t\t\t\tlogger.debug(`Failed to load legacy ${implementingClass}${ext}:`, e);\n\t\t\t}\n\t\t\tif (NavigatorImpl) break;\n\t\t}\n\t\tif (!NavigatorImpl) throw new Error(`Could not load navigator implementation for: ${implementingClass}`);\n\t\treturn new NavigatorImpl(user, course, strategyData);\n\t}\n\t/**\n\t* Get cards with suitability scores and provenance trails.\n\t*\n\t* **This is the PRIMARY API for navigation strategies.**\n\t*\n\t* Returns cards ranked by suitability score (0-1). Higher scores indicate\n\t* better candidates for presentation. Each card includes a provenance trail\n\t* documenting how strategies contributed to the final score.\n\t*\n\t* ## Implementation Required\n\t* All navigation strategies MUST override this method. The base class does\n\t* not provide a default implementation.\n\t*\n\t* ## For Generators\n\t* Override this method to generate candidates and compute scores based on\n\t* your strategy's logic (e.g., ELO proximity, review urgency). Create the\n\t* initial provenance entry with action='generated'.\n\t*\n\t* ## For Filters\n\t* Filters should implement the CardFilter interface instead and be composed\n\t* via Pipeline. Filters do not directly implement getWeightedCards().\n\t*\n\t* @param limit - Maximum cards to return\n\t* @returns Cards sorted by score descending, with provenance trails\n\t*/\n\tasync getWeightedCards(_limit) {\n\t\tthrow new Error(`${this.constructor.name} must implement getWeightedCards(). `);\n\t}\n\t/**\n\t* Set ephemeral hints for the next pipeline run.\n\t* No-op for non-Pipeline navigators. Pipeline overrides this.\n\t*/\n\tsetEphemeralHints(_hints) {}\n};\n//#endregion\nexport { ContentNavigator, NavigatorRole, NavigatorRoles, Navigators, getCardOrigin, getRegisteredFilterKind, getRegisteredNavigator, getRegisteredNavigatorNames, getRegisteredNavigatorRole, hasRegisteredNavigator, initializeNavigatorRegistry, isFilter, isGenerator, registerNavigator };\n\n//# sourceMappingURL=index.mjs.map","import \"../../_virtual/_rolldown/runtime.mjs\";\nimport { logger } from \"../../util/logger.mjs\";\nimport { NavigatorRoles, getRegisteredNavigatorNames, getRegisteredNavigatorRole, isFilter, isGenerator } from \"./index.mjs\";\n//#region src/core/navigators/PipelineDebugger.ts\n/**\n* Captured reference to the most recently created Pipeline instance.\n* Used by the debug API to run diagnostics against the live pipeline.\n*/\nlet _activePipeline = null;\n/**\n* Register a pipeline instance for diagnostic access.\n* Called by Pipeline constructor.\n*/\nfunction registerPipelineForDebug(pipeline) {\n\t_activePipeline = pipeline;\n}\n/**\n* The most recently constructed pipeline for the current session, or null if\n* none has been built yet. This is the supported, non-debug accessor for\n* out-of-band reads against the live pipeline (e.g. a commit-free\n* `forecast()`), replacing reach-ins through `window.skuilder.pipeline`.\n*/\nfunction getActivePipeline() {\n\treturn _activePipeline;\n}\n/**\n* Ring buffer for storing recent pipeline runs.\n*/\nconst MAX_RUNS = 10;\nconst runHistory = [];\n/**\n* Ambient, like `registerPipelineForDebug` — a pipeline is per content-source\n* and can outlive any one session. Set by `SessionController`.\n*/\nlet _currentSessionId;\nfunction setDebugSessionId(sessionId) {\n\t_currentSessionId = sessionId;\n}\n/**\n* Runs captured since the last drain. `SessionController` drains after each\n* plan and applies its own label — one plan can be several runs (one per\n* source), and the label is the controller's knowledge, not the pipeline's.\n*/\nlet _pendingRuns = [];\n/** Take and clear the runs captured since the previous call, in execution order. */\nfunction drainCapturedRuns() {\n\tconst drained = _pendingRuns;\n\t_pendingRuns = [];\n\treturn drained;\n}\n/**\n* Runs for `sessionId`, oldest first. Bounded by {@link MAX_RUNS} — the\n* complete record is `StudySessionDoc.runs`.\n*/\nfunction getRunsForSession(sessionId) {\n\treturn runHistory.filter((r) => r.sessionId === sessionId).reverse();\n}\n/**\n* Cap on non-selected (\"discarded\") cards retained per run report.\n*\n* Pipeline candidate pools are typically hundreds of cards (ELO window pull\n* + generators), but most are scored down by filters and never selected.\n* Their provenance trails are the dominant text-memory cost in the ring\n* buffer (each entry ~1–2 KB). Retaining only the top-N \"near misses\"\n* preserves debugging value while collapsing memory roughly an order of\n* magnitude or more.\n*/\nconst DISCARDED_KEEP_TOP = 25;\n/**\n* Programmatic clear of pipeline run history.\n*\n* Called by session-lifecycle hooks (session end, course switch, logout)\n* to release retained provenance/tag arrays once they're no longer useful\n* for in-session debugging. The interactive `clear()` debug method remains\n* for manual use.\n*/\nfunction clearRunHistory() {\n\trunHistory.length = 0;\n\t_pendingRuns = [];\n}\n/**\n* What a card is to the learner's queue: a scheduled review (it carries a\n* `reviewID`) or new. The same test as the generator counts and\n* `unselectedNew`. What put it in the queue is {@link RunReportCard.generator}\n* and {@link RunReportCard.required}.\n*/\nfunction getOrigin(card) {\n\treturn card.reviewID ? \"review\" : \"new\";\n}\n/**\n* The hint that made a card mandatory (its provenance name), if one did.\n* applyHints marks a requireCards/requireTags requirement with an infinite\n* score, and nothing else scores a card infinite.\n*/\nfunction requiredBy(card) {\n\treturn card.provenance.find((p) => p.strategy === \"ephemeralHint\" && p.score === Number.POSITIVE_INFINITY)?.strategyName;\n}\n/**\n* Capture a pipeline run for later inspection.\n*/\nfunction captureRun(report) {\n\tconst fullReport = {\n\t\t...report,\n\t\trunId: `run-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\n\t\tsessionId: _currentSessionId,\n\t\ttimestamp: /* @__PURE__ */ new Date()\n\t};\n\trunHistory.unshift(fullReport);\n\tif (runHistory.length > MAX_RUNS) runHistory.pop();\n\t_pendingRuns.push(fullReport);\n\treturn fullReport;\n}\n/**\n* Build a capture-ready report from pipeline execution data.\n*/\n/**\n* Parse card ELO from the ELO generator's provenance reason string.\n* Format: \"ELO distance XX (card: YYYY, user: ZZZZ), ...\"\n*/\nfunction parseCardElo(provenance) {\n\tconst eloEntry = provenance.find((p) => p.strategy === \"elo\");\n\tif (!eloEntry?.reason) return void 0;\n\tconst match = eloEntry.reason.match(/card:\\s*(\\d+)/);\n\treturn match ? parseInt(match[1], 10) : void 0;\n}\nfunction buildRunReport(courseId, courseName, generatorName, generators, generatedCount, filters, allCards, selectedCards, userElo, hints, scoredCards, regulators) {\n\tconst selectedIds = new Set(selectedCards.map((c) => c.cardId));\n\tconst toReport = (card) => {\n\t\tconst required = requiredBy(card);\n\t\tconst first = card.provenance[0];\n\t\tconst generator = first && first.strategy !== \"ephemeralHint\" ? first.strategyName || first.strategy : void 0;\n\t\treturn {\n\t\t\tcardId: card.cardId,\n\t\t\tcourseId: card.courseId,\n\t\t\torigin: getOrigin(card),\n\t\t\t...generator ? { generator } : {},\n\t\t\t...required ? { required } : {},\n\t\t\tfinalScore: card.score,\n\t\t\tcardElo: card.cardElo ?? parseCardElo(card.provenance),\n\t\t\tprovenance: card.provenance,\n\t\t\ttags: card.tags,\n\t\t\tselected: selectedIds.has(card.cardId)\n\t\t};\n\t};\n\tconst selectedReported = [];\n\tconst nearMissReported = [];\n\tconst discardedTailCards = [];\n\tlet nonSelectedSeen = 0;\n\tfor (const card of allCards) if (selectedIds.has(card.cardId)) selectedReported.push(toReport(card));\n\telse if (nonSelectedSeen < DISCARDED_KEEP_TOP) {\n\t\tnearMissReported.push(toReport(card));\n\t\tnonSelectedSeen++;\n\t} else discardedTailCards.push(card);\n\tconst cards = [...selectedReported, ...nearMissReported];\n\tlet discardedTail;\n\tif (discardedTailCards.length > 0) {\n\t\tlet scoreMin = Infinity;\n\t\tlet scoreMax = -Infinity;\n\t\tlet eloMin = Infinity;\n\t\tlet eloMax = -Infinity;\n\t\tlet eloSeen = false;\n\t\tfor (const c of discardedTailCards) {\n\t\t\tif (c.score < scoreMin) scoreMin = c.score;\n\t\t\tif (c.score > scoreMax) scoreMax = c.score;\n\t\t\tconst elo = parseCardElo(c.provenance);\n\t\t\tif (elo !== void 0) {\n\t\t\t\teloSeen = true;\n\t\t\t\tif (elo < eloMin) eloMin = elo;\n\t\t\t\tif (elo > eloMax) eloMax = elo;\n\t\t\t}\n\t\t}\n\t\tconst eloFragment = eloSeen ? `, ELO ${eloMin}–${eloMax}` : \"\";\n\t\tdiscardedTail = {\n\t\t\tcount: discardedTailCards.length,\n\t\t\tscoreRange: [scoreMin, scoreMax],\n\t\t\teloRange: eloSeen ? [eloMin, eloMax] : void 0,\n\t\t\tnote: `${discardedTailCards.length} additional candidate(s) scored below the top ${DISCARDED_KEEP_TOP} near-misses and were not retained (score ${scoreMin.toExponential(2)}–${scoreMax.toExponential(2)}${eloFragment}). Likely ELO-window pull remnants filtered out by hierarchy/lesson/priority gates.`\n\t\t};\n\t}\n\tconst isUnselectedNew = (c) => !c.reviewID && !selectedIds.has(c.cardId);\n\tconst generatorScore = (c) => c.provenance[0]?.score ?? 0;\n\tconst keptIds = new Set(allCards.map((c) => c.cardId));\n\tconst hintExcluded = (c) => c.score > 0 && !keptIds.has(c.cardId);\n\tlet nextInLine;\n\tfor (const c of allCards) if (isUnselectedNew(c) && (!nextInLine || c.score > nextInLine.score)) nextInLine = c;\n\tlet topGenerated;\n\tfor (const c of scoredCards ?? allCards) {\n\t\tif (!isUnselectedNew(c) || hintExcluded(c)) continue;\n\t\tif (!topGenerated || generatorScore(c) > generatorScore(topGenerated)) topGenerated = c;\n\t}\n\tconst unselectedNew = nextInLine || topGenerated ? {\n\t\t...nextInLine ? { nextInLine: toReport(nextInLine) } : {},\n\t\t...topGenerated && topGenerated.cardId !== nextInLine?.cardId ? { topGenerated: toReport(topGenerated) } : {}\n\t} : void 0;\n\tconst reviewsSelected = selectedCards.filter((c) => getOrigin(c) === \"review\").length;\n\tconst newSelected = selectedCards.filter((c) => getOrigin(c) === \"new\").length;\n\treturn {\n\t\tcourseId,\n\t\tcourseName,\n\t\tuserElo,\n\t\tgeneratorName,\n\t\tgenerators,\n\t\tgeneratedCount,\n\t\tfilters,\n\t\thints,\n\t\tfinalCount: selectedCards.length,\n\t\treviewsSelected,\n\t\tnewSelected,\n\t\tcards,\n\t\tunselectedNew,\n\t\tdiscardedTail,\n\t\t...regulators ? { regulators } : {}\n\t};\n}\n/**\n* Format a provenance trail for console display.\n*/\nfunction formatProvenance(provenance) {\n\treturn provenance.map((p) => {\n\t\treturn ` ${p.action === \"generated\" ? \"🎲\" : p.action === \"boosted\" ? \"⬆️\" : p.action === \"penalized\" ? \"⬇️\" : \"➡️\"} ${p.strategyName}: ${p.score.toFixed(3)} - ${p.reason}`;\n\t}).join(\"\\n\");\n}\n/**\n* Print summary of a single pipeline run.\n*/\nfunction printRunSummary(run) {\n\tconsole.group(`🔍 Pipeline Run: ${run.courseId} (${run.courseName || \"unnamed\"})`);\n\tlogger.print(`Run ID: ${run.runId}`);\n\tlogger.print(`Time: ${run.timestamp.toISOString()}`);\n\tlogger.print(`User ELO: ${run.userElo ?? \"unknown\"}`);\n\tlogger.print(`Generator: ${run.generatorName} → ${run.generatedCount} candidates`);\n\tif (run.generators && run.generators.length > 0) {\n\t\tconsole.group(\"Generator breakdown:\");\n\t\tfor (const g of run.generators) logger.print(` ${g.name}: ${g.cardCount} cards (${g.newCount} new, ${g.reviewCount} reviews, top: ${g.topScore.toFixed(2)})`);\n\t\tconsole.groupEnd();\n\t}\n\tif (run.filters.length > 0) {\n\t\tconsole.group(\"Filter impact:\");\n\t\tfor (const f of run.filters) logger.print(` ${f.name}: ↑${f.boosted} ↓${f.penalized} =${f.passed} ✕${f.removed}`);\n\t\tconsole.groupEnd();\n\t}\n\tlogger.print(`Result: ${run.finalCount} cards selected (${run.newSelected} new, ${run.reviewsSelected} reviews)`);\n\tconsole.groupEnd();\n}\nlet _uiContainer = null;\nlet _selectedRunIndex = null;\nlet _cardSearchQuery = \"\";\nfunction escapeHtml(s) {\n\treturn s.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n}\nfunction escapeAttr(s) {\n\treturn escapeHtml(s).replace(/\"/g, \"&quot;\");\n}\nfunction copyTextToClipboard(text, btn) {\n\tconst done = () => {\n\t\tif (!btn) return;\n\t\tconst orig = btn.textContent ?? \"Copy\";\n\t\tbtn.textContent = \"Copied!\";\n\t\tbtn.classList.add(\"copied\");\n\t\tsetTimeout(() => {\n\t\t\tbtn.textContent = orig;\n\t\t\tbtn.classList.remove(\"copied\");\n\t\t}, 1200);\n\t};\n\tconst fallback = () => {\n\t\tconst ta = document.createElement(\"textarea\");\n\t\tta.value = text;\n\t\tta.style.position = \"fixed\";\n\t\tta.style.opacity = \"0\";\n\t\tdocument.body.appendChild(ta);\n\t\tta.select();\n\t\ttry {\n\t\t\tdocument.execCommand(\"copy\");\n\t\t} catch (e) {\n\t\t\tlogger.warn(`[Pipeline Debug] Copy failed: ${e}`);\n\t\t}\n\t\tdocument.body.removeChild(ta);\n\t\tdone();\n\t};\n\tif (navigator.clipboard?.writeText) navigator.clipboard.writeText(text).then(done).catch(fallback);\n\telse fallback();\n}\nfunction renderUI() {\n\tif (!_uiContainer) return;\n\tconst runs = runHistory;\n\tconst selectedRun = _selectedRunIndex !== null ? runs[_selectedRunIndex] : null;\n\tconst styles = `\n #sk-pipeline-debugger {\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n background: #f8f9fa;\n color: #212529;\n z-index: 999999;\n display: flex;\n flex-direction: column;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n font-size: 14px;\n }\n #sk-pipeline-debugger header {\n padding: 1rem;\n background: #343a40;\n color: white;\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n #sk-pipeline-debugger .container {\n display: flex;\n flex: 1;\n overflow: hidden;\n }\n #sk-pipeline-debugger .sidebar {\n width: 300px;\n border-right: 1px solid #dee2e6;\n overflow-y: auto;\n background: white;\n }\n #sk-pipeline-debugger .main-content {\n flex: 1;\n overflow-y: auto;\n padding: 1.5rem;\n }\n #sk-pipeline-debugger .run-item {\n padding: 0.75rem 1rem;\n border-bottom: 1px solid #eee;\n cursor: pointer;\n }\n #sk-pipeline-debugger .run-item:hover { background: #f1f3f5; }\n #sk-pipeline-debugger .run-item.active { background: #e9ecef; border-left: 4px solid #007bff; }\n #sk-pipeline-debugger h2, #sk-pipeline-debugger h3 { margin-top: 0; }\n #sk-pipeline-debugger table { width: 100%; border-collapse: collapse; margin-bottom: 1rem; background: white; }\n #sk-pipeline-debugger th, #sk-pipeline-debugger td { border: 1px solid #dee2e6; padding: 0.5rem; text-align: left; }\n #sk-pipeline-debugger th { background: #f1f3f5; }\n #sk-pipeline-debugger code { background: #f1f3f5; padding: 0.1rem 0.3rem; border-radius: 3px; font-family: monospace; }\n #sk-pipeline-debugger .close-btn { background: #dc3545; color: white; border: none; padding: 0.5rem 1rem; border-radius: 4px; cursor: pointer; }\n #sk-pipeline-debugger .search-box { margin-bottom: 1rem; width: 100%; padding: 0.5rem; border: 1px solid #ced4da; border-radius: 4px; }\n #sk-pipeline-debugger .provenance { font-size: 12px; color: #666; margin-top: 0.25rem; white-space: pre-wrap; font-family: monospace; background: #f8f9fa; padding: 0.5rem; border-radius: 4px; }\n #sk-pipeline-debugger .run-label { display: inline-block; margin-top: 0.25rem; padding: 0.1rem 0.4rem; background: #fff3cd; color: #664d03; border-radius: 3px; font-family: monospace; font-size: 11px; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }\n #sk-pipeline-debugger .label-banner { display: inline-block; padding: 0.25rem 0.6rem; background: #fff3cd; color: #664d03; border-radius: 4px; font-family: monospace; font-size: 13px; margin: 0 0 0.75rem 0; }\n #sk-pipeline-debugger .copy-btn { background: #0d6efd; color: white; border: none; padding: 0.25rem 0.6rem; border-radius: 3px; cursor: pointer; font-size: 12px; margin-left: 0.5rem; }\n #sk-pipeline-debugger .copy-btn:hover { background: #0b5ed7; }\n #sk-pipeline-debugger .copy-btn.copied { background: #198754; }\n #sk-pipeline-debugger .section-head { display: flex; align-items: center; justify-content: space-between; margin-top: 1rem; }\n #sk-pipeline-debugger .section-head h3 { margin: 0; }\n `;\n\tconst runListHtml = runs.length === 0 ? \"<div style=\\\"padding: 1rem;\\\">No runs captured yet.</div>\" : runs.map((r, i) => `\n <div class=\"run-item ${i === _selectedRunIndex ? \"active\" : \"\"}\" onclick=\"window.skuilder.pipeline._selectRun(${i})\">\n <strong>${r.timestamp.toLocaleTimeString()}</strong><br/>\n <small>${r.courseName || r.courseId.slice(0, 8)}</small><br/>\n <small>${r.finalCount} cards selected</small>\n ${r.hints?._label ? `<br/><span class=\"run-label\" title=\"${escapeAttr(r.hints._label)}\">${escapeHtml(r.hints._label)}</span>` : \"\"}\n </div>\n `).join(\"\");\n\tlet detailsHtml = \"<div style=\\\"color: #6c757d; text-align: center; margin-top: 5rem;\\\">Select a run to see details</div>\";\n\tif (selectedRun) {\n\t\tconst filteredCards = selectedRun.cards.filter((c) => !_cardSearchQuery || c.cardId.toLowerCase().includes(_cardSearchQuery.toLowerCase()));\n\t\tconst labelText = selectedRun.hints?._label ?? \"(no label)\";\n\t\tdetailsHtml = `\n <h2>Run: ${selectedRun.runId}</h2>\n <div class=\"label-banner\" title=\"${escapeAttr(labelText)}\">${escapeHtml(labelText)}</div>\n <p>\n <strong>Time:</strong> ${selectedRun.timestamp.toLocaleString()} |\n <strong>Course:</strong> ${selectedRun.courseName || selectedRun.courseId} |\n <strong>User ELO:</strong> ${selectedRun.userElo ?? \"unknown\"}\n </p>\n\n <h3>Pipeline Config</h3>\n <table>\n <tr><th>Generator</th><td>${selectedRun.generatorName} (${selectedRun.generatedCount} candidates)</td></tr>\n ${(selectedRun.generators || []).map((g) => `\n <tr><td style=\"padding-left: 2rem;\">↳ ${g.name}</td><td>${g.cardCount} cards (${g.newCount} new, ${g.reviewCount} review, top: ${g.topScore.toFixed(2)})</td></tr>\n `).join(\"\")}\n </table>\n\n ${selectedRun.hints ? `\n <div class=\"section-head\">\n <h3>Ephemeral Hints</h3>\n <button class=\"copy-btn\" onclick=\"window.skuilder.pipeline._copyConfig('${selectedRun.runId}', this)\">Copy config</button>\n </div>\n <table>\n ${selectedRun.hints._label ? `<tr><th>Label</th><td>${selectedRun.hints._label}</td></tr>` : \"\"}\n ${selectedRun.hints.boostTags ? `<tr><th>Boost Tags</th><td><pre style=\"margin:0\">${JSON.stringify(selectedRun.hints.boostTags, null, 2)}</pre></td></tr>` : \"\"}\n ${selectedRun.hints.boostCards ? `<tr><th>Boost Cards</th><td><pre style=\"margin:0\">${JSON.stringify(selectedRun.hints.boostCards, null, 2)}</pre></td></tr>` : \"\"}\n ${selectedRun.hints.requireTags ? `<tr><th>Require Tags</th><td>${selectedRun.hints.requireTags.join(\", \")}</td></tr>` : \"\"}\n ${selectedRun.hints.requireCards ? `<tr><th>Require Cards</th><td>${selectedRun.hints.requireCards.join(\", \")}</td></tr>` : \"\"}\n ${selectedRun.hints.excludeTags ? `<tr><th>Exclude Tags</th><td>${selectedRun.hints.excludeTags.join(\", \")}</td></tr>` : \"\"}\n ${selectedRun.hints.excludeCards ? `<tr><th>Exclude Cards</th><td>${selectedRun.hints.excludeCards.join(\", \")}</td></tr>` : \"\"}\n </table>\n ` : \"\"}\n\n <h3>Filter Impact</h3>\n <table>\n <thead><tr><th>Filter</th><th>Boosted</th><th>Penalized</th><th>Passed</th><th>Removed</th></tr></thead>\n <tbody>\n ${selectedRun.filters.map((f) => `\n <tr><td>${f.name}</td><td>↑${f.boosted}</td><td>↓${f.penalized}</td><td>=${f.passed}</td><td>✕${f.removed}</td></tr>\n `).join(\"\")}\n </tbody>\n </table>\n\n <div class=\"section-head\">\n <h3>Cards (${selectedRun.finalCount} selected / ${selectedRun.cards.length} total)</h3>\n <button class=\"copy-btn\" onclick=\"window.skuilder.pipeline._copyResults('${selectedRun.runId}', this)\">Copy results</button>\n </div>\n <input type=\"text\" class=\"search-box\" placeholder=\"Search Card ID...\" value=\"${_cardSearchQuery}\" oninput=\"window.skuilder.pipeline._setSearch(this.value)\">\n \n <table>\n <thead><tr><th>ID</th><th>Generator</th><th>Origin</th><th>Score</th><th>Selected</th></tr></thead>\n <tbody>\n ${filteredCards.map((c) => `\n <tr>\n <td><code>${c.cardId}</code></td>\n <td>${c.generator || \"unknown\"}</td>\n <td>${c.origin}</td>\n <td>${c.finalScore.toFixed(3)}</td>\n <td>${c.selected ? \"✅\" : \"❌\"}</td>\n </tr>\n ${c.selected || _cardSearchQuery ? `\n <tr>\n <td colspan=\"5\">\n <div class=\"provenance\">${formatProvenance(c.provenance)}</div>\n </td>\n </tr>\n ` : \"\"}\n `).join(\"\")}\n </tbody>\n </table>\n `;\n\t}\n\t_uiContainer.innerHTML = `\n <style>${styles}</style>\n <header>\n <strong>Pipeline Debugger</strong>\n <button class=\"close-btn\" onclick=\"window.skuilder.pipeline.ui()\">Close</button>\n </header>\n <div class=\"container\">\n <div class=\"sidebar\">${runListHtml}</div>\n <div class=\"main-content\">${detailsHtml}</div>\n </div>\n `;\n}\n/**\n* Console API object exposed on window.skuilder.pipeline\n*/\nconst pipelineDebugAPI = {\n\tget runs() {\n\t\treturn [...runHistory];\n\t},\n\tshowRun(idOrIndex = 0) {\n\t\tif (runHistory.length === 0) {\n\t\t\tlogger.print(\"[Pipeline Debug] No runs captured yet.\");\n\t\t\treturn;\n\t\t}\n\t\tlet run;\n\t\tif (typeof idOrIndex === \"number\") {\n\t\t\trun = runHistory[idOrIndex];\n\t\t\tif (!run) {\n\t\t\t\tlogger.print(`[Pipeline Debug] No run found at index ${idOrIndex}. History length: ${runHistory.length}`);\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\trun = runHistory.find((r) => r.runId.endsWith(idOrIndex));\n\t\t\tif (!run) {\n\t\t\t\tlogger.print(`[Pipeline Debug] No run found matching ID '${idOrIndex}'.`);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tprintRunSummary(run);\n\t},\n\tshowLastRun() {\n\t\tthis.showRun(0);\n\t},\n\tshowCard(cardId) {\n\t\tfor (const run of runHistory) {\n\t\t\tconst card = run.cards.find((c) => c.cardId === cardId);\n\t\t\tif (card) {\n\t\t\t\tconsole.group(`🎴 Card: ${cardId}`);\n\t\t\t\tlogger.print(`Course: ${card.courseId}`);\n\t\t\t\tlogger.print(`Origin: ${card.origin}`);\n\t\t\t\tlogger.print(`Card ELO: ${card.cardElo ?? \"unknown\"} | User ELO: ${run.userElo ?? \"unknown\"}`);\n\t\t\t\tlogger.print(`Final score: ${card.finalScore.toFixed(3)}`);\n\t\t\t\tlogger.print(`Selected: ${card.selected ? \"Yes ✅\" : \"No ❌\"}`);\n\t\t\t\tif (card.tags && card.tags.length > 0) logger.print(`Tags (${card.tags.length}): ${card.tags.join(\", \")}`);\n\t\t\t\tlogger.print(\"Provenance:\");\n\t\t\t\tlogger.print(formatProvenance(card.provenance));\n\t\t\t\tconsole.groupEnd();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tconst runsWithTails = runHistory.filter((r) => r.discardedTail && r.discardedTail.count > 0);\n\t\tif (runsWithTails.length > 0) logger.print(`[Pipeline Debug] Card '${cardId}' not found in retained cards. ${runsWithTails.length} run(s) have discarded tails that were not retained — the card may have been a low-score candidate. See run.discardedTail for ranges.`);\n\t\telse logger.print(`[Pipeline Debug] Card '${cardId}' not found in recent runs.`);\n\t},\n\texplainReviews() {\n\t\tif (runHistory.length === 0) {\n\t\t\tlogger.print(\"[Pipeline Debug] No runs captured yet.\");\n\t\t\treturn;\n\t\t}\n\t\tconsole.group(\"📋 Review Selection Analysis\");\n\t\tfor (const run of runHistory) {\n\t\t\tconsole.group(`Run: ${run.courseId} @ ${run.timestamp.toLocaleTimeString()}`);\n\t\t\tconst allReviews = run.cards.filter((c) => c.origin === \"review\");\n\t\t\tconst selectedReviews = allReviews.filter((c) => c.selected);\n\t\t\tif (allReviews.length === 0) logger.print(\"❌ No reviews were generated. Check SRS logs for why.\");\n\t\t\telse if (selectedReviews.length === 0) {\n\t\t\t\tlogger.print(`⚠️ ${allReviews.length} reviews generated but none selected.`);\n\t\t\t\tlogger.print(\"Possible reasons:\");\n\t\t\t\tconst topNewScore = Math.max(...run.cards.filter((c) => c.origin === \"new\" && c.selected).map((c) => c.finalScore), 0);\n\t\t\t\tconst topReviewScore = Math.max(...allReviews.map((c) => c.finalScore), 0);\n\t\t\t\tif (topReviewScore < topNewScore) logger.print(` - New cards scored higher (top new: ${topNewScore.toFixed(2)}, top review: ${topReviewScore.toFixed(2)})`);\n\t\t\t\tconst topReview = allReviews.sort((a, b) => b.finalScore - a.finalScore)[0];\n\t\t\t\tif (topReview) {\n\t\t\t\t\tlogger.print(` - Top review score: ${topReview.finalScore.toFixed(3)}`);\n\t\t\t\t\tlogger.print(\" - Its provenance:\");\n\t\t\t\t\tlogger.print(formatProvenance(topReview.provenance));\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlogger.print(`✅ ${selectedReviews.length}/${allReviews.length} reviews selected.`);\n\t\t\t\tlogger.print(\"Top selected review:\");\n\t\t\t\tconst topSelected = selectedReviews.sort((a, b) => b.finalScore - a.finalScore)[0];\n\t\t\t\tlogger.print(formatProvenance(topSelected.provenance));\n\t\t\t}\n\t\t\tconsole.groupEnd();\n\t\t}\n\t\tconsole.groupEnd();\n\t},\n\tshowPrescribed(groupId) {\n\t\tif (runHistory.length === 0) {\n\t\t\tlogger.print(\"[Pipeline Debug] No runs captured yet.\");\n\t\t\treturn;\n\t\t}\n\t\tconst run = runHistory[0];\n\t\tconst prescribedCards = run.cards.filter((c) => c.provenance.some((p) => p.strategy === \"prescribed\"));\n\t\tconsole.group(`🧭 Prescribed Debug (${run.courseId})`);\n\t\tif (prescribedCards.length === 0) {\n\t\t\tlogger.print(\"No prescribed-generated cards were present in the most recent run.\");\n\t\t\tconsole.groupEnd();\n\t\t\treturn;\n\t\t}\n\t\tconst rows = prescribedCards.map((card) => {\n\t\t\tconst reason = card.provenance.find((p) => p.strategy === \"prescribed\")?.reason ?? \"\";\n\t\t\tconst parsedGroup = reason.match(/group=([^;]+)/)?.[1] ?? \"unknown\";\n\t\t\tconst mode = reason.match(/mode=([^;]+)/)?.[1] ?? \"unknown\";\n\t\t\tconst blocked = reason.match(/blocked=([^;]+)/)?.[1] ?? \"unknown\";\n\t\t\tconst blockedTargets = reason.match(/blockedTargets=([^;]+)/)?.[1] ?? \"none\";\n\t\t\tconst supportCard = reason.match(/supportCard=([^;]+)/)?.[1] ?? \"none\";\n\t\t\tconst supportTags = reason.match(/supportTags=([^;]+)/)?.[1] ?? \"none\";\n\t\t\tconst multiplier = reason.match(/multiplier=([^;]+)/)?.[1] ?? \"unknown\";\n\t\t\treturn {\n\t\t\t\tgroup: parsedGroup,\n\t\t\t\tmode,\n\t\t\t\tsupportSource: mode === \"discovered-support\" ? \"discovered\" : mode === \"support\" ? \"authored\" : \"n/a\",\n\t\t\t\tcardId: card.cardId,\n\t\t\t\tselected: card.selected ? \"yes\" : \"no\",\n\t\t\t\tfinalScore: card.finalScore.toFixed(3),\n\t\t\t\tblocked,\n\t\t\t\tblockedTargets,\n\t\t\t\tsupportCard,\n\t\t\t\tsupportTags,\n\t\t\t\tmultiplier\n\t\t\t};\n\t\t}).filter((row) => !groupId || row.group === groupId).sort((a, b) => Number(b.finalScore) - Number(a.finalScore));\n\t\tif (rows.length === 0) {\n\t\t\tlogger.print(`[Pipeline Debug] No prescribed cards matched group '${groupId}' in the most recent run.`);\n\t\t\tconsole.groupEnd();\n\t\t\treturn;\n\t\t}\n\t\tconsole.table(rows);\n\t\tconst selectedRows = rows.filter((r) => r.selected === \"yes\");\n\t\tconst blockedTargetSet = /* @__PURE__ */ new Set();\n\t\tconst supportTagSet = /* @__PURE__ */ new Set();\n\t\tconst authoredSupportSet = /* @__PURE__ */ new Set();\n\t\tconst discoveredSupportSet = /* @__PURE__ */ new Set();\n\t\tfor (const row of rows) {\n\t\t\tif (row.blockedTargets && row.blockedTargets !== \"none\") row.blockedTargets.split(\"|\").filter(Boolean).forEach((t) => blockedTargetSet.add(t));\n\t\t\tif (row.supportTags && row.supportTags !== \"none\") row.supportTags.split(\"|\").filter(Boolean).forEach((t) => supportTagSet.add(t));\n\t\t\tif (row.supportCard && row.supportCard !== \"none\") {\n\t\t\t\tif (row.supportSource === \"discovered\") discoveredSupportSet.add(row.supportCard);\n\t\t\t\telse if (row.supportSource === \"authored\") authoredSupportSet.add(row.supportCard);\n\t\t\t}\n\t\t}\n\t\tlogger.print(`Prescribed cards in run: ${rows.length}`);\n\t\tlogger.print(`Selected prescribed cards: ${selectedRows.length}`);\n\t\tlogger.print(`Blocked prescribed targets referenced: ${blockedTargetSet.size > 0 ? [...blockedTargetSet].join(\", \") : \"none\"}`);\n\t\tlogger.print(`Resolved support tags referenced: ${supportTagSet.size > 0 ? [...supportTagSet].join(\", \") : \"none\"}`);\n\t\tlogger.print(`Authored support cards emitted: ${authoredSupportSet.size > 0 ? [...authoredSupportSet].join(\", \") : \"none\"}`);\n\t\tlogger.print(`Discovered support cards emitted: ${discoveredSupportSet.size > 0 ? [...discoveredSupportSet].join(\", \") : \"none\"}`);\n\t\tconsole.groupEnd();\n\t},\n\tlistRuns() {\n\t\tif (runHistory.length === 0) {\n\t\t\tlogger.print(\"[Pipeline Debug] No runs captured yet.\");\n\t\t\treturn;\n\t\t}\n\t\tconsole.table(runHistory.map((r) => ({\n\t\t\tid: r.runId.slice(-8),\n\t\t\ttime: r.timestamp.toLocaleTimeString(),\n\t\t\tcourse: r.courseName || r.courseId.slice(0, 8),\n\t\t\tgenerated: r.generatedCount,\n\t\t\tselected: r.finalCount,\n\t\t\tnew: r.newSelected,\n\t\t\treviews: r.reviewsSelected\n\t\t})));\n\t},\n\texport() {\n\t\tconst json = JSON.stringify(runHistory, null, 2);\n\t\tlogger.print(\"[Pipeline Debug] Run history exported. Copy the returned string or use:\");\n\t\tlogger.print(\" copy(window.skuilder.pipeline.export())\");\n\t\treturn json;\n\t},\n\tclear() {\n\t\trunHistory.length = 0;\n\t\tlogger.print(\"[Pipeline Debug] Run history cleared.\");\n\t},\n\tshowRegistry() {\n\t\tconst names = getRegisteredNavigatorNames();\n\t\tif (names.length === 0) {\n\t\t\tlogger.print(\"[Pipeline Debug] Navigator registry is empty.\");\n\t\t\treturn;\n\t\t}\n\t\tconsole.group(\"📦 Navigator Registry\");\n\t\tconsole.table(names.map((name) => {\n\t\t\tconst registryRole = getRegisteredNavigatorRole(name);\n\t\t\tconst builtinRole = NavigatorRoles[name];\n\t\t\treturn {\n\t\t\t\tname,\n\t\t\t\trole: builtinRole || registryRole || \"⚠️ NONE\",\n\t\t\t\tsource: builtinRole ? \"built-in\" : registryRole ? \"consumer\" : \"unclassified\",\n\t\t\t\tisGenerator: isGenerator(name),\n\t\t\t\tisFilter: isFilter(name)\n\t\t\t};\n\t\t}));\n\t\tconsole.groupEnd();\n\t},\n\tshowStrategies() {\n\t\tthis.showRegistry();\n\t\tif (runHistory.length === 0) {\n\t\t\tlogger.print(\"[Pipeline Debug] No pipeline runs captured yet — cannot show strategy doc mapping.\");\n\t\t\treturn;\n\t\t}\n\t\tconst run = runHistory[0];\n\t\tconsole.group(\"🔌 Pipeline Strategy Mapping (last run)\");\n\t\tlogger.print(`Generator: ${run.generatorName}`);\n\t\tif (run.generators && run.generators.length > 0) for (const g of run.generators) logger.print(` 📥 ${g.name}: ${g.cardCount} cards (${g.newCount} new, ${g.reviewCount} reviews)`);\n\t\tif (run.filters.length > 0) {\n\t\t\tlogger.print(\"Filters:\");\n\t\t\tfor (const f of run.filters) logger.print(` 🔸 ${f.name}: ↑${f.boosted} ↓${f.penalized} =${f.passed} ✕${f.removed}`);\n\t\t} else logger.print(\"Filters: (none)\");\n\t\tconsole.groupEnd();\n\t},\n\tasync diagnoseCardSpace(threshold) {\n\t\tif (!_activePipeline) {\n\t\t\tlogger.print(\"[Pipeline Debug] No active pipeline. Run a session first.\");\n\t\t\treturn null;\n\t\t}\n\t\treturn _activePipeline.diagnoseCardSpace({ threshold });\n\t},\n\tasync showTagElo(tagFilter) {\n\t\tif (!_activePipeline) {\n\t\t\tlogger.print(\"[Pipeline Debug] No active pipeline. Run a session first.\");\n\t\t\treturn;\n\t\t}\n\t\tconst status = await _activePipeline.getTagEloStatus(tagFilter);\n\t\tconst entries = Object.entries(status).sort(([a], [b]) => a.localeCompare(b));\n\t\tif (entries.length === 0) {\n\t\t\tlogger.print(`[Pipeline Debug] No tag ELO data found${tagFilter ? ` for pattern: ${tagFilter}` : \"\"}.`);\n\t\t\treturn;\n\t\t}\n\t\tconsole.table(Object.fromEntries(entries.map(([tag, data]) => [tag, {\n\t\t\tscore: Math.round(data.score),\n\t\t\tcount: data.count\n\t\t}])));\n\t},\n\tui() {\n\t\tif (_uiContainer) {\n\t\t\tdocument.body.removeChild(_uiContainer);\n\t\t\t_uiContainer = null;\n\t\t\treturn;\n\t\t}\n\t\t_uiContainer = document.createElement(\"div\");\n\t\t_uiContainer.id = \"sk-pipeline-debugger\";\n\t\tdocument.body.appendChild(_uiContainer);\n\t\tif (_selectedRunIndex === null && runHistory.length > 0) _selectedRunIndex = 0;\n\t\trenderUI();\n\t},\n\t_selectRun(index) {\n\t\t_selectedRunIndex = index;\n\t\trenderUI();\n\t},\n\t_setSearch(query) {\n\t\t_cardSearchQuery = query;\n\t\trenderUI();\n\t},\n\t_copyConfig(runId, btn) {\n\t\tconst run = runHistory.find((r) => r.runId === runId);\n\t\tif (!run) return;\n\t\tconst payload = {\n\t\t\trunId: run.runId,\n\t\t\ttimestamp: run.timestamp.toISOString(),\n\t\t\tcourseId: run.courseId,\n\t\t\tcourseName: run.courseName,\n\t\t\thints: run.hints ?? null\n\t\t};\n\t\tcopyTextToClipboard(JSON.stringify(payload, null, 2), btn);\n\t},\n\t_copyResults(runId, btn) {\n\t\tconst run = runHistory.find((r) => r.runId === runId);\n\t\tif (!run) return;\n\t\tconst selected = run.cards.filter((c) => c.selected).sort((a, b) => b.finalScore - a.finalScore).map((c) => ({\n\t\t\tcardId: c.cardId,\n\t\t\tgenerator: c.generator,\n\t\t\torigin: c.origin,\n\t\t\tscore: Number(c.finalScore.toFixed(3)),\n\t\t\ttopReason: c.provenance[0]?.reason ?? \"\"\n\t\t}));\n\t\tconst payload = {\n\t\t\trunId: run.runId,\n\t\t\tlabel: run.hints?._label ?? null,\n\t\t\tfinalCount: run.finalCount,\n\t\t\tnewSelected: run.newSelected,\n\t\t\treviewsSelected: run.reviewsSelected,\n\t\t\tselected\n\t\t};\n\t\tcopyTextToClipboard(JSON.stringify(payload, null, 2), btn);\n\t},\n\thelp() {\n\t\tlogger.print(`\n🔧 Pipeline Debug API\n\nCommands:\n .ui() Toggle full-screen UI debugger\n .showLastRun() Show summary of most recent pipeline run\n .showRun(id|index) Show summary of a specific run (by index or ID suffix)\n .showCard(cardId) Show provenance trail for a specific card\n .showTagElo(pattern) Show user's tag ELO data (async). E.g. 'gpc:expose:*'\n .explainReviews() Analyze why reviews were/weren't selected\n .diagnoseCardSpace() Scan full card space through filters (async)\n .showRegistry() Show navigator registry (classes + roles)\n .showStrategies() Show registry + strategy mapping from last run\n .showPrescribed(id?) Show prescribed-generated cards and blocked/support details from last run\n .listRuns() List all captured runs in table format\n .export() Export run history as JSON for bug reports\n .clear() Clear run history\n .runs Access raw run history array\n .help() Show this help message\n\nExample:\n window.skuilder.pipeline.ui()\n window.skuilder.pipeline.showLastRun()\n window.skuilder.pipeline.showRun(1)\n await window.skuilder.pipeline.diagnoseCardSpace()\n`);\n\t}\n};\n/**\n* Mount the debug API on window.skuilder.pipeline\n*/\nfunction mountPipelineDebugger() {\n\tif (typeof window === \"undefined\") return;\n\tconst win = window;\n\twin.skuilder = win.skuilder || {};\n\twin.skuilder.pipeline = pipelineDebugAPI;\n}\nmountPipelineDebugger();\n//#endregion\nexport { buildRunReport, captureRun, clearRunHistory, drainCapturedRuns, getActivePipeline, getRunsForSession, mountPipelineDebugger, pipelineDebugAPI, registerPipelineForDebug, setDebugSessionId };\n\n//# sourceMappingURL=PipelineDebugger.mjs.map"],"file":"PipelineDebugger-BHaqzqZw.js"}
1
+ {"version":3,"mappings":"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","names":["snapshots"],"ignoreList":[],"sources":["../../../db/dist/_virtual/_rolldown/runtime.mjs","../../../db/dist/core/navigators/diversityRerank.mjs","../../../db/dist/util/logger.mjs","../../../db/dist/core/navigators/SrsDebugger.mjs","../../../db/dist/core/navigators/StrategyPressureDebugger.mjs","../../../db/dist/core/navigators/index.mjs","../../../db/dist/core/navigators/PipelineDebugger.mjs"],"sourcesContent":["//#region \\0rolldown/runtime.js\nvar __defProp = Object.defineProperty;\nvar __name = (target, value) => __defProp(target, \"name\", {\n\tvalue,\n\tconfigurable: true\n});\n//#endregion\nexport { __name };\n","import \"../../_virtual/_rolldown/runtime.mjs\";\n//#region src/core/navigators/diversityRerank.ts\n/** Default repetition strength. See DiversityRerankOptions.strength. */\nconst DIVERSITY_STRENGTH = .6;\n/** Default penalty floor. See DiversityRerankOptions.floor. */\nconst DIVERSITY_FLOOR = .3;\nconst STRATEGY = \"diversityRerank\";\nconst STRATEGY_ID = \"DIVERSITY_RERANK\";\nconst STRATEGY_NAME = \"Diversity Re-rank\";\n/**\n* Re-rank a scored candidate pool for answer/concept variety.\n*\n* Pure: returns a new array (diversified order, adjusted scores, appended\n* provenance) and does not mutate the input cards. Cards entering are assumed\n* to have score > 0 (the Pipeline strips zero-score cards before this stage).\n* Non-finite scores (mandatory `requireCards`, score = +Infinity) are emitted\n* untouched and still count toward repetition for later cards.\n*\n* @param cards - Post-filter, post-hint candidates.\n* @param opts - Optional strength/floor overrides (defaults are sane and\n* course-general; promote to strategy config if you ever want\n* this learnable under the orchestration layer).\n* @returns Cards in diversified order with penalised scores.\n*/\nfunction diversityRerank(cards, opts = {}) {\n\tconst strength = opts.strength ?? .6;\n\tconst floor = opts.floor ?? .3;\n\tconst n = cards.length;\n\tif (n <= 1) return cards;\n\tconst df = /* @__PURE__ */ new Map();\n\tfor (const card of cards) for (const tag of card.tags ?? []) df.set(tag, (df.get(tag) ?? 0) + 1);\n\tconst idf = /* @__PURE__ */ new Map();\n\tfor (const [tag, freq] of df) idf.set(tag, Math.log(n / freq));\n\tconst remaining = [...cards];\n\tconst emittedCount = /* @__PURE__ */ new Map();\n\tconst out = [];\n\tconst repetitionLoad = (card) => {\n\t\tlet load = 0;\n\t\tfor (const tag of card.tags ?? []) {\n\t\t\tconst seen = emittedCount.get(tag);\n\t\t\tif (seen) load += (idf.get(tag) ?? 0) * seen;\n\t\t}\n\t\treturn load;\n\t};\n\twhile (remaining.length > 0) {\n\t\tlet bestIdx = 0;\n\t\tlet bestValue = -Infinity;\n\t\tlet bestPenalty = 1;\n\t\tlet bestLoad = 0;\n\t\tfor (let i = 0; i < remaining.length; i++) {\n\t\t\tconst card = remaining[i];\n\t\t\tconst load = repetitionLoad(card);\n\t\t\tconst penalty = load > 0 ? Math.max(floor, 1 / (1 + strength * load)) : 1;\n\t\t\tconst value = card.score * penalty;\n\t\t\tif (value > bestValue) {\n\t\t\t\tbestValue = value;\n\t\t\t\tbestIdx = i;\n\t\t\t\tbestPenalty = penalty;\n\t\t\t\tbestLoad = load;\n\t\t\t}\n\t\t}\n\t\tconst [picked] = remaining.splice(bestIdx, 1);\n\t\tif (Number.isFinite(picked.score) && bestPenalty < 1) {\n\t\t\tconst newScore = picked.score * bestPenalty;\n\t\t\tout.push({\n\t\t\t\t...picked,\n\t\t\t\tscore: newScore,\n\t\t\t\tprovenance: [...picked.provenance, {\n\t\t\t\t\tstrategy: STRATEGY,\n\t\t\t\t\tstrategyId: STRATEGY_ID,\n\t\t\t\t\tstrategyName: STRATEGY_NAME,\n\t\t\t\t\taction: \"penalized\",\n\t\t\t\t\tscore: newScore,\n\t\t\t\t\treason: `repeated tags (load ${bestLoad.toFixed(2)}) → ×${bestPenalty.toFixed(2)}`\n\t\t\t\t}]\n\t\t\t});\n\t\t} else out.push(picked);\n\t\tfor (const tag of picked.tags ?? []) emittedCount.set(tag, (emittedCount.get(tag) ?? 0) + 1);\n\t}\n\treturn out;\n}\n//#endregion\nexport { DIVERSITY_FLOOR, DIVERSITY_STRENGTH, diversityRerank };\n\n//# sourceMappingURL=diversityRerank.mjs.map","import \"../_virtual/_rolldown/runtime.mjs\";\n//#region src/util/logger.ts\nconst LEVELS = {\n\tdebug: 0,\n\tinfo: 1,\n\twarn: 2,\n\terror: 3,\n\tsilent: 4\n};\nconst STORAGE_KEY = \"sk.logLevel\";\nconst isBrowser = typeof window !== \"undefined\";\nfunction isLevel(v) {\n\treturn typeof v === \"string\" && v in LEVELS;\n}\nfunction initialLevel() {\n\tif (isBrowser) {\n\t\ttry {\n\t\t\tconst stored = window.localStorage?.getItem(STORAGE_KEY);\n\t\t\tif (isLevel(stored)) return stored;\n\t\t} catch {}\n\t\treturn \"warn\";\n\t}\n\tif (typeof process !== \"undefined\") {\n\t\tconst env = process.env.SK_LOG_LEVEL;\n\t\tif (isLevel(env)) return env;\n\t}\n\treturn \"info\";\n}\nconst shared = globalThis.__skuilderDbLog ??= { level: initialLevel() };\nfunction getLogLevel() {\n\treturn shared.level;\n}\n/**\n* Set the active log level. In the browser this persists across reloads\n* unless `persist` is false.\n*/\nfunction setLogLevel(level, persist = true) {\n\tif (!isLevel(level)) {\n\t\tconsole.warn(`[DB] Unknown log level '${level}'. Use one of: ${Object.keys(LEVELS).join(\", \")}`);\n\t\treturn;\n\t}\n\tshared.level = level;\n\tif (isBrowser && persist) try {\n\t\twindow.localStorage?.setItem(STORAGE_KEY, level);\n\t} catch {}\n}\nconst logger = {\n\tdebug: (message, ...args) => {\n\t\tif (LEVELS[shared.level] <= LEVELS.debug) console.debug(`[DB:DEBUG] ${message}`, ...args);\n\t},\n\tinfo: (message, ...args) => {\n\t\tif (LEVELS[shared.level] <= LEVELS.info) console.info(`[DB:INFO] ${message}`, ...args);\n\t},\n\twarn: (message, ...args) => {\n\t\tif (LEVELS[shared.level] <= LEVELS.warn) console.warn(`[DB:WARN] ${message}`, ...args);\n\t},\n\terror: (message, ...args) => {\n\t\tif (LEVELS[shared.level] <= LEVELS.error) console.error(`[DB:ERROR] ${message}`, ...args);\n\t},\n\tlog: (message, ...args) => {\n\t\tif (LEVELS[shared.level] <= LEVELS.debug) console.log(`[DB:LOG] ${message}`, ...args);\n\t},\n\tprint: (message, ...args) => {\n\t\tconsole.log(message, ...args);\n\t}\n};\n/**\n* Mount the level control on window.skuilder.logLevel\n*\n* window.skuilder.logLevel() // current level\n* window.skuilder.logLevel('info') // set + persist\n*/\nfunction mountLogLevelControl() {\n\tif (!isBrowser) return;\n\tconst win = window;\n\twin.skuilder = win.skuilder || {};\n\twin.skuilder.logLevel = (level) => {\n\t\tif (level !== void 0) setLogLevel(level);\n\t\treturn getLogLevel();\n\t};\n}\nmountLogLevelControl();\n//#endregion\nexport { logger };\n\n//# sourceMappingURL=logger.mjs.map","import \"../../_virtual/_rolldown/runtime.mjs\";\n//#region src/core/navigators/SrsDebugger.ts\nconst snapshots = /* @__PURE__ */ new Map();\n/** Called by the SRS generator once per run. Latest snapshot per course wins. */\nfunction captureSrsBacklog(snapshot) {\n\tsnapshots.set(snapshot.courseId, snapshot);\n}\n/**\n* Called by the pipeline's regulator stage once per run: the review mass and\n* the multiplier it set. Patches the course's latest SRS snapshot.\n*/\nfunction noteReviewPressure(courseId, pressure) {\n\tconst snapshot = snapshots.get(courseId);\n\tif (!snapshot) return;\n\tsnapshots.set(courseId, {\n\t\t...snapshot,\n\t\treviewMass: pressure.mass,\n\t\thealthyBacklog: pressure.healthyMass,\n\t\tbacklogGrowthRate: pressure.rate,\n\t\tbacklogMultiplier: pressure.multiplier\n\t});\n}\n/** Current backlog snapshot for every course seen, newest-first. */\nfunction getSrsBacklogDebug() {\n\treturn [...snapshots.values()].sort((a, b) => b.timestamp - a.timestamp);\n}\n/** Drop all captured snapshots (called on session start, alongside pipeline history). */\nfunction clearSrsBacklogDebug() {\n\tsnapshots.clear();\n}\n//#endregion\nexport { captureSrsBacklog, clearSrsBacklogDebug, getSrsBacklogDebug, noteReviewPressure };\n\n//# sourceMappingURL=SrsDebugger.mjs.map","import \"../../_virtual/_rolldown/runtime.mjs\";\n//#region src/core/navigators/StrategyPressureDebugger.ts\nconst snapshots = /* @__PURE__ */ new Map();\n/** Called by a strategy once per run. Latest snapshot per (source, course) wins. */\nfunction captureStrategyPressure(snapshot) {\n\tsnapshots.set(`${snapshot.source}:${snapshot.courseId}`, snapshot);\n}\n/** Current pressure snapshot for every source seen, newest-first. */\nfunction getStrategyPressureDebug() {\n\treturn [...snapshots.values()].sort((a, b) => b.timestamp - a.timestamp);\n}\n/** Drop all captured snapshots (called on session start, alongside pipeline history). */\nfunction clearStrategyPressureDebug() {\n\tsnapshots.clear();\n}\n//#endregion\nexport { captureStrategyPressure, clearStrategyPressureDebug, getStrategyPressureDebug };\n\n//# sourceMappingURL=StrategyPressureDebugger.mjs.map","import \"../../_virtual/_rolldown/runtime.mjs\";\nimport { logger } from \"../../util/logger.mjs\";\nimport \"./diversityRerank.mjs\";\nimport \"./PipelineDebugger.mjs\";\nimport \"./SrsDebugger.mjs\";\nimport \"./StrategyPressureDebugger.mjs\";\n//#region src/core/navigators/index.ts\n/**\n* Registry mapping implementingClass names to navigator entries.\n* Populated by registerNavigator() and used by ContentNavigator.create().\n*/\nconst navigatorRegistry = /* @__PURE__ */ new Map();\n/**\n* Register a navigator implementation.\n*\n* Call this to make a navigator available for instantiation by\n* ContentNavigator.create() without relying on dynamic imports.\n*\n* Passing a `role` is optional for built-in navigators (whose roles are in\n* the hardcoded `NavigatorRoles` record), but **required** for consumer-\n* defined navigators that need to participate in pipeline assembly.\n*\n* @param implementingClass - The class name (e.g., 'elo', 'letterGatingFilter')\n* @param constructor - The navigator class constructor\n* @param role - Optional pipeline role (GENERATOR or FILTER)\n*/\nfunction registerNavigator(implementingClass, constructor, role) {\n\tnavigatorRegistry.set(implementingClass, {\n\t\tconstructor,\n\t\trole\n\t});\n\tlogger.debug(`[NavigatorRegistry] Registered: ${implementingClass}${role ? ` (${role})` : \"\"}`);\n}\n/**\n* Get a navigator constructor from the registry.\n*\n* @param implementingClass - The class name to look up\n* @returns The constructor, or undefined if not registered\n*/\nfunction getRegisteredNavigator(implementingClass) {\n\treturn navigatorRegistry.get(implementingClass)?.constructor;\n}\n/**\n* Check if a navigator is registered.\n*\n* @param implementingClass - The class name to check\n* @returns true if registered, false otherwise\n*/\nfunction hasRegisteredNavigator(implementingClass) {\n\treturn navigatorRegistry.has(implementingClass);\n}\n/**\n* Get the registered role for a navigator, if one was provided at registration.\n*\n* @param implementingClass - The class name to look up\n* @returns The role, or undefined if not registered or no role was specified\n*/\nfunction getRegisteredNavigatorRole(implementingClass) {\n\treturn navigatorRegistry.get(implementingClass)?.role;\n}\n/**\n* A registered filter's declared kind (see `CardFilter.kind`): the static\n* `kind` on its class. Undefined if unregistered or undeclared; undeclared\n* filters count as gates at run time.\n* @param implementingClass - The class name to look up\n*/\nfunction getRegisteredFilterKind(implementingClass) {\n\treturn (navigatorRegistry.get(implementingClass)?.constructor)?.kind;\n}\n/**\n* Get all registered navigator names.\n* Useful for debugging and testing.\n*/\nfunction getRegisteredNavigatorNames() {\n\treturn Array.from(navigatorRegistry.keys());\n}\n/**\n* Initialize the navigator registry with all built-in navigators.\n*\n* This function dynamically imports all standard navigator implementations\n* and registers them. Call this once at application startup to ensure\n* all navigators are available.\n*\n* In test environments, this may need to be called explicitly before\n* using ContentNavigator.create().\n*/\nasync function initializeNavigatorRegistry() {\n\tlogger.debug(\"[NavigatorRegistry] Initializing built-in navigators...\");\n\tconst [eloModule, srsModule] = await Promise.all([import(\"./generators/elo.mjs\"), import(\"./generators/srs.mjs\")]);\n\tconst prescribedModule = await import(\"./generators/prescribed.mjs\");\n\tregisterNavigator(\"elo\", eloModule.default);\n\tregisterNavigator(\"srs\", srsModule.default);\n\tregisterNavigator(\"prescribed\", prescribedModule.default);\n\tconst [hierarchyModule, interferenceModule, relativePriorityModule, userTagPreferenceModule, eloDistanceModule] = await Promise.all([\n\t\timport(\"./filters/hierarchyDefinition.mjs\"),\n\t\timport(\"./filters/interferenceMitigator.mjs\"),\n\t\timport(\"./filters/relativePriority.mjs\"),\n\t\timport(\"./filters/userTagPreference.mjs\"),\n\t\timport(\"./filters/eloDistance.mjs\")\n\t]);\n\tregisterNavigator(\"hierarchyDefinition\", hierarchyModule.default);\n\tregisterNavigator(\"interferenceMitigator\", interferenceModule.default);\n\tregisterNavigator(\"relativePriority\", relativePriorityModule.default);\n\tregisterNavigator(\"userTagPreference\", userTagPreferenceModule.default);\n\tregisterNavigator(\"eloDistance\", eloDistanceModule.default);\n\tlogger.debug(`[NavigatorRegistry] Initialized ${navigatorRegistry.size} navigators: ${getRegisteredNavigatorNames().join(\", \")}`);\n}\n/**\n* Extract card origin from provenance trail.\n*\n* The first provenance entry (from the generator) indicates whether\n* this is a new card, review, or failed card. We parse the reason\n* string to extract this information.\n*\n* @param card - Card with provenance trail\n* @returns Card origin ('new', 'review', or 'failed')\n*/\nfunction getCardOrigin(card) {\n\tif (card.provenance.length === 0) throw new Error(\"Card has no provenance - cannot determine origin\");\n\tconst reason = card.provenance[0].reason.toLowerCase();\n\tif (reason.includes(\"failed\")) return \"failed\";\n\tif (reason.includes(\"review\")) return \"review\";\n\treturn \"new\";\n}\nlet Navigators = /* @__PURE__ */ function(Navigators) {\n\tNavigators[\"ELO\"] = \"elo\";\n\tNavigators[\"SRS\"] = \"srs\";\n\tNavigators[\"PRESCRIBED\"] = \"prescribed\";\n\tNavigators[\"HIERARCHY\"] = \"hierarchyDefinition\";\n\tNavigators[\"INTERFERENCE\"] = \"interferenceMitigator\";\n\tNavigators[\"RELATIVE_PRIORITY\"] = \"relativePriority\";\n\tNavigators[\"USER_TAG_PREFERENCE\"] = \"userTagPreference\";\n\tNavigators[\"ELO_DISTANCE\"] = \"eloDistance\";\n\treturn Navigators;\n}({});\n/**\n* Role classification for navigation strategies.\n*\n* - GENERATOR: Produces candidate cards with initial scores\n* - FILTER: Transforms cards with score multipliers\n*/\nlet NavigatorRole = /* @__PURE__ */ function(NavigatorRole) {\n\tNavigatorRole[\"GENERATOR\"] = \"generator\";\n\tNavigatorRole[\"FILTER\"] = \"filter\";\n\treturn NavigatorRole;\n}({});\n/**\n* Registry mapping navigator implementations to their roles.\n*/\nconst NavigatorRoles = {\n\t[Navigators.ELO]: NavigatorRole.GENERATOR,\n\t[Navigators.SRS]: NavigatorRole.GENERATOR,\n\t[Navigators.PRESCRIBED]: NavigatorRole.GENERATOR,\n\t[Navigators.HIERARCHY]: NavigatorRole.FILTER,\n\t[Navigators.INTERFERENCE]: NavigatorRole.FILTER,\n\t[Navigators.RELATIVE_PRIORITY]: NavigatorRole.FILTER,\n\t[Navigators.USER_TAG_PREFERENCE]: NavigatorRole.FILTER,\n\t[Navigators.ELO_DISTANCE]: NavigatorRole.FILTER\n};\n/**\n* Check if a navigator implementation is a generator.\n*\n* @param impl - Navigator implementation name (e.g., 'elo', 'hierarchyDefinition')\n* @returns true if the navigator is a generator, false otherwise\n*/\nfunction isGenerator(impl) {\n\tif (NavigatorRoles[impl] === NavigatorRole.GENERATOR) return true;\n\treturn getRegisteredNavigatorRole(impl) === NavigatorRole.GENERATOR;\n}\n/**\n* Check if a navigator implementation is a filter.\n*\n* Checks the built-in NavigatorRoles enum first, then falls back to the\n* navigator registry for consumer-registered navigators.\n*\n* @param impl - Navigator implementation name (e.g., 'elo', 'letterGatingFilter')\n* @returns true if the navigator is a filter, false otherwise\n*/\nfunction isFilter(impl) {\n\tif (NavigatorRoles[impl] === NavigatorRole.FILTER) return true;\n\treturn getRegisteredNavigatorRole(impl) === NavigatorRole.FILTER;\n}\n/**\n* Abstract base class for navigation strategies.\n*\n* This class exists primarily for backward compatibility with legacy code.\n* New code should use CardGenerator or CardFilter interfaces directly.\n*\n* The class implements StudyContentSource for compatibility with SessionController.\n* Once SessionController migrates to use getWeightedCards() exclusively,\n* the legacy methods can be removed.\n*/\nvar ContentNavigator = class {\n\t/** User interface for this navigation session */\n\tuser;\n\t/** Course interface for this navigation session */\n\tcourse;\n\t/** Human-readable name for this strategy instance (from ContentNavigationStrategyData.name) */\n\tstrategyName;\n\t/** Unique document ID for this strategy instance (from ContentNavigationStrategyData._id) */\n\tstrategyId;\n\t/** Evolutionary weighting configuration */\n\tlearnable;\n\t/** Whether to bypass deviation (manual/static weighting) */\n\tstaticWeight;\n\t/**\n\t* Constructor for standard navigators.\n\t* Call this from subclass constructors to initialize common fields.\n\t*\n\t* Note: CompositeGenerator and Pipeline call super() without args, then set\n\t* user/course fields directly if needed.\n\t*/\n\tconstructor(user, course, strategyData) {\n\t\tthis.user = user;\n\t\tthis.course = course;\n\t\tif (strategyData) {\n\t\t\tthis.strategyName = strategyData.name;\n\t\t\tthis.strategyId = strategyData._id;\n\t\t\tthis.learnable = strategyData.learnable;\n\t\t\tthis.staticWeight = strategyData.staticWeight;\n\t\t}\n\t}\n\t/**\n\t* Unique key identifying this strategy for state storage.\n\t*\n\t* Defaults to the constructor name (e.g., \"UserTagPreferenceFilter\").\n\t* Override in subclasses if multiple instances of the same strategy type\n\t* need separate state storage.\n\t*/\n\tget strategyKey() {\n\t\treturn this.constructor.name;\n\t}\n\t/**\n\t* Get this strategy's persisted state for the current course.\n\t*\n\t* @returns The strategy's data payload, or null if no state exists\n\t* @throws Error if user or course is not initialized\n\t*/\n\tasync getStrategyState() {\n\t\tif (!this.user || !this.course) throw new Error(\"Cannot get strategy state: navigator not properly initialized. Ensure user and course are provided to constructor.\");\n\t\treturn this.user.getStrategyState(this.course.getCourseID(), this.strategyKey);\n\t}\n\t/**\n\t* Persist this strategy's state for the current course.\n\t*\n\t* @param data - The strategy's data payload to store\n\t* @throws Error if user or course is not initialized\n\t*/\n\tasync putStrategyState(data) {\n\t\tif (!this.user || !this.course) throw new Error(\"Cannot put strategy state: navigator not properly initialized. Ensure user and course are provided to constructor.\");\n\t\treturn this.user.putStrategyState(this.course.getCourseID(), this.strategyKey, data);\n\t}\n\t/**\n\t* Factory method to create navigator instances.\n\t*\n\t* First checks the navigator registry for a pre-registered constructor.\n\t* If not found, falls back to dynamic import (for custom navigators).\n\t*\n\t* For reliable operation in test environments, call initializeNavigatorRegistry()\n\t* before using this method.\n\t*\n\t* @param user - User interface\n\t* @param course - Course interface\n\t* @param strategyData - Strategy configuration document\n\t* @returns the runtime object used to steer a study session.\n\t*/\n\tstatic async create(user, course, strategyData) {\n\t\tconst implementingClass = strategyData.implementingClass;\n\t\tconst RegisteredImpl = getRegisteredNavigator(implementingClass);\n\t\tif (RegisteredImpl) {\n\t\t\tlogger.debug(`[ContentNavigator.create] Using registered navigator: ${implementingClass}`);\n\t\t\treturn new RegisteredImpl(user, course, strategyData);\n\t\t}\n\t\tlogger.debug(`[ContentNavigator.create] Navigator not in registry, attempting dynamic import: ${implementingClass}`);\n\t\tlet NavigatorImpl;\n\t\tconst load = (specifier) => import(\n\t\t\t/* @vite-ignore */\n\t\t\tspecifier\n);\n\t\tfor (const ext of [\n\t\t\t\".ts\",\n\t\t\t\".js\",\n\t\t\t\"\"\n\t\t]) {\n\t\t\ttry {\n\t\t\t\tNavigatorImpl = (await load(`./generators/${implementingClass}${ext}`)).default;\n\t\t\t\tif (NavigatorImpl) break;\n\t\t\t} catch (e) {\n\t\t\t\tlogger.debug(`Failed to load generator ${implementingClass}${ext}:`, e);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tNavigatorImpl = (await load(`./filters/${implementingClass}${ext}`)).default;\n\t\t\t\tif (NavigatorImpl) break;\n\t\t\t} catch (e) {\n\t\t\t\tlogger.debug(`Failed to load filter ${implementingClass}${ext}:`, e);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tNavigatorImpl = (await load(`./${implementingClass}${ext}`)).default;\n\t\t\t\tif (NavigatorImpl) break;\n\t\t\t} catch (e) {\n\t\t\t\tlogger.debug(`Failed to load legacy ${implementingClass}${ext}:`, e);\n\t\t\t}\n\t\t\tif (NavigatorImpl) break;\n\t\t}\n\t\tif (!NavigatorImpl) throw new Error(`Could not load navigator implementation for: ${implementingClass}`);\n\t\treturn new NavigatorImpl(user, course, strategyData);\n\t}\n\t/**\n\t* Get cards with suitability scores and provenance trails.\n\t*\n\t* **This is the PRIMARY API for navigation strategies.**\n\t*\n\t* Returns cards ranked by suitability score (0-1). Higher scores indicate\n\t* better candidates for presentation. Each card includes a provenance trail\n\t* documenting how strategies contributed to the final score.\n\t*\n\t* ## Implementation Required\n\t* All navigation strategies MUST override this method. The base class does\n\t* not provide a default implementation.\n\t*\n\t* ## For Generators\n\t* Override this method to generate candidates and compute scores based on\n\t* your strategy's logic (e.g., ELO proximity, review urgency). Create the\n\t* initial provenance entry with action='generated'.\n\t*\n\t* ## For Filters\n\t* Filters should implement the CardFilter interface instead and be composed\n\t* via Pipeline. Filters do not directly implement getWeightedCards().\n\t*\n\t* @param limit - Maximum cards to return\n\t* @returns Cards sorted by score descending, with provenance trails\n\t*/\n\tasync getWeightedCards(_limit) {\n\t\tthrow new Error(`${this.constructor.name} must implement getWeightedCards(). `);\n\t}\n\t/**\n\t* Set ephemeral hints for the next pipeline run.\n\t* No-op for non-Pipeline navigators. Pipeline overrides this.\n\t*/\n\tsetEphemeralHints(_hints) {}\n};\n//#endregion\nexport { ContentNavigator, NavigatorRole, NavigatorRoles, Navigators, getCardOrigin, getRegisteredFilterKind, getRegisteredNavigator, getRegisteredNavigatorNames, getRegisteredNavigatorRole, hasRegisteredNavigator, initializeNavigatorRegistry, isFilter, isGenerator, registerNavigator };\n\n//# sourceMappingURL=index.mjs.map","import \"../../_virtual/_rolldown/runtime.mjs\";\nimport { logger } from \"../../util/logger.mjs\";\nimport { NavigatorRoles, getRegisteredNavigatorNames, getRegisteredNavigatorRole, isFilter, isGenerator } from \"./index.mjs\";\n//#region src/core/navigators/PipelineDebugger.ts\n/**\n* Captured reference to the most recently created Pipeline instance.\n* Used by the debug API to run diagnostics against the live pipeline.\n*/\nlet _activePipeline = null;\n/**\n* Register a pipeline instance for diagnostic access.\n* Called by Pipeline constructor.\n*/\nfunction registerPipelineForDebug(pipeline) {\n\t_activePipeline = pipeline;\n}\n/**\n* The most recently constructed pipeline for the current session, or null if\n* none has been built yet. This is the supported, non-debug accessor for\n* out-of-band reads against the live pipeline (e.g. a commit-free\n* `forecast()`), replacing reach-ins through `window.skuilder.pipeline`.\n*/\nfunction getActivePipeline() {\n\treturn _activePipeline;\n}\n/**\n* Ring buffer for storing recent pipeline runs.\n*/\nconst MAX_RUNS = 10;\nconst runHistory = [];\n/**\n* Ambient, like `registerPipelineForDebug` — a pipeline is per content-source\n* and can outlive any one session. Set by `SessionController`.\n*/\nlet _currentSessionId;\nfunction setDebugSessionId(sessionId) {\n\t_currentSessionId = sessionId;\n}\n/**\n* Runs captured since the last drain. `SessionController` drains after each\n* plan and applies its own label — one plan can be several runs (one per\n* source), and the label is the controller's knowledge, not the pipeline's.\n*/\nlet _pendingRuns = [];\n/** Take and clear the runs captured since the previous call, in execution order. */\nfunction drainCapturedRuns() {\n\tconst drained = _pendingRuns;\n\t_pendingRuns = [];\n\treturn drained;\n}\n/**\n* Runs for `sessionId`, oldest first. Bounded by {@link MAX_RUNS} — the\n* complete record is `StudySessionDoc.runs`.\n*/\nfunction getRunsForSession(sessionId) {\n\treturn runHistory.filter((r) => r.sessionId === sessionId).reverse();\n}\n/**\n* Cap on non-selected (\"discarded\") cards retained per run report.\n*\n* Pipeline candidate pools are typically hundreds of cards (ELO window pull\n* + generators), but most are scored down by filters and never selected.\n* Their provenance trails are the dominant text-memory cost in the ring\n* buffer (each entry ~1–2 KB). Retaining only the top-N \"near misses\"\n* preserves debugging value while collapsing memory roughly an order of\n* magnitude or more.\n*/\nconst DISCARDED_KEEP_TOP = 25;\n/**\n* Programmatic clear of pipeline run history.\n*\n* Called by session-lifecycle hooks (session end, course switch, logout)\n* to release retained provenance/tag arrays once they're no longer useful\n* for in-session debugging. The interactive `clear()` debug method remains\n* for manual use.\n*/\nfunction clearRunHistory() {\n\trunHistory.length = 0;\n\t_pendingRuns = [];\n}\n/**\n* What a card is to the learner's queue: a scheduled review (it carries a\n* `reviewID`) or new. The same test as the generator counts and\n* `unselectedNew`. What put it in the queue is {@link RunReportCard.generator}\n* and {@link RunReportCard.required}.\n*/\nfunction getOrigin(card) {\n\treturn card.reviewID ? \"review\" : \"new\";\n}\n/**\n* The hint that made a card mandatory (its provenance name), if one did.\n* applyHints marks a requireCards/requireTags requirement with an infinite\n* score, and nothing else scores a card infinite.\n*/\nfunction requiredBy(card) {\n\treturn card.provenance.find((p) => p.strategy === \"ephemeralHint\" && p.score === Number.POSITIVE_INFINITY)?.strategyName;\n}\n/**\n* Capture a pipeline run for later inspection.\n*/\nfunction captureRun(report) {\n\tconst fullReport = {\n\t\t...report,\n\t\trunId: `run-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\n\t\tsessionId: _currentSessionId,\n\t\ttimestamp: /* @__PURE__ */ new Date()\n\t};\n\trunHistory.unshift(fullReport);\n\tif (runHistory.length > MAX_RUNS) runHistory.pop();\n\t_pendingRuns.push(fullReport);\n\treturn fullReport;\n}\n/**\n* Build a capture-ready report from pipeline execution data.\n*/\n/**\n* Parse card ELO from the ELO generator's provenance reason string.\n* Format: \"ELO distance XX (card: YYYY, user: ZZZZ), ...\"\n*/\nfunction parseCardElo(provenance) {\n\tconst eloEntry = provenance.find((p) => p.strategy === \"elo\");\n\tif (!eloEntry?.reason) return void 0;\n\tconst match = eloEntry.reason.match(/card:\\s*(\\d+)/);\n\treturn match ? parseInt(match[1], 10) : void 0;\n}\nfunction buildRunReport(courseId, courseName, generatorName, generators, generatedCount, filters, allCards, selectedCards, userElo, hints, scoredCards, regulators) {\n\tconst selectedIds = new Set(selectedCards.map((c) => c.cardId));\n\tconst toReport = (card) => {\n\t\tconst required = requiredBy(card);\n\t\tconst first = card.provenance[0];\n\t\tconst generator = first && first.strategy !== \"ephemeralHint\" ? first.strategyName || first.strategy : void 0;\n\t\treturn {\n\t\t\tcardId: card.cardId,\n\t\t\tcourseId: card.courseId,\n\t\t\torigin: getOrigin(card),\n\t\t\t...generator ? { generator } : {},\n\t\t\t...required ? { required } : {},\n\t\t\tfinalScore: card.score,\n\t\t\tcardElo: card.cardElo ?? parseCardElo(card.provenance),\n\t\t\tprovenance: card.provenance,\n\t\t\ttags: card.tags,\n\t\t\tselected: selectedIds.has(card.cardId)\n\t\t};\n\t};\n\tconst selectedReported = [];\n\tconst nearMissReported = [];\n\tconst discardedTailCards = [];\n\tlet nonSelectedSeen = 0;\n\tfor (const card of allCards) if (selectedIds.has(card.cardId)) selectedReported.push(toReport(card));\n\telse if (nonSelectedSeen < DISCARDED_KEEP_TOP) {\n\t\tnearMissReported.push(toReport(card));\n\t\tnonSelectedSeen++;\n\t} else discardedTailCards.push(card);\n\tconst cards = [...selectedReported, ...nearMissReported];\n\tlet discardedTail;\n\tif (discardedTailCards.length > 0) {\n\t\tlet scoreMin = Infinity;\n\t\tlet scoreMax = -Infinity;\n\t\tlet eloMin = Infinity;\n\t\tlet eloMax = -Infinity;\n\t\tlet eloSeen = false;\n\t\tfor (const c of discardedTailCards) {\n\t\t\tif (c.score < scoreMin) scoreMin = c.score;\n\t\t\tif (c.score > scoreMax) scoreMax = c.score;\n\t\t\tconst elo = parseCardElo(c.provenance);\n\t\t\tif (elo !== void 0) {\n\t\t\t\teloSeen = true;\n\t\t\t\tif (elo < eloMin) eloMin = elo;\n\t\t\t\tif (elo > eloMax) eloMax = elo;\n\t\t\t}\n\t\t}\n\t\tconst eloFragment = eloSeen ? `, ELO ${eloMin}–${eloMax}` : \"\";\n\t\tdiscardedTail = {\n\t\t\tcount: discardedTailCards.length,\n\t\t\tscoreRange: [scoreMin, scoreMax],\n\t\t\teloRange: eloSeen ? [eloMin, eloMax] : void 0,\n\t\t\tnote: `${discardedTailCards.length} additional candidate(s) scored below the top ${DISCARDED_KEEP_TOP} near-misses and were not retained (score ${scoreMin.toExponential(2)}–${scoreMax.toExponential(2)}${eloFragment}). Likely ELO-window pull remnants filtered out by hierarchy/lesson/priority gates.`\n\t\t};\n\t}\n\tconst isUnselectedNew = (c) => !c.reviewID && !selectedIds.has(c.cardId);\n\tconst generatorScore = (c) => c.provenance[0]?.score ?? 0;\n\tconst keptIds = new Set(allCards.map((c) => c.cardId));\n\tconst hintExcluded = (c) => c.score > 0 && !keptIds.has(c.cardId);\n\tlet nextInLine;\n\tfor (const c of allCards) if (isUnselectedNew(c) && (!nextInLine || c.score > nextInLine.score)) nextInLine = c;\n\tlet topGenerated;\n\tfor (const c of scoredCards ?? allCards) {\n\t\tif (!isUnselectedNew(c) || hintExcluded(c)) continue;\n\t\tif (!topGenerated || generatorScore(c) > generatorScore(topGenerated)) topGenerated = c;\n\t}\n\tconst unselectedNew = nextInLine || topGenerated ? {\n\t\t...nextInLine ? { nextInLine: toReport(nextInLine) } : {},\n\t\t...topGenerated && topGenerated.cardId !== nextInLine?.cardId ? { topGenerated: toReport(topGenerated) } : {}\n\t} : void 0;\n\tconst reviewsSelected = selectedCards.filter((c) => getOrigin(c) === \"review\").length;\n\tconst newSelected = selectedCards.filter((c) => getOrigin(c) === \"new\").length;\n\treturn {\n\t\tcourseId,\n\t\tcourseName,\n\t\tuserElo,\n\t\tgeneratorName,\n\t\tgenerators,\n\t\tgeneratedCount,\n\t\tfilters,\n\t\thints,\n\t\tfinalCount: selectedCards.length,\n\t\treviewsSelected,\n\t\tnewSelected,\n\t\tcards,\n\t\tunselectedNew,\n\t\tdiscardedTail,\n\t\t...regulators ? { regulators } : {}\n\t};\n}\n/**\n* Format a provenance trail for console display.\n*/\nfunction formatProvenance(provenance) {\n\treturn provenance.map((p) => {\n\t\treturn ` ${p.action === \"generated\" ? \"🎲\" : p.action === \"boosted\" ? \"⬆️\" : p.action === \"penalized\" ? \"⬇️\" : \"➡️\"} ${p.strategyName}: ${p.score.toFixed(3)} - ${p.reason}`;\n\t}).join(\"\\n\");\n}\n/**\n* Print summary of a single pipeline run.\n*/\nfunction printRunSummary(run) {\n\tconsole.group(`🔍 Pipeline Run: ${run.courseId} (${run.courseName || \"unnamed\"})`);\n\tlogger.print(`Run ID: ${run.runId}`);\n\tlogger.print(`Time: ${run.timestamp.toISOString()}`);\n\tlogger.print(`User ELO: ${run.userElo ?? \"unknown\"}`);\n\tlogger.print(`Generator: ${run.generatorName} → ${run.generatedCount} candidates`);\n\tif (run.generators && run.generators.length > 0) {\n\t\tconsole.group(\"Generator breakdown:\");\n\t\tfor (const g of run.generators) logger.print(` ${g.name}: ${g.cardCount} cards (${g.newCount} new, ${g.reviewCount} reviews, top: ${g.topScore.toFixed(2)})`);\n\t\tconsole.groupEnd();\n\t}\n\tif (run.filters.length > 0) {\n\t\tconsole.group(\"Filter impact:\");\n\t\tfor (const f of run.filters) logger.print(` ${f.name}: ↑${f.boosted} ↓${f.penalized} =${f.passed} ✕${f.removed}`);\n\t\tconsole.groupEnd();\n\t}\n\tlogger.print(`Result: ${run.finalCount} cards selected (${run.newSelected} new, ${run.reviewsSelected} reviews)`);\n\tconsole.groupEnd();\n}\nlet _uiContainer = null;\nlet _selectedRunIndex = null;\nlet _cardSearchQuery = \"\";\nfunction escapeHtml(s) {\n\treturn s.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n}\nfunction escapeAttr(s) {\n\treturn escapeHtml(s).replace(/\"/g, \"&quot;\");\n}\nfunction copyTextToClipboard(text, btn) {\n\tconst done = () => {\n\t\tif (!btn) return;\n\t\tconst orig = btn.textContent ?? \"Copy\";\n\t\tbtn.textContent = \"Copied!\";\n\t\tbtn.classList.add(\"copied\");\n\t\tsetTimeout(() => {\n\t\t\tbtn.textContent = orig;\n\t\t\tbtn.classList.remove(\"copied\");\n\t\t}, 1200);\n\t};\n\tconst fallback = () => {\n\t\tconst ta = document.createElement(\"textarea\");\n\t\tta.value = text;\n\t\tta.style.position = \"fixed\";\n\t\tta.style.opacity = \"0\";\n\t\tdocument.body.appendChild(ta);\n\t\tta.select();\n\t\ttry {\n\t\t\tdocument.execCommand(\"copy\");\n\t\t} catch (e) {\n\t\t\tlogger.warn(`[Pipeline Debug] Copy failed: ${e}`);\n\t\t}\n\t\tdocument.body.removeChild(ta);\n\t\tdone();\n\t};\n\tif (navigator.clipboard?.writeText) navigator.clipboard.writeText(text).then(done).catch(fallback);\n\telse fallback();\n}\nfunction renderUI() {\n\tif (!_uiContainer) return;\n\tconst runs = runHistory;\n\tconst selectedRun = _selectedRunIndex !== null ? runs[_selectedRunIndex] : null;\n\tconst styles = `\n #sk-pipeline-debugger {\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n background: #f8f9fa;\n color: #212529;\n z-index: 999999;\n display: flex;\n flex-direction: column;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n font-size: 14px;\n }\n #sk-pipeline-debugger header {\n padding: 1rem;\n background: #343a40;\n color: white;\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n #sk-pipeline-debugger .container {\n display: flex;\n flex: 1;\n overflow: hidden;\n }\n #sk-pipeline-debugger .sidebar {\n width: 300px;\n border-right: 1px solid #dee2e6;\n overflow-y: auto;\n background: white;\n }\n #sk-pipeline-debugger .main-content {\n flex: 1;\n overflow-y: auto;\n padding: 1.5rem;\n }\n #sk-pipeline-debugger .run-item {\n padding: 0.75rem 1rem;\n border-bottom: 1px solid #eee;\n cursor: pointer;\n }\n #sk-pipeline-debugger .run-item:hover { background: #f1f3f5; }\n #sk-pipeline-debugger .run-item.active { background: #e9ecef; border-left: 4px solid #007bff; }\n #sk-pipeline-debugger h2, #sk-pipeline-debugger h3 { margin-top: 0; }\n #sk-pipeline-debugger table { width: 100%; border-collapse: collapse; margin-bottom: 1rem; background: white; }\n #sk-pipeline-debugger th, #sk-pipeline-debugger td { border: 1px solid #dee2e6; padding: 0.5rem; text-align: left; }\n #sk-pipeline-debugger th { background: #f1f3f5; }\n #sk-pipeline-debugger code { background: #f1f3f5; padding: 0.1rem 0.3rem; border-radius: 3px; font-family: monospace; }\n #sk-pipeline-debugger .close-btn { background: #dc3545; color: white; border: none; padding: 0.5rem 1rem; border-radius: 4px; cursor: pointer; }\n #sk-pipeline-debugger .search-box { margin-bottom: 1rem; width: 100%; padding: 0.5rem; border: 1px solid #ced4da; border-radius: 4px; }\n #sk-pipeline-debugger .provenance { font-size: 12px; color: #666; margin-top: 0.25rem; white-space: pre-wrap; font-family: monospace; background: #f8f9fa; padding: 0.5rem; border-radius: 4px; }\n #sk-pipeline-debugger .run-label { display: inline-block; margin-top: 0.25rem; padding: 0.1rem 0.4rem; background: #fff3cd; color: #664d03; border-radius: 3px; font-family: monospace; font-size: 11px; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }\n #sk-pipeline-debugger .label-banner { display: inline-block; padding: 0.25rem 0.6rem; background: #fff3cd; color: #664d03; border-radius: 4px; font-family: monospace; font-size: 13px; margin: 0 0 0.75rem 0; }\n #sk-pipeline-debugger .copy-btn { background: #0d6efd; color: white; border: none; padding: 0.25rem 0.6rem; border-radius: 3px; cursor: pointer; font-size: 12px; margin-left: 0.5rem; }\n #sk-pipeline-debugger .copy-btn:hover { background: #0b5ed7; }\n #sk-pipeline-debugger .copy-btn.copied { background: #198754; }\n #sk-pipeline-debugger .section-head { display: flex; align-items: center; justify-content: space-between; margin-top: 1rem; }\n #sk-pipeline-debugger .section-head h3 { margin: 0; }\n `;\n\tconst runListHtml = runs.length === 0 ? \"<div style=\\\"padding: 1rem;\\\">No runs captured yet.</div>\" : runs.map((r, i) => `\n <div class=\"run-item ${i === _selectedRunIndex ? \"active\" : \"\"}\" onclick=\"window.skuilder.pipeline._selectRun(${i})\">\n <strong>${r.timestamp.toLocaleTimeString()}</strong><br/>\n <small>${r.courseName || r.courseId.slice(0, 8)}</small><br/>\n <small>${r.finalCount} cards selected</small>\n ${r.hints?._label ? `<br/><span class=\"run-label\" title=\"${escapeAttr(r.hints._label)}\">${escapeHtml(r.hints._label)}</span>` : \"\"}\n </div>\n `).join(\"\");\n\tlet detailsHtml = \"<div style=\\\"color: #6c757d; text-align: center; margin-top: 5rem;\\\">Select a run to see details</div>\";\n\tif (selectedRun) {\n\t\tconst filteredCards = selectedRun.cards.filter((c) => !_cardSearchQuery || c.cardId.toLowerCase().includes(_cardSearchQuery.toLowerCase()));\n\t\tconst labelText = selectedRun.hints?._label ?? \"(no label)\";\n\t\tdetailsHtml = `\n <h2>Run: ${selectedRun.runId}</h2>\n <div class=\"label-banner\" title=\"${escapeAttr(labelText)}\">${escapeHtml(labelText)}</div>\n <p>\n <strong>Time:</strong> ${selectedRun.timestamp.toLocaleString()} |\n <strong>Course:</strong> ${selectedRun.courseName || selectedRun.courseId} |\n <strong>User ELO:</strong> ${selectedRun.userElo ?? \"unknown\"}\n </p>\n\n <h3>Pipeline Config</h3>\n <table>\n <tr><th>Generator</th><td>${selectedRun.generatorName} (${selectedRun.generatedCount} candidates)</td></tr>\n ${(selectedRun.generators || []).map((g) => `\n <tr><td style=\"padding-left: 2rem;\">↳ ${g.name}</td><td>${g.cardCount} cards (${g.newCount} new, ${g.reviewCount} review, top: ${g.topScore.toFixed(2)})</td></tr>\n `).join(\"\")}\n </table>\n\n ${selectedRun.hints ? `\n <div class=\"section-head\">\n <h3>Ephemeral Hints</h3>\n <button class=\"copy-btn\" onclick=\"window.skuilder.pipeline._copyConfig('${selectedRun.runId}', this)\">Copy config</button>\n </div>\n <table>\n ${selectedRun.hints._label ? `<tr><th>Label</th><td>${selectedRun.hints._label}</td></tr>` : \"\"}\n ${selectedRun.hints.boostTags ? `<tr><th>Boost Tags</th><td><pre style=\"margin:0\">${JSON.stringify(selectedRun.hints.boostTags, null, 2)}</pre></td></tr>` : \"\"}\n ${selectedRun.hints.boostCards ? `<tr><th>Boost Cards</th><td><pre style=\"margin:0\">${JSON.stringify(selectedRun.hints.boostCards, null, 2)}</pre></td></tr>` : \"\"}\n ${selectedRun.hints.requireTags ? `<tr><th>Require Tags</th><td>${selectedRun.hints.requireTags.join(\", \")}</td></tr>` : \"\"}\n ${selectedRun.hints.requireCards ? `<tr><th>Require Cards</th><td>${selectedRun.hints.requireCards.join(\", \")}</td></tr>` : \"\"}\n ${selectedRun.hints.excludeTags ? `<tr><th>Exclude Tags</th><td>${selectedRun.hints.excludeTags.join(\", \")}</td></tr>` : \"\"}\n ${selectedRun.hints.excludeCards ? `<tr><th>Exclude Cards</th><td>${selectedRun.hints.excludeCards.join(\", \")}</td></tr>` : \"\"}\n </table>\n ` : \"\"}\n\n <h3>Filter Impact</h3>\n <table>\n <thead><tr><th>Filter</th><th>Boosted</th><th>Penalized</th><th>Passed</th><th>Removed</th></tr></thead>\n <tbody>\n ${selectedRun.filters.map((f) => `\n <tr><td>${f.name}</td><td>↑${f.boosted}</td><td>↓${f.penalized}</td><td>=${f.passed}</td><td>✕${f.removed}</td></tr>\n `).join(\"\")}\n </tbody>\n </table>\n\n <div class=\"section-head\">\n <h3>Cards (${selectedRun.finalCount} selected / ${selectedRun.cards.length} total)</h3>\n <button class=\"copy-btn\" onclick=\"window.skuilder.pipeline._copyResults('${selectedRun.runId}', this)\">Copy results</button>\n </div>\n <input type=\"text\" class=\"search-box\" placeholder=\"Search Card ID...\" value=\"${_cardSearchQuery}\" oninput=\"window.skuilder.pipeline._setSearch(this.value)\">\n \n <table>\n <thead><tr><th>ID</th><th>Generator</th><th>Origin</th><th>Score</th><th>Selected</th></tr></thead>\n <tbody>\n ${filteredCards.map((c) => `\n <tr>\n <td><code>${c.cardId}</code></td>\n <td>${c.generator || \"unknown\"}</td>\n <td>${c.origin}</td>\n <td>${c.finalScore.toFixed(3)}</td>\n <td>${c.selected ? \"✅\" : \"❌\"}</td>\n </tr>\n ${c.selected || _cardSearchQuery ? `\n <tr>\n <td colspan=\"5\">\n <div class=\"provenance\">${formatProvenance(c.provenance)}</div>\n </td>\n </tr>\n ` : \"\"}\n `).join(\"\")}\n </tbody>\n </table>\n `;\n\t}\n\t_uiContainer.innerHTML = `\n <style>${styles}</style>\n <header>\n <strong>Pipeline Debugger</strong>\n <button class=\"close-btn\" onclick=\"window.skuilder.pipeline.ui()\">Close</button>\n </header>\n <div class=\"container\">\n <div class=\"sidebar\">${runListHtml}</div>\n <div class=\"main-content\">${detailsHtml}</div>\n </div>\n `;\n}\n/**\n* Console API object exposed on window.skuilder.pipeline\n*/\nconst pipelineDebugAPI = {\n\tget runs() {\n\t\treturn [...runHistory];\n\t},\n\tshowRun(idOrIndex = 0) {\n\t\tif (runHistory.length === 0) {\n\t\t\tlogger.print(\"[Pipeline Debug] No runs captured yet.\");\n\t\t\treturn;\n\t\t}\n\t\tlet run;\n\t\tif (typeof idOrIndex === \"number\") {\n\t\t\trun = runHistory[idOrIndex];\n\t\t\tif (!run) {\n\t\t\t\tlogger.print(`[Pipeline Debug] No run found at index ${idOrIndex}. History length: ${runHistory.length}`);\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\trun = runHistory.find((r) => r.runId.endsWith(idOrIndex));\n\t\t\tif (!run) {\n\t\t\t\tlogger.print(`[Pipeline Debug] No run found matching ID '${idOrIndex}'.`);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tprintRunSummary(run);\n\t},\n\tshowLastRun() {\n\t\tthis.showRun(0);\n\t},\n\tshowCard(cardId) {\n\t\tfor (const run of runHistory) {\n\t\t\tconst card = run.cards.find((c) => c.cardId === cardId);\n\t\t\tif (card) {\n\t\t\t\tconsole.group(`🎴 Card: ${cardId}`);\n\t\t\t\tlogger.print(`Course: ${card.courseId}`);\n\t\t\t\tlogger.print(`Origin: ${card.origin}`);\n\t\t\t\tlogger.print(`Card ELO: ${card.cardElo ?? \"unknown\"} | User ELO: ${run.userElo ?? \"unknown\"}`);\n\t\t\t\tlogger.print(`Final score: ${card.finalScore.toFixed(3)}`);\n\t\t\t\tlogger.print(`Selected: ${card.selected ? \"Yes ✅\" : \"No ❌\"}`);\n\t\t\t\tif (card.tags && card.tags.length > 0) logger.print(`Tags (${card.tags.length}): ${card.tags.join(\", \")}`);\n\t\t\t\tlogger.print(\"Provenance:\");\n\t\t\t\tlogger.print(formatProvenance(card.provenance));\n\t\t\t\tconsole.groupEnd();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tconst runsWithTails = runHistory.filter((r) => r.discardedTail && r.discardedTail.count > 0);\n\t\tif (runsWithTails.length > 0) logger.print(`[Pipeline Debug] Card '${cardId}' not found in retained cards. ${runsWithTails.length} run(s) have discarded tails that were not retained — the card may have been a low-score candidate. See run.discardedTail for ranges.`);\n\t\telse logger.print(`[Pipeline Debug] Card '${cardId}' not found in recent runs.`);\n\t},\n\texplainReviews() {\n\t\tif (runHistory.length === 0) {\n\t\t\tlogger.print(\"[Pipeline Debug] No runs captured yet.\");\n\t\t\treturn;\n\t\t}\n\t\tconsole.group(\"📋 Review Selection Analysis\");\n\t\tfor (const run of runHistory) {\n\t\t\tconsole.group(`Run: ${run.courseId} @ ${run.timestamp.toLocaleTimeString()}`);\n\t\t\tconst allReviews = run.cards.filter((c) => c.origin === \"review\");\n\t\t\tconst selectedReviews = allReviews.filter((c) => c.selected);\n\t\t\tif (allReviews.length === 0) logger.print(\"❌ No reviews were generated. Check SRS logs for why.\");\n\t\t\telse if (selectedReviews.length === 0) {\n\t\t\t\tlogger.print(`⚠️ ${allReviews.length} reviews generated but none selected.`);\n\t\t\t\tlogger.print(\"Possible reasons:\");\n\t\t\t\tconst topNewScore = Math.max(...run.cards.filter((c) => c.origin === \"new\" && c.selected).map((c) => c.finalScore), 0);\n\t\t\t\tconst topReviewScore = Math.max(...allReviews.map((c) => c.finalScore), 0);\n\t\t\t\tif (topReviewScore < topNewScore) logger.print(` - New cards scored higher (top new: ${topNewScore.toFixed(2)}, top review: ${topReviewScore.toFixed(2)})`);\n\t\t\t\tconst topReview = allReviews.sort((a, b) => b.finalScore - a.finalScore)[0];\n\t\t\t\tif (topReview) {\n\t\t\t\t\tlogger.print(` - Top review score: ${topReview.finalScore.toFixed(3)}`);\n\t\t\t\t\tlogger.print(\" - Its provenance:\");\n\t\t\t\t\tlogger.print(formatProvenance(topReview.provenance));\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlogger.print(`✅ ${selectedReviews.length}/${allReviews.length} reviews selected.`);\n\t\t\t\tlogger.print(\"Top selected review:\");\n\t\t\t\tconst topSelected = selectedReviews.sort((a, b) => b.finalScore - a.finalScore)[0];\n\t\t\t\tlogger.print(formatProvenance(topSelected.provenance));\n\t\t\t}\n\t\t\tconsole.groupEnd();\n\t\t}\n\t\tconsole.groupEnd();\n\t},\n\tshowPrescribed(groupId) {\n\t\tif (runHistory.length === 0) {\n\t\t\tlogger.print(\"[Pipeline Debug] No runs captured yet.\");\n\t\t\treturn;\n\t\t}\n\t\tconst run = runHistory[0];\n\t\tconst prescribedCards = run.cards.filter((c) => c.provenance.some((p) => p.strategy === \"prescribed\"));\n\t\tconsole.group(`🧭 Prescribed Debug (${run.courseId})`);\n\t\tif (prescribedCards.length === 0) {\n\t\t\tlogger.print(\"No prescribed-generated cards were present in the most recent run.\");\n\t\t\tconsole.groupEnd();\n\t\t\treturn;\n\t\t}\n\t\tconst rows = prescribedCards.map((card) => {\n\t\t\tconst reason = card.provenance.find((p) => p.strategy === \"prescribed\")?.reason ?? \"\";\n\t\t\tconst parsedGroup = reason.match(/group=([^;]+)/)?.[1] ?? \"unknown\";\n\t\t\tconst mode = reason.match(/mode=([^;]+)/)?.[1] ?? \"unknown\";\n\t\t\tconst blocked = reason.match(/blocked=([^;]+)/)?.[1] ?? \"unknown\";\n\t\t\tconst blockedTargets = reason.match(/blockedTargets=([^;]+)/)?.[1] ?? \"none\";\n\t\t\tconst supportCard = reason.match(/supportCard=([^;]+)/)?.[1] ?? \"none\";\n\t\t\tconst supportTags = reason.match(/supportTags=([^;]+)/)?.[1] ?? \"none\";\n\t\t\tconst multiplier = reason.match(/multiplier=([^;]+)/)?.[1] ?? \"unknown\";\n\t\t\treturn {\n\t\t\t\tgroup: parsedGroup,\n\t\t\t\tmode,\n\t\t\t\tsupportSource: mode === \"discovered-support\" ? \"discovered\" : mode === \"support\" ? \"authored\" : \"n/a\",\n\t\t\t\tcardId: card.cardId,\n\t\t\t\tselected: card.selected ? \"yes\" : \"no\",\n\t\t\t\tfinalScore: card.finalScore.toFixed(3),\n\t\t\t\tblocked,\n\t\t\t\tblockedTargets,\n\t\t\t\tsupportCard,\n\t\t\t\tsupportTags,\n\t\t\t\tmultiplier\n\t\t\t};\n\t\t}).filter((row) => !groupId || row.group === groupId).sort((a, b) => Number(b.finalScore) - Number(a.finalScore));\n\t\tif (rows.length === 0) {\n\t\t\tlogger.print(`[Pipeline Debug] No prescribed cards matched group '${groupId}' in the most recent run.`);\n\t\t\tconsole.groupEnd();\n\t\t\treturn;\n\t\t}\n\t\tconsole.table(rows);\n\t\tconst selectedRows = rows.filter((r) => r.selected === \"yes\");\n\t\tconst blockedTargetSet = /* @__PURE__ */ new Set();\n\t\tconst supportTagSet = /* @__PURE__ */ new Set();\n\t\tconst authoredSupportSet = /* @__PURE__ */ new Set();\n\t\tconst discoveredSupportSet = /* @__PURE__ */ new Set();\n\t\tfor (const row of rows) {\n\t\t\tif (row.blockedTargets && row.blockedTargets !== \"none\") row.blockedTargets.split(\"|\").filter(Boolean).forEach((t) => blockedTargetSet.add(t));\n\t\t\tif (row.supportTags && row.supportTags !== \"none\") row.supportTags.split(\"|\").filter(Boolean).forEach((t) => supportTagSet.add(t));\n\t\t\tif (row.supportCard && row.supportCard !== \"none\") {\n\t\t\t\tif (row.supportSource === \"discovered\") discoveredSupportSet.add(row.supportCard);\n\t\t\t\telse if (row.supportSource === \"authored\") authoredSupportSet.add(row.supportCard);\n\t\t\t}\n\t\t}\n\t\tlogger.print(`Prescribed cards in run: ${rows.length}`);\n\t\tlogger.print(`Selected prescribed cards: ${selectedRows.length}`);\n\t\tlogger.print(`Blocked prescribed targets referenced: ${blockedTargetSet.size > 0 ? [...blockedTargetSet].join(\", \") : \"none\"}`);\n\t\tlogger.print(`Resolved support tags referenced: ${supportTagSet.size > 0 ? [...supportTagSet].join(\", \") : \"none\"}`);\n\t\tlogger.print(`Authored support cards emitted: ${authoredSupportSet.size > 0 ? [...authoredSupportSet].join(\", \") : \"none\"}`);\n\t\tlogger.print(`Discovered support cards emitted: ${discoveredSupportSet.size > 0 ? [...discoveredSupportSet].join(\", \") : \"none\"}`);\n\t\tconsole.groupEnd();\n\t},\n\tlistRuns() {\n\t\tif (runHistory.length === 0) {\n\t\t\tlogger.print(\"[Pipeline Debug] No runs captured yet.\");\n\t\t\treturn;\n\t\t}\n\t\tconsole.table(runHistory.map((r) => ({\n\t\t\tid: r.runId.slice(-8),\n\t\t\ttime: r.timestamp.toLocaleTimeString(),\n\t\t\tcourse: r.courseName || r.courseId.slice(0, 8),\n\t\t\tgenerated: r.generatedCount,\n\t\t\tselected: r.finalCount,\n\t\t\tnew: r.newSelected,\n\t\t\treviews: r.reviewsSelected\n\t\t})));\n\t},\n\texport() {\n\t\tconst json = JSON.stringify(runHistory, null, 2);\n\t\tlogger.print(\"[Pipeline Debug] Run history exported. Copy the returned string or use:\");\n\t\tlogger.print(\" copy(window.skuilder.pipeline.export())\");\n\t\treturn json;\n\t},\n\tclear() {\n\t\trunHistory.length = 0;\n\t\tlogger.print(\"[Pipeline Debug] Run history cleared.\");\n\t},\n\tshowRegistry() {\n\t\tconst names = getRegisteredNavigatorNames();\n\t\tif (names.length === 0) {\n\t\t\tlogger.print(\"[Pipeline Debug] Navigator registry is empty.\");\n\t\t\treturn;\n\t\t}\n\t\tconsole.group(\"📦 Navigator Registry\");\n\t\tconsole.table(names.map((name) => {\n\t\t\tconst registryRole = getRegisteredNavigatorRole(name);\n\t\t\tconst builtinRole = NavigatorRoles[name];\n\t\t\treturn {\n\t\t\t\tname,\n\t\t\t\trole: builtinRole || registryRole || \"⚠️ NONE\",\n\t\t\t\tsource: builtinRole ? \"built-in\" : registryRole ? \"consumer\" : \"unclassified\",\n\t\t\t\tisGenerator: isGenerator(name),\n\t\t\t\tisFilter: isFilter(name)\n\t\t\t};\n\t\t}));\n\t\tconsole.groupEnd();\n\t},\n\tshowStrategies() {\n\t\tthis.showRegistry();\n\t\tif (runHistory.length === 0) {\n\t\t\tlogger.print(\"[Pipeline Debug] No pipeline runs captured yet — cannot show strategy doc mapping.\");\n\t\t\treturn;\n\t\t}\n\t\tconst run = runHistory[0];\n\t\tconsole.group(\"🔌 Pipeline Strategy Mapping (last run)\");\n\t\tlogger.print(`Generator: ${run.generatorName}`);\n\t\tif (run.generators && run.generators.length > 0) for (const g of run.generators) logger.print(` 📥 ${g.name}: ${g.cardCount} cards (${g.newCount} new, ${g.reviewCount} reviews)`);\n\t\tif (run.filters.length > 0) {\n\t\t\tlogger.print(\"Filters:\");\n\t\t\tfor (const f of run.filters) logger.print(` 🔸 ${f.name}: ↑${f.boosted} ↓${f.penalized} =${f.passed} ✕${f.removed}`);\n\t\t} else logger.print(\"Filters: (none)\");\n\t\tconsole.groupEnd();\n\t},\n\tasync diagnoseCardSpace(threshold) {\n\t\tif (!_activePipeline) {\n\t\t\tlogger.print(\"[Pipeline Debug] No active pipeline. Run a session first.\");\n\t\t\treturn null;\n\t\t}\n\t\treturn _activePipeline.diagnoseCardSpace({ threshold });\n\t},\n\tasync showTagElo(tagFilter) {\n\t\tif (!_activePipeline) {\n\t\t\tlogger.print(\"[Pipeline Debug] No active pipeline. Run a session first.\");\n\t\t\treturn;\n\t\t}\n\t\tconst status = await _activePipeline.getTagEloStatus(tagFilter);\n\t\tconst entries = Object.entries(status).sort(([a], [b]) => a.localeCompare(b));\n\t\tif (entries.length === 0) {\n\t\t\tlogger.print(`[Pipeline Debug] No tag ELO data found${tagFilter ? ` for pattern: ${tagFilter}` : \"\"}.`);\n\t\t\treturn;\n\t\t}\n\t\tconsole.table(Object.fromEntries(entries.map(([tag, data]) => [tag, {\n\t\t\tscore: Math.round(data.score),\n\t\t\tcount: data.count\n\t\t}])));\n\t},\n\tui() {\n\t\tif (_uiContainer) {\n\t\t\tdocument.body.removeChild(_uiContainer);\n\t\t\t_uiContainer = null;\n\t\t\treturn;\n\t\t}\n\t\t_uiContainer = document.createElement(\"div\");\n\t\t_uiContainer.id = \"sk-pipeline-debugger\";\n\t\tdocument.body.appendChild(_uiContainer);\n\t\tif (_selectedRunIndex === null && runHistory.length > 0) _selectedRunIndex = 0;\n\t\trenderUI();\n\t},\n\t_selectRun(index) {\n\t\t_selectedRunIndex = index;\n\t\trenderUI();\n\t},\n\t_setSearch(query) {\n\t\t_cardSearchQuery = query;\n\t\trenderUI();\n\t},\n\t_copyConfig(runId, btn) {\n\t\tconst run = runHistory.find((r) => r.runId === runId);\n\t\tif (!run) return;\n\t\tconst payload = {\n\t\t\trunId: run.runId,\n\t\t\ttimestamp: run.timestamp.toISOString(),\n\t\t\tcourseId: run.courseId,\n\t\t\tcourseName: run.courseName,\n\t\t\thints: run.hints ?? null\n\t\t};\n\t\tcopyTextToClipboard(JSON.stringify(payload, null, 2), btn);\n\t},\n\t_copyResults(runId, btn) {\n\t\tconst run = runHistory.find((r) => r.runId === runId);\n\t\tif (!run) return;\n\t\tconst selected = run.cards.filter((c) => c.selected).sort((a, b) => b.finalScore - a.finalScore).map((c) => ({\n\t\t\tcardId: c.cardId,\n\t\t\tgenerator: c.generator,\n\t\t\torigin: c.origin,\n\t\t\tscore: Number(c.finalScore.toFixed(3)),\n\t\t\ttopReason: c.provenance[0]?.reason ?? \"\"\n\t\t}));\n\t\tconst payload = {\n\t\t\trunId: run.runId,\n\t\t\tlabel: run.hints?._label ?? null,\n\t\t\tfinalCount: run.finalCount,\n\t\t\tnewSelected: run.newSelected,\n\t\t\treviewsSelected: run.reviewsSelected,\n\t\t\tselected\n\t\t};\n\t\tcopyTextToClipboard(JSON.stringify(payload, null, 2), btn);\n\t},\n\thelp() {\n\t\tlogger.print(`\n🔧 Pipeline Debug API\n\nCommands:\n .ui() Toggle full-screen UI debugger\n .showLastRun() Show summary of most recent pipeline run\n .showRun(id|index) Show summary of a specific run (by index or ID suffix)\n .showCard(cardId) Show provenance trail for a specific card\n .showTagElo(pattern) Show user's tag ELO data (async). E.g. 'gpc:expose:*'\n .explainReviews() Analyze why reviews were/weren't selected\n .diagnoseCardSpace() Scan full card space through filters (async)\n .showRegistry() Show navigator registry (classes + roles)\n .showStrategies() Show registry + strategy mapping from last run\n .showPrescribed(id?) Show prescribed-generated cards and blocked/support details from last run\n .listRuns() List all captured runs in table format\n .export() Export run history as JSON for bug reports\n .clear() Clear run history\n .runs Access raw run history array\n .help() Show this help message\n\nExample:\n window.skuilder.pipeline.ui()\n window.skuilder.pipeline.showLastRun()\n window.skuilder.pipeline.showRun(1)\n await window.skuilder.pipeline.diagnoseCardSpace()\n`);\n\t}\n};\n/**\n* Mount the debug API on window.skuilder.pipeline\n*/\nfunction mountPipelineDebugger() {\n\tif (typeof window === \"undefined\") return;\n\tconst win = window;\n\twin.skuilder = win.skuilder || {};\n\twin.skuilder.pipeline = pipelineDebugAPI;\n}\nmountPipelineDebugger();\n//#endregion\nexport { buildRunReport, captureRun, clearRunHistory, drainCapturedRuns, getActivePipeline, getRunsForSession, mountPipelineDebugger, pipelineDebugAPI, registerPipelineForDebug, setDebugSessionId };\n\n//# sourceMappingURL=PipelineDebugger.mjs.map"],"file":"PipelineDebugger-DhnKlMgD.js"}