coursecode 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (362) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +322 -0
  3. package/THIRD_PARTY_NOTICES.md +22 -0
  4. package/bin/cli.js +331 -0
  5. package/framework/assets/logo-coursecode-black.svg +14 -0
  6. package/framework/assets/logo-coursecode-white.svg +14 -0
  7. package/framework/assets/logo-coursecode.svg +14 -0
  8. package/framework/css/01-base.css +160 -0
  9. package/framework/css/02-layout.css +499 -0
  10. package/framework/css/accessibility.css +834 -0
  11. package/framework/css/components/accordions.css +710 -0
  12. package/framework/css/components/assessments.css +520 -0
  13. package/framework/css/components/audio-player.css +570 -0
  14. package/framework/css/components/badges.css +80 -0
  15. package/framework/css/components/breadcrumbs.css +87 -0
  16. package/framework/css/components/buttons.css +707 -0
  17. package/framework/css/components/callouts.css +1280 -0
  18. package/framework/css/components/cards.css +475 -0
  19. package/framework/css/components/carousel.css +193 -0
  20. package/framework/css/components/checkbox-group.css +123 -0
  21. package/framework/css/components/checklist.css +203 -0
  22. package/framework/css/components/collapse.css +96 -0
  23. package/framework/css/components/comparison.css +33 -0
  24. package/framework/css/components/content-image.css +36 -0
  25. package/framework/css/components/document-gallery.css +425 -0
  26. package/framework/css/components/dropdown.css +115 -0
  27. package/framework/css/components/embed-frame.css +142 -0
  28. package/framework/css/components/engagement.css +412 -0
  29. package/framework/css/components/features.css +35 -0
  30. package/framework/css/components/flip-cards.css +253 -0
  31. package/framework/css/components/footer.css +353 -0
  32. package/framework/css/components/forms.css +294 -0
  33. package/framework/css/components/hero.css +216 -0
  34. package/framework/css/components/images.css +528 -0
  35. package/framework/css/components/interactive-timeline.css +274 -0
  36. package/framework/css/components/intro-cards.css +30 -0
  37. package/framework/css/components/lightbox.css +666 -0
  38. package/framework/css/components/loading.css +65 -0
  39. package/framework/css/components/modals.css +235 -0
  40. package/framework/css/components/notifications.css +107 -0
  41. package/framework/css/components/quote.css +150 -0
  42. package/framework/css/components/sidebar.css +684 -0
  43. package/framework/css/components/slide-header.css +52 -0
  44. package/framework/css/components/spinner.css +62 -0
  45. package/framework/css/components/stats.css +44 -0
  46. package/framework/css/components/steps.css +232 -0
  47. package/framework/css/components/tables.css +90 -0
  48. package/framework/css/components/tabs.css +347 -0
  49. package/framework/css/components/timeline.css +154 -0
  50. package/framework/css/components/toggle.css +95 -0
  51. package/framework/css/components/tooltip.css +226 -0
  52. package/framework/css/components/video-player.css +438 -0
  53. package/framework/css/design-tokens.css +707 -0
  54. package/framework/css/framework.css +86 -0
  55. package/framework/css/interactions/accessibility.css +75 -0
  56. package/framework/css/interactions/base.css +92 -0
  57. package/framework/css/interactions/drag-drop.css +295 -0
  58. package/framework/css/interactions/fill-in-the-blank.css +236 -0
  59. package/framework/css/interactions/hotspots.css +69 -0
  60. package/framework/css/interactions/index.css +45 -0
  61. package/framework/css/interactions/interactive-image.css +359 -0
  62. package/framework/css/interactions/likert.css +126 -0
  63. package/framework/css/interactions/matching.css +354 -0
  64. package/framework/css/interactions/numeric-input.css +78 -0
  65. package/framework/css/interactions/sequencing.css +378 -0
  66. package/framework/css/interactions/true-false.css +177 -0
  67. package/framework/css/layouts/article.css +258 -0
  68. package/framework/css/layouts/base.css +30 -0
  69. package/framework/css/layouts/canvas.css +38 -0
  70. package/framework/css/layouts/focused.css +236 -0
  71. package/framework/css/layouts/index.css +29 -0
  72. package/framework/css/layouts/presentation.css +191 -0
  73. package/framework/css/layouts/traditional.css +52 -0
  74. package/framework/css/responsive.css +439 -0
  75. package/framework/css/utilities/accessibility-utils.css +59 -0
  76. package/framework/css/utilities/animations.css +419 -0
  77. package/framework/css/utilities/borders.css +72 -0
  78. package/framework/css/utilities/colors.css +76 -0
  79. package/framework/css/utilities/container.css +46 -0
  80. package/framework/css/utilities/decorative.css +442 -0
  81. package/framework/css/utilities/display.css +257 -0
  82. package/framework/css/utilities/flexbox.css +80 -0
  83. package/framework/css/utilities/grid.css +69 -0
  84. package/framework/css/utilities/icons.css +534 -0
  85. package/framework/css/utilities/lists.css +190 -0
  86. package/framework/css/utilities/spacing.css +167 -0
  87. package/framework/css/utilities/tables.css +81 -0
  88. package/framework/css/utilities/typography.css +159 -0
  89. package/framework/css/utilities/visibility.css +117 -0
  90. package/framework/docs/COURSE_AUTHORING_GUIDE.md +1773 -0
  91. package/framework/docs/COURSE_OUTLINE_GUIDE.md +725 -0
  92. package/framework/docs/COURSE_OUTLINE_TEMPLATE.md +161 -0
  93. package/framework/docs/DATA_MODEL.md +409 -0
  94. package/framework/docs/FRAMEWORK_GUIDE.md +1088 -0
  95. package/framework/docs/USER_GUIDE.md +583 -0
  96. package/framework/docs/examples/cloudflare-channel-relay.js +169 -0
  97. package/framework/docs/examples/cloudflare-data-worker.js +102 -0
  98. package/framework/docs/examples/cloudflare-error-worker.js +228 -0
  99. package/framework/index.html +175 -0
  100. package/framework/js/app/AppActions.js +410 -0
  101. package/framework/js/app/AppState.js +225 -0
  102. package/framework/js/app/AppUI.js +616 -0
  103. package/framework/js/assessment/AssessmentActions.js +615 -0
  104. package/framework/js/assessment/AssessmentFactory.js +471 -0
  105. package/framework/js/assessment/AssessmentState.js +322 -0
  106. package/framework/js/assessment/AssessmentUI.js +451 -0
  107. package/framework/js/automation/api-engagement.js +196 -0
  108. package/framework/js/automation/api-interactions.js +167 -0
  109. package/framework/js/automation/api.js +242 -0
  110. package/framework/js/automation/index.js +41 -0
  111. package/framework/js/components/interactions/drag-drop.js +884 -0
  112. package/framework/js/components/interactions/fill-in.js +535 -0
  113. package/framework/js/components/interactions/hotspot.js +702 -0
  114. package/framework/js/components/interactions/interaction-base.js +511 -0
  115. package/framework/js/components/interactions/likert.js +301 -0
  116. package/framework/js/components/interactions/matching.js +699 -0
  117. package/framework/js/components/interactions/multiple-choice.js +377 -0
  118. package/framework/js/components/interactions/numeric.js +271 -0
  119. package/framework/js/components/interactions/sequencing.js +423 -0
  120. package/framework/js/components/interactions/true-false.js +241 -0
  121. package/framework/js/components/ui-components/accordion.js +442 -0
  122. package/framework/js/components/ui-components/alert.js +88 -0
  123. package/framework/js/components/ui-components/audio-player.js +1193 -0
  124. package/framework/js/components/ui-components/callout.js +121 -0
  125. package/framework/js/components/ui-components/carousel.js +145 -0
  126. package/framework/js/components/ui-components/checkbox-group.js +87 -0
  127. package/framework/js/components/ui-components/checklist.js +40 -0
  128. package/framework/js/components/ui-components/collapse.js +114 -0
  129. package/framework/js/components/ui-components/comparison.js +30 -0
  130. package/framework/js/components/ui-components/conditional-display.js +150 -0
  131. package/framework/js/components/ui-components/content-image.js +41 -0
  132. package/framework/js/components/ui-components/dropdown.js +262 -0
  133. package/framework/js/components/ui-components/embed-frame.js +274 -0
  134. package/framework/js/components/ui-components/features.js +33 -0
  135. package/framework/js/components/ui-components/flip-card.js +230 -0
  136. package/framework/js/components/ui-components/form-validator.js +76 -0
  137. package/framework/js/components/ui-components/hero.js +49 -0
  138. package/framework/js/components/ui-components/index.js +12 -0
  139. package/framework/js/components/ui-components/interactive-image.js +235 -0
  140. package/framework/js/components/ui-components/interactive-timeline.js +285 -0
  141. package/framework/js/components/ui-components/intro-cards.js +35 -0
  142. package/framework/js/components/ui-components/lightbox.js +652 -0
  143. package/framework/js/components/ui-components/modal.js +386 -0
  144. package/framework/js/components/ui-components/notifications.js +145 -0
  145. package/framework/js/components/ui-components/progress.js +88 -0
  146. package/framework/js/components/ui-components/quote.js +41 -0
  147. package/framework/js/components/ui-components/stats.js +33 -0
  148. package/framework/js/components/ui-components/steps.js +41 -0
  149. package/framework/js/components/ui-components/tabs.js +255 -0
  150. package/framework/js/components/ui-components/timeline.js +42 -0
  151. package/framework/js/components/ui-components/toggle-group.js +73 -0
  152. package/framework/js/components/ui-components/tooltip.js +458 -0
  153. package/framework/js/components/ui-components/value-display.js +133 -0
  154. package/framework/js/components/ui-components/video-player.js +686 -0
  155. package/framework/js/core/component-catalog.js +121 -0
  156. package/framework/js/core/event-bus.js +178 -0
  157. package/framework/js/core/interaction-catalog.js +149 -0
  158. package/framework/js/dev/runtime-linter.js +1725 -0
  159. package/framework/js/drivers/cmi5-driver.js +768 -0
  160. package/framework/js/drivers/driver-factory.js +77 -0
  161. package/framework/js/drivers/driver-interface.js +110 -0
  162. package/framework/js/drivers/http-driver-base.js +241 -0
  163. package/framework/js/drivers/lti-driver.js +508 -0
  164. package/framework/js/drivers/proxy-driver.js +444 -0
  165. package/framework/js/drivers/scorm-12-driver.js +560 -0
  166. package/framework/js/drivers/scorm-2004-driver.js +775 -0
  167. package/framework/js/drivers/scorm-driver-base.js +112 -0
  168. package/framework/js/engagement/engagement-manager.js +404 -0
  169. package/framework/js/engagement/engagement-progress.js +191 -0
  170. package/framework/js/engagement/engagement-trackers.js +215 -0
  171. package/framework/js/engagement/requirement-strategies.js +268 -0
  172. package/framework/js/main.js +727 -0
  173. package/framework/js/managers/accessibility-manager.js +499 -0
  174. package/framework/js/managers/assessment-manager.js +230 -0
  175. package/framework/js/managers/audio-manager.js +944 -0
  176. package/framework/js/managers/comment-manager.js +88 -0
  177. package/framework/js/managers/flag-manager.js +86 -0
  178. package/framework/js/managers/interaction-manager.js +254 -0
  179. package/framework/js/managers/interaction-registry.js +96 -0
  180. package/framework/js/managers/objective-manager.js +423 -0
  181. package/framework/js/managers/score-manager.js +441 -0
  182. package/framework/js/managers/video-manager.js +536 -0
  183. package/framework/js/navigation/Breadcrumbs.js +234 -0
  184. package/framework/js/navigation/NavigationActions.js +1132 -0
  185. package/framework/js/navigation/NavigationState.js +276 -0
  186. package/framework/js/navigation/NavigationUI.js +574 -0
  187. package/framework/js/navigation/document-gallery.js +357 -0
  188. package/framework/js/navigation/navigation-helpers.js +175 -0
  189. package/framework/js/navigation/navigation-validators.js +174 -0
  190. package/framework/js/state/index.js +8 -0
  191. package/framework/js/state/lms-connection.js +482 -0
  192. package/framework/js/state/lms-error-utils.js +58 -0
  193. package/framework/js/state/state-commits.js +200 -0
  194. package/framework/js/state/state-domains.js +86 -0
  195. package/framework/js/state/state-manager.js +502 -0
  196. package/framework/js/state/state-validation.js +311 -0
  197. package/framework/js/state/transaction-log.js +41 -0
  198. package/framework/js/state/xapi-statement-service.js +325 -0
  199. package/framework/js/utilities/access-control.js +99 -0
  200. package/framework/js/utilities/breakpoint-manager.js +315 -0
  201. package/framework/js/utilities/canvas-slide.js +35 -0
  202. package/framework/js/utilities/conditional-display.js +388 -0
  203. package/framework/js/utilities/course-channel.js +214 -0
  204. package/framework/js/utilities/course-helpers.js +420 -0
  205. package/framework/js/utilities/data-reporter.js +273 -0
  206. package/framework/js/utilities/error-reporter.js +313 -0
  207. package/framework/js/utilities/hotspot-helper.js +341 -0
  208. package/framework/js/utilities/icons.js +348 -0
  209. package/framework/js/utilities/logger.js +92 -0
  210. package/framework/js/utilities/markdown-renderer.js +45 -0
  211. package/framework/js/utilities/scroll-tracker.js +68 -0
  212. package/framework/js/utilities/ui-initializer.js +146 -0
  213. package/framework/js/utilities/utilities.js +293 -0
  214. package/framework/js/utilities/view-manager.js +227 -0
  215. package/framework/js/validation/html-validators.js +422 -0
  216. package/framework/js/validation/scorm-validators.js +438 -0
  217. package/framework/js/vendor/pipwerks.js +931 -0
  218. package/framework/scripts/generate-narration.js +629 -0
  219. package/framework/scripts/tts-providers/azure-provider.js +178 -0
  220. package/framework/scripts/tts-providers/base-provider.js +81 -0
  221. package/framework/scripts/tts-providers/deepgram-provider.js +135 -0
  222. package/framework/scripts/tts-providers/elevenlabs-provider.js +148 -0
  223. package/framework/scripts/tts-providers/google-provider.js +272 -0
  224. package/framework/scripts/tts-providers/index.js +158 -0
  225. package/framework/scripts/tts-providers/openai-provider.js +143 -0
  226. package/framework/version.json +63 -0
  227. package/lib/authoring-api.js +919 -0
  228. package/lib/build-linter.js +450 -0
  229. package/lib/build-packaging.js +186 -0
  230. package/lib/build.js +88 -0
  231. package/lib/cloud.js +691 -0
  232. package/lib/convert.js +341 -0
  233. package/lib/course-parser.js +936 -0
  234. package/lib/course-writer.js +258 -0
  235. package/lib/create.js +248 -0
  236. package/lib/css-index.js +237 -0
  237. package/lib/dev.js +51 -0
  238. package/lib/export-content.js +1246 -0
  239. package/lib/headless-browser.js +413 -0
  240. package/lib/import.js +377 -0
  241. package/lib/index.js +80 -0
  242. package/lib/info.js +79 -0
  243. package/lib/interaction-formatters.js +568 -0
  244. package/lib/manifest/cmi5-manifest.js +63 -0
  245. package/lib/manifest/lti-tool-config.js +53 -0
  246. package/lib/manifest/manifest-factory.js +99 -0
  247. package/lib/manifest/scorm-12-manifest.js +61 -0
  248. package/lib/manifest/scorm-2004-manifest.js +94 -0
  249. package/lib/manifest/scorm-proxy-manifest.js +104 -0
  250. package/lib/manifest-parser.js +96 -0
  251. package/lib/mcp-prompts.js +753 -0
  252. package/lib/mcp-server.js +316 -0
  253. package/lib/narration.js +53 -0
  254. package/lib/pdf-structure.js +142 -0
  255. package/lib/preview-export.js +231 -0
  256. package/lib/preview-routes-api.js +662 -0
  257. package/lib/preview-routes-editing.js +159 -0
  258. package/lib/preview-routes-lms.js +230 -0
  259. package/lib/preview-server.js +564 -0
  260. package/lib/project-utils.js +269 -0
  261. package/lib/proxy-templates/proxy.html +68 -0
  262. package/lib/proxy-templates/scorm-bridge.js +112 -0
  263. package/lib/scaffold.js +193 -0
  264. package/lib/schema-extractor.js +361 -0
  265. package/lib/slide-source-editor.js +586 -0
  266. package/lib/stub-player/app-viewer.js +195 -0
  267. package/lib/stub-player/app.js +370 -0
  268. package/lib/stub-player/catalog-panel.js +312 -0
  269. package/lib/stub-player/config-panel.js +1303 -0
  270. package/lib/stub-player/content-generator.js +586 -0
  271. package/lib/stub-player/content-viewer.js +173 -0
  272. package/lib/stub-player/debug-panel.js +420 -0
  273. package/lib/stub-player/edit-mode.js +922 -0
  274. package/lib/stub-player/edit-utils.js +400 -0
  275. package/lib/stub-player/header-bar.js +354 -0
  276. package/lib/stub-player/interaction-editor.js +210 -0
  277. package/lib/stub-player/interactions-panel.js +565 -0
  278. package/lib/stub-player/lms-api.js +1094 -0
  279. package/lib/stub-player/login-screen.js +74 -0
  280. package/lib/stub-player/outline-mode.js +689 -0
  281. package/lib/stub-player/styles/_assessments-panel.css +245 -0
  282. package/lib/stub-player/styles/_base.css +89 -0
  283. package/lib/stub-player/styles/_catalog-icons.css +96 -0
  284. package/lib/stub-player/styles/_catalog-panel.css +291 -0
  285. package/lib/stub-player/styles/_config-panel.css +636 -0
  286. package/lib/stub-player/styles/_content-viewer.css +834 -0
  287. package/lib/stub-player/styles/_debug-panel.css +576 -0
  288. package/lib/stub-player/styles/_edit-mode.css +128 -0
  289. package/lib/stub-player/styles/_header-bar.css +343 -0
  290. package/lib/stub-player/styles/_interaction-editor.css +140 -0
  291. package/lib/stub-player/styles/_interactions-panel.css +1038 -0
  292. package/lib/stub-player/styles/_login-screen.css +102 -0
  293. package/lib/stub-player/styles/_outline-mode.css +752 -0
  294. package/lib/stub-player/styles.css +15 -0
  295. package/lib/stub-player.js +160 -0
  296. package/lib/test-data-reporting.js +176 -0
  297. package/lib/test-error-reporting.js +146 -0
  298. package/lib/token.js +86 -0
  299. package/lib/upgrade.js +257 -0
  300. package/lib/validation-rules.js +517 -0
  301. package/lib/vite-plugin-content-discovery.js +296 -0
  302. package/package.json +108 -0
  303. package/schemas/XMLSchema.dtd +402 -0
  304. package/schemas/adlcp_v1p3.xsd +111 -0
  305. package/schemas/adlnav_v1p3.xsd +61 -0
  306. package/schemas/adlseq_v1p3.xsd +93 -0
  307. package/schemas/common/anyElement.xsd +27 -0
  308. package/schemas/common/dataTypes.xsd +138 -0
  309. package/schemas/common/elementNames.xsd +767 -0
  310. package/schemas/common/elementTypes.xsd +786 -0
  311. package/schemas/common/rootElement.xsd +31 -0
  312. package/schemas/common/vocabTypes.xsd +345 -0
  313. package/schemas/common/vocabValues.xsd +257 -0
  314. package/schemas/datatypes.dtd +203 -0
  315. package/schemas/ims_xml.xsd +35 -0
  316. package/schemas/imscp_v1p1.xsd +368 -0
  317. package/schemas/imsss_v1p0.xsd +67 -0
  318. package/schemas/imsss_v1p0auxresource.xsd +19 -0
  319. package/schemas/imsss_v1p0control.xsd +20 -0
  320. package/schemas/imsss_v1p0delivery.xsd +17 -0
  321. package/schemas/imsss_v1p0limit.xsd +47 -0
  322. package/schemas/imsss_v1p0objective.xsd +67 -0
  323. package/schemas/imsss_v1p0random.xsd +16 -0
  324. package/schemas/imsss_v1p0rollup.xsd +46 -0
  325. package/schemas/imsss_v1p0seqrule.xsd +108 -0
  326. package/schemas/imsss_v1p0util.xsd +94 -0
  327. package/schemas/license.txt +17 -0
  328. package/schemas/lom.xsd +102 -0
  329. package/schemas/lomCustom.xsd +62 -0
  330. package/schemas/lomLoose.xsd +62 -0
  331. package/schemas/lomStrict.xsd +62 -0
  332. package/schemas/xml.xsd +81 -0
  333. package/template/.env.example +92 -0
  334. package/template/course/assets/audio/example-intro.mp3 +0 -0
  335. package/template/course/assets/audio/example-ui-demo--compact-player.mp3 +0 -0
  336. package/template/course/assets/audio/example-ui-demo--demo-modal.mp3 +0 -0
  337. package/template/course/assets/audio/example-ui-demo--full-player.mp3 +0 -0
  338. package/template/course/assets/docs/example_md_1.md +39 -0
  339. package/template/course/assets/docs/example_md_2.md +41 -0
  340. package/template/course/assets/docs/example_pdf_1_thumbnail.png +0 -0
  341. package/template/course/assets/docs/example_pdf_2.pdf +0 -0
  342. package/template/course/assets/images/course-architecture.svg +36 -0
  343. package/template/course/assets/images/logo.svg +14 -0
  344. package/template/course/assets/widgets/counter-demo.html +190 -0
  345. package/template/course/assets/widgets/gravity-painter.html +384 -0
  346. package/template/course/course-config.js +539 -0
  347. package/template/course/icons.js +19 -0
  348. package/template/course/interactions/PLUGIN_GUIDE.md +97 -0
  349. package/template/course/slides/example-course-structure.js +138 -0
  350. package/template/course/slides/example-final-exam.js +144 -0
  351. package/template/course/slides/example-finishing.js +127 -0
  352. package/template/course/slides/example-interactions-showcase.js +615 -0
  353. package/template/course/slides/example-preview-tour.js +129 -0
  354. package/template/course/slides/example-remedial.js +143 -0
  355. package/template/course/slides/example-summary.js +103 -0
  356. package/template/course/slides/example-ui-showcase.js +1805 -0
  357. package/template/course/slides/example-welcome.js +123 -0
  358. package/template/course/slides/example-workflow.js +140 -0
  359. package/template/course/theme.css +165 -0
  360. package/template/eslint.config.js +47 -0
  361. package/template/package.json +28 -0
  362. package/template/vite.config.js +339 -0
@@ -0,0 +1,161 @@
1
+ # [Course Title]
2
+
3
+ > **Intended Audience: AI Agents** — This is a machine-readable template for AI agents. For human-readable documentation, see `USER_GUIDE.md`.
4
+
5
+ * **Course ID:** `[COURSE-ID]`
6
+ * **Target Audience:** `[Audience]`
7
+ * **Estimated Duration:** `[X] minutes`
8
+ * **Layout Type:** `traditional` | `article` | `focused` | `presentation` | `canvas`
9
+ * **Architecture:** `Single-SCO`
10
+ * **Key Learning Objectives:** `[Human-readable objective 1]`, `[Objective 2]`, `[Objective 3]`
11
+
12
+ ---
13
+
14
+ ## 1. Course Overview & Strategy
15
+
16
+ *This section defines the high-level architecture, scoring, and success criteria.*
17
+
18
+ ### A. Completion & Success Rules
19
+
20
+ * **Completion:** [e.g., "Must view all slides and pass Final Exam"]
21
+ * **Success:** [e.g., "Final Exam score >= 80%"]
22
+ * **Scoring Strategy:** [e.g., "Weighted: Final Exam (100%)" or "Average of all quizzes"]
23
+
24
+ ### B. Objectives & Tracking Logic
25
+
26
+ *Defines the SCORM objectives used for tracking. Maps to `course-config.js`.*
27
+
28
+ | ID | Description | Criteria Type | Details |
29
+ |---|---|---|---|
30
+ | `obj-intro` | Completed introduction | `slideVisited` | `slide-01` |
31
+ | `obj-core` | Reviewed core content | `allSlidesVisited` | `[slide-02, slide-03]` |
32
+ | `obj-exam` | Passed Final Exam | `Manual` | Set by `assess-final` |
33
+
34
+ ---
35
+
36
+ ## 2. Content Structure (High-Level)
37
+
38
+ *Master table of contents showing flow, gating, and logic.*
39
+
40
+ * **Module 1: Introduction**
41
+ * `slide-01`: [Welcome]
42
+ * **Module 2: Core Concepts** (`Gate:` Requires `obj-intro`)
43
+ * `slide-02`: [Concept A]
44
+ * `slide-03`: [Concept B]
45
+ * **Module 3: Assessment**
46
+ * `assess-final`: [Final Exam]
47
+
48
+ ---
49
+
50
+ ## 3. Slide-by-Slide Breakdown
51
+
52
+ *Detailed specification for every slide. This is the blueprint for development.*
53
+
54
+ ### Module 1: Introduction
55
+
56
+ #### `slide-01`: [Title]
57
+
58
+ **Visual Concept:**
59
+
60
+ [Describe the layout, imagery, and visual hierarchy. E.g., "Split screen: Left side has a welcome video placeholder, Right side has the course title and start button."]
61
+
62
+ **Content:**
63
+
64
+ * **Heading:** [H1 Title]
65
+ * **Body:**
66
+ * [Paragraph 1 text...]
67
+ * [Bullet points...]
68
+ * **UI Elements:**
69
+ * Button: "Start Course"
70
+
71
+ **Narration:** (if audio is used)
72
+
73
+ > [Narration script that complements—not duplicates—on-screen content. Expand on key points, provide context, or guide attention rather than reading text verbatim.]
74
+
75
+ **Navigation & Tracking:**
76
+
77
+ * **Nav:** Next button unlocks after media completes.
78
+ * **Track:** `slideVisited` (completes `obj-intro`).
79
+
80
+ ---
81
+
82
+ ### Module 2: Core Concepts
83
+
84
+ #### `slide-02`: [Title]
85
+
86
+ **Visual Concept:**
87
+
88
+ [E.g., "Interactive Accordion. Three collapsible sections labeled 'Plan', 'Do', 'Check'."]
89
+
90
+ **Content:**
91
+
92
+ * **Intro Text:** Click each step to learn more.
93
+ * **Accordion Item 1 (Plan):** [Content for item 1]
94
+ * **Accordion Item 2 (Do):** [Content for item 2]
95
+ * **Accordion Item 3 (Check):** [Content for item 3]
96
+
97
+ **Interactions:**
98
+
99
+ * **Type:** Accordion
100
+ * **Behavior:** User must click all 3 items to proceed.
101
+
102
+ **Navigation & Tracking:**
103
+
104
+ * **Engagement:** `viewAllTabs` required to unlock Next button.
105
+
106
+ ---
107
+
108
+ #### `slide-03`: [Practice Scenario]
109
+
110
+ **Visual Concept:**
111
+
112
+ [E.g., "Scenario Layout. Context text on top, multiple choice question below."]
113
+
114
+ **Content:**
115
+
116
+ * **Scenario:** [Context paragraph...]
117
+ * **Question:** [Question text]
118
+ * **Options:**
119
+ * A) [Text]
120
+ * B) [Text] (Correct)
121
+ * C) [Text]
122
+ * **Feedback:**
123
+ * **Correct:** [Text]
124
+ * **Incorrect:** [Text]
125
+
126
+ **Interactions:**
127
+
128
+ * **Type:** Multiple Choice (Practice)
129
+ * **ID:** `practice-01`
130
+
131
+ **Navigation & Tracking:**
132
+
133
+ * **Track:** Contributes to `obj-core`.
134
+
135
+ ---
136
+
137
+ ### Module 3: Assessment
138
+
139
+ #### `assess-final`: [Final Exam]
140
+
141
+ **Strategy:**
142
+
143
+ * **Pool:** Select 10 questions from a bank of 15.
144
+ * **Pass Score:** 80%
145
+ * **Retries:** 2 attempts allowed.
146
+
147
+ **Question Bank:**
148
+
149
+ **Q1** (`q1-id`): [Question Text]
150
+
151
+ * **Type:** Multiple Choice
152
+ * **Options:** A) [Text], B) [Text] (Correct)
153
+ * **Feedback:** [Explain why]
154
+
155
+ **Q2** (`q2-id`): [Question Text]
156
+
157
+ * **Type:** True/False
158
+ * **Correct:** True
159
+ * **Feedback:** [Explain why]
160
+
161
+ ... *(continue for all questions)* ...
@@ -0,0 +1,409 @@
1
+ # CourseCode Data Model Reference
2
+
3
+ > **Intended Audience: AI Agents** — This document is a machine-readable data model reference for AI agents. For human-readable documentation, see `USER_GUIDE.md`.
4
+
5
+ Complete reference for all learner data managed by the framework. The framework uses a **domain-based state model** that is transport-agnostic — the same domains exist regardless of whether the delivery format is SCORM 1.2, SCORM 2004, cmi5, or LTI. The state module ([state/](../js/state/)) routes each domain to the appropriate storage mechanism.
6
+
7
+ > [!TIP]
8
+ > **For framework internals** (drivers, managers, architecture), see [`FRAMEWORK_GUIDE.md`](./FRAMEWORK_GUIDE.md).
9
+
10
+ ---
11
+
12
+ ## Storage Architecture
13
+
14
+ ```mermaid
15
+ graph TD
16
+ subgraph "Framework Domains (suspend_data)"
17
+ META["_meta"]
18
+ NAV["navigation"]
19
+ ENG["engagement"]
20
+ IR["interactionResponses"]
21
+ ASSESS["assessment_*"]
22
+ FLAGS["flags"]
23
+ SESSION["sessionData"]
24
+ A11Y["accessibility"]
25
+ AUDIO["audio"]
26
+ VIDEO["video"]
27
+ end
28
+
29
+ subgraph "CMI-Backed Domains (SCORM only)"
30
+ OBJ["objectives"]
31
+ INT["interactions"]
32
+ end
33
+
34
+ subgraph "Direct CMI Writes"
35
+ SCORE["cmi.score.*"]
36
+ COMP["cmi.completion_status"]
37
+ SUCC["cmi.success_status"]
38
+ PROG["cmi.progress_measure"]
39
+ LOC["cmi.location"]
40
+ EXIT["cmi.exit"]
41
+ SESSTIME["cmi.session_time"]
42
+ COMMENTS["cmi.comments_from_learner.*"]
43
+ end
44
+
45
+ SD["suspend_data (JSON blob)"]
46
+
47
+ META & NAV & ENG & IR & ASSESS & FLAGS & SESSION & A11Y & AUDIO & VIDEO --> SD
48
+ OBJ -->|"SCORM: cmi.objectives.*"| CMI["CMI Data Model"]
49
+ OBJ -->|"cmi5/LTI: suspend_data"| SD
50
+ INT -->|"SCORM: cmi.interactions.*"| CMI
51
+ INT -->|"cmi5/LTI: suspend_data"| SD
52
+ ```
53
+
54
+ ### Per-Format Routing
55
+
56
+ | Storage | SCORM 1.2 / 2004 | cmi5 | LTI |
57
+ |---------|-------------------|------|-----|
58
+ | `suspend_data` domains | ✅ | ✅ | ✅ (host provides) |
59
+ | CMI-backed `objectives` | `cmi.objectives.*` | suspend_data | suspend_data |
60
+ | CMI-backed `interactions` | `cmi.interactions.*` (append-only) | suspend_data | suspend_data |
61
+ | Direct CMI writes | ✅ | Via xAPI statements | Score via LTI AGS |
62
+ | `cmi.location` | ✅ | ✅ (suspend_data key) | ✅ (host provides) |
63
+
64
+ ---
65
+
66
+ ## Access Pattern
67
+
68
+ All state access flows through `stateManager` — the sole public API from the [state/](../js/state/) module:
69
+
70
+ ```javascript
71
+ import stateManager from '../state/index.js';
72
+
73
+ // Read/write domain state
74
+ stateManager.getDomainState('navigation');
75
+ stateManager.setDomainState('navigation', { visitedSlides: ['intro', 'slide-01'] });
76
+
77
+ // Semantic LMS operations (delegated to the driver internally)
78
+ stateManager.reportScore({ raw: 85, scaled: 0.85, min: 0, max: 100 });
79
+ stateManager.reportCompletion('completed');
80
+ stateManager.setBookmark('slide-03');
81
+ stateManager.flush(); // Force immediate commit
82
+ ```
83
+
84
+ > [!IMPORTANT]
85
+ > **Never import `lms-connection.js` or driver modules directly.** All LMS communication flows through `stateManager`.
86
+
87
+ ---
88
+
89
+ ## Domain Schemas
90
+
91
+ ### `_meta`
92
+
93
+ Internal metadata for state versioning. Managed by [state-validation.js](../js/state/state-validation.js).
94
+
95
+ ```js
96
+ {
97
+ schemaVersion: number, // e.g. 1 — used for state migration on course updates
98
+ createdAt: string, // ISO 8601 timestamp
99
+ lastValidatedAt?: string // Set after validation against course structure
100
+ }
101
+ ```
102
+
103
+ ---
104
+
105
+ ### `navigation`
106
+
107
+ Slide visit tracking. Managed by [NavigationState.js](../js/navigation/NavigationState.js).
108
+
109
+ ```js
110
+ {
111
+ visitedSlides: string[] // Array of slide IDs the learner has visited
112
+ }
113
+ ```
114
+
115
+ > `currentSlideIndex` is runtime-only (not persisted). `cmi.location` is the authoritative bookmark.
116
+
117
+ ---
118
+
119
+ ### `engagement`
120
+
121
+ Engagement tracking for navigation gating. Managed by [engagement-manager.js](../js/managers/engagement-manager.js).
122
+
123
+ ```js
124
+ {
125
+ [slideId: string]: {
126
+ required: boolean,
127
+ complete: boolean,
128
+ tracked: {
129
+ tabsViewed: string[],
130
+ tabsTotal: number,
131
+ accordionPanelsViewed: string[],
132
+ accordionPanelsTotal: number,
133
+ flipCardsViewed: string[],
134
+ flipCardsTotal: number,
135
+ flipCardsRegistered: string[],
136
+ interactiveImageHotspotsViewed: string[],
137
+ interactiveImageHotspotsTotal: number,
138
+ modalsViewed: string[],
139
+ modalsTotal: number,
140
+ modalsAudioComplete: string[],
141
+ lightboxesViewed: string[],
142
+ lightboxesTotal: number,
143
+ timelineEventsViewed: string[],
144
+ timelineEventsTotal: number,
145
+ interactionsCompleted: { [interactionId: string]: { completed: boolean, correct: boolean } },
146
+ scrollDepth: number, // 0-100
147
+ audioComplete: boolean, // Slide-level audio
148
+ standaloneAudioComplete: string[],
149
+ videoComplete: boolean, // Slide-level video
150
+ standaloneVideoComplete: string[]
151
+ }
152
+ }
153
+ }
154
+ ```
155
+
156
+ > Only slides with `engagement.required = true` in the course config get state entries. Non-required slides are skipped to save space.
157
+
158
+ ---
159
+
160
+ ### `interactionResponses`
161
+
162
+ Learner responses for standalone interactions (outside assessments). Managed by [interaction-base.js](../js/components/interactions/interaction-base.js).
163
+
164
+ ```js
165
+ {
166
+ [interactionId: string]: {
167
+ response: any, // Format depends on interaction type
168
+ submitted: boolean // Whether the learner has submitted (clicked Check)
169
+ }
170
+ }
171
+ ```
172
+
173
+ #### Dual Storage Pattern
174
+
175
+ Standalone interactions use two storage mechanisms:
176
+
177
+ | Storage | Domain | Purpose | Pattern |
178
+ |---------|--------|---------|---------|
179
+ | `cmi.interactions.n.*` | `interactions` | LMS reporting, audit trail | Append-only (each Check = new record) |
180
+ | `suspend_data` | `interactionResponses` | UI state restoration | Key-value (latest state only) |
181
+
182
+ **Why?** CMI interactions are append-only by spec — same ID appears multiple times (one per attempt). Can't use CMI for restoration, so `interactionResponses` stores `{ response, submitted }` for O(1) lookup.
183
+
184
+ ---
185
+
186
+ ### `assessment_${assessmentId}`
187
+
188
+ Per-assessment state. Each assessment gets its own domain (e.g. `assessment_final-exam`). Managed by [AssessmentState.js](../js/assessment/AssessmentState.js).
189
+
190
+ ```js
191
+ {
192
+ summary: {
193
+ attempts: number,
194
+ passed: boolean,
195
+ lastResults: {
196
+ scorePercentage: number, // 0-100
197
+ scoreRaw: number,
198
+ scoreMax: number,
199
+ passed: boolean,
200
+ correctCount: number,
201
+ incorrectCount: number,
202
+ totalQuestions: number
203
+ }
204
+ },
205
+ session: {
206
+ currentView: string, // 'instructions' | 'question' | 'results' | 'review'
207
+ currentQuestionIndex: number,
208
+ startTime: number, // Date.now() timestamp
209
+ submitted: boolean,
210
+ attemptNumber: number,
211
+ responses: { [questionId: string]: any },
212
+ selectedQuestions: string[], // Question IDs (may be randomized subset)
213
+ reviewReached: boolean
214
+ },
215
+ discardedAttempts: any[] // Previous attempt data kept for audit
216
+ }
217
+ ```
218
+
219
+ ---
220
+
221
+ ### `flags`
222
+
223
+ Arbitrary key-value flags for custom course logic. Managed by [flag-manager.js](../js/managers/flag-manager.js).
224
+
225
+ ```js
226
+ {
227
+ [key: string]: any // Boolean, string, number — any serializable value
228
+ }
229
+ ```
230
+
231
+ ---
232
+
233
+ ### `sessionData`
234
+
235
+ Slide timing data. Managed by [AppActions.js](../js/app/AppActions.js).
236
+
237
+ ```js
238
+ {
239
+ slideStartTimes: { [slideId: string]: number }, // Date.now() timestamps
240
+ slideDurations: { [slideId: string]: number } // Accumulated milliseconds
241
+ }
242
+ ```
243
+
244
+ ---
245
+
246
+ ### `accessibility`
247
+
248
+ Learner accessibility preferences. Managed by [accessibility-manager.js](../js/managers/accessibility-manager.js).
249
+
250
+ ```js
251
+ {
252
+ theme: 'light' | 'dark',
253
+ fontSize: 'normal' | 'large',
254
+ highContrast: boolean,
255
+ reducedMotion: boolean
256
+ }
257
+ ```
258
+
259
+ ---
260
+
261
+ ### `audio`
262
+
263
+ Audio playback state. Managed by [audio-manager.js](../js/managers/audio-manager.js).
264
+
265
+ ```js
266
+ {
267
+ positions: { [contextId: string]: number }, // Playback position in seconds
268
+ completions: { [contextId: string]: boolean }, // Whether audio has been completed
269
+ muted: boolean // Learner's mute preference
270
+ }
271
+ ```
272
+
273
+ ---
274
+
275
+ ### `video`
276
+
277
+ Video playback state. Managed by [video-manager.js](../js/managers/video-manager.js).
278
+
279
+ ```js
280
+ {
281
+ positions: { [contextId: string]: number }, // Playback position in seconds
282
+ completions: { [contextId: string]: boolean }, // Whether video has been completed
283
+ isMuted: boolean // Learner's mute preference
284
+ }
285
+ ```
286
+
287
+ ---
288
+
289
+ ### `objectives` (CMI-backed)
290
+
291
+ Learning objectives. Managed by [objective-manager.js](../js/managers/objective-manager.js). Routed to `cmi.objectives.*` on SCORM, or `suspend_data` on cmi5/LTI.
292
+
293
+ ```js
294
+ {
295
+ [objectiveId: string]: {
296
+ id: string,
297
+ completion_status: 'completed' | 'incomplete',
298
+ success_status: 'passed' | 'failed' | 'unknown',
299
+ score: number | null // 0-100
300
+ }
301
+ }
302
+ ```
303
+
304
+ ---
305
+
306
+ ### `interactions` (CMI-backed)
307
+
308
+ Interaction records for LMS reporting. Managed by [interaction-manager.js](../js/managers/interaction-manager.js). **Append-only** on SCORM (`cmi.interactions.*`), or in `suspend_data` on cmi5/LTI.
309
+
310
+ ```js
311
+ {
312
+ id: string,
313
+ type: string, // 'choice' | 'true-false' | 'fill-in' | 'matching' | 'sequencing' | 'numeric' | 'other'
314
+ learner_response: string, // SCORM wire format ([,] delimiters, [.] pair separators)
315
+ result: string, // 'correct' | 'incorrect' | 'neutral'
316
+ timestamp: string, // ISO 8601
317
+ correct_responses?: string,
318
+ latency?: string,
319
+ description?: string,
320
+ weighting?: number
321
+ }
322
+ ```
323
+
324
+ ---
325
+
326
+ ## Direct CMI Writes
327
+
328
+ These are written directly by `stateManager` semantic methods and are **not** part of domain state. They flow through the driver to the LMS.
329
+
330
+ | CMI Key | Written By | Value | Notes |
331
+ |---------|-----------|-------|-------|
332
+ | `cmi.score.raw` | `stateManager.reportScore()` | `0` – `100` | Via [score-manager.js](../js/managers/score-manager.js) |
333
+ | `cmi.score.scaled` | `stateManager.reportScore()` | `0` – `1` | raw / 100 |
334
+ | `cmi.score.min` | `stateManager.reportScore()` | `0` | Always 0 |
335
+ | `cmi.score.max` | `stateManager.reportScore()` | `100` | Always 100 |
336
+ | `cmi.completion_status` | `stateManager.reportCompletion()` | `completed` / `incomplete` | |
337
+ | `cmi.success_status` | `stateManager.reportSuccess()` | `passed` / `failed` / `unknown` | |
338
+ | `cmi.progress_measure` | `stateManager.updateProgressMeasure()` | `0` – `1` | Fraction of slides visited |
339
+ | `cmi.location` | `stateManager.setBookmark()` | Slide ID string | Authoritative bookmark |
340
+ | `cmi.exit` | `stateManager.exitCourseWithSuspend()` | `suspend` / `normal` | Set on exit |
341
+ | `cmi.session_time` | `stateManager.terminate()` | ISO 8601 duration | Calculated on terminate |
342
+ | `cmi.comments_from_learner.*` | [comment-manager.js](../js/managers/comment-manager.js) | Comment text + timestamp | Append-only |
343
+
344
+ ---
345
+
346
+ ## suspend_data Serialization
347
+
348
+ All domain states combine into a single JSON object stored in `cmi.suspend_data`:
349
+
350
+ ```js
351
+ {
352
+ _meta: { schemaVersion: 1, createdAt: '2026-...' },
353
+ navigation: { visitedSlides: [...] },
354
+ engagement: { ... },
355
+ interactionResponses: { ... },
356
+ assessment_quiz1: { ... },
357
+ flags: { ... },
358
+ sessionData: { ... },
359
+ accessibility: { ... },
360
+ audio: { ... },
361
+ video: { ... },
362
+ // cmi5/LTI only (SCORM uses CMI arrays):
363
+ objectives: { ... },
364
+ interactions: { ... }
365
+ }
366
+ ```
367
+
368
+ > [!NOTE]
369
+ > **Compression:** `cmi.suspend_data` is automatically compressed via `lz-string` (UTF16) in the driver layer. This is transparent to all consumers.
370
+
371
+ > [!NOTE]
372
+ > For SCORM, `objectives` and `interactions` are stored in CMI arrays and **not** included in `suspend_data`. For cmi5 and LTI, they are included since those formats don't support CMI data model arrays.
373
+
374
+ ---
375
+
376
+ ## Write Batching
377
+
378
+ LMS writes are auto-batched with a 500ms debounce. Rapid `setDomainState` calls within this window combine into a single commit.
379
+
380
+ ```javascript
381
+ // These writes auto-batch into 1 commit
382
+ stateManager.setDomainState('navigation', navState);
383
+ stateManager.setDomainState('engagement', engState);
384
+ // → Single commit fires after 500ms idle
385
+
386
+ // Force immediate commit for critical paths
387
+ stateManager.flush();
388
+ ```
389
+
390
+ **Critical actions** (exit, terminate) automatically flush pending writes before proceeding.
391
+
392
+ ---
393
+
394
+ ## State Validation & Migration
395
+
396
+ Handles LMS data mismatches when course structure changes after learners have started:
397
+
398
+ | Behavior | Dev Mode | Prod Mode |
399
+ |----------|----------|----------|
400
+ | Orphaned slide in navigation | Warns + filters | Silently removes |
401
+ | Orphaned engagement data | Warns | Silently removes |
402
+ | Schema version newer (downgrade) | Throws error | Resets to fresh state |
403
+ | Schema version older (upgrade) | Runs migrations | Runs migrations |
404
+
405
+ **Setup:** `stateManager.setCourseValidationConfig(config)` called in `main.js` before `initialize()`.
406
+
407
+ **Schema versioning:** `STATE_SCHEMA_VERSION` in [state-validation.js](../js/state/state-validation.js). Add migration functions in `STATE_MIGRATIONS` when incrementing.
408
+
409
+ **Event:** `state:recovered` emitted when prod mode gracefully recovers.