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,99 @@
1
+ /**
2
+ * @file manifest-factory.js
3
+ * @description Factory for generating format-specific manifests.
4
+ */
5
+
6
+ import { generateScorm2004Manifest } from './scorm-2004-manifest.js';
7
+ import { generateScorm12Manifest } from './scorm-12-manifest.js';
8
+ import { generateCmi5Manifest } from './cmi5-manifest.js';
9
+ import { generateScorm12ProxyManifest, generateScorm2004ProxyManifest } from './scorm-proxy-manifest.js';
10
+ import { generateLtiToolConfig } from './lti-tool-config.js';
11
+
12
+ /**
13
+ * Generates the appropriate manifest based on format.
14
+ * @param {string} format - 'scorm2004' | 'scorm1.2' | 'cmi5' | 'scorm1.2-proxy' | 'scorm2004-proxy' | 'cmi5-remote' | 'lti'
15
+ * @param {Object} config - Course configuration
16
+ * @param {string[]} files - List of files to include
17
+ * @param {Object} options - Additional options (externalUrl for proxy/remote)
18
+ * @returns {{ filename: string, content: string }} Manifest filename and content
19
+ */
20
+ export function generateManifest(format, config, files, options = {}) {
21
+ switch (format) {
22
+ case 'cmi5':
23
+ return {
24
+ filename: 'cmi5.xml',
25
+ content: generateCmi5Manifest(config, files)
26
+ };
27
+
28
+ case 'cmi5-remote':
29
+ return {
30
+ filename: 'cmi5.xml',
31
+ content: generateCmi5Manifest(config, files, { externalUrl: options.externalUrl })
32
+ };
33
+
34
+ case 'scorm1.2':
35
+ return {
36
+ filename: 'imsmanifest.xml',
37
+ content: generateScorm12Manifest(config, files)
38
+ };
39
+
40
+ case 'scorm1.2-proxy':
41
+ return {
42
+ filename: 'imsmanifest.xml',
43
+ content: generateScorm12ProxyManifest(config)
44
+ };
45
+
46
+ case 'scorm2004-proxy':
47
+ return {
48
+ filename: 'imsmanifest.xml',
49
+ content: generateScorm2004ProxyManifest(config)
50
+ };
51
+
52
+ case 'lti':
53
+ return {
54
+ filename: 'lti-tool-config.json',
55
+ content: generateLtiToolConfig(config, options)
56
+ };
57
+
58
+ case 'scorm2004':
59
+ default:
60
+ return {
61
+ filename: 'imsmanifest.xml',
62
+ content: generateScorm2004Manifest(config, files)
63
+ };
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Gets the schema files needed for the format.
69
+ * @param {string} format - 'scorm2004' | 'scorm1.2' | 'cmi5'
70
+ * @returns {string[]} List of schema file patterns to copy
71
+ */
72
+ export function getSchemaFiles(format) {
73
+ switch (format) {
74
+ case 'cmi5':
75
+ case 'lti':
76
+ // cmi5 and LTI don't require schema files in the package
77
+ return [];
78
+
79
+ case 'scorm1.2':
80
+ // SCORM 1.2 schema files
81
+ return [
82
+ 'imscp_rootv1p1p2.xsd',
83
+ 'adlcp_rootv1p2.xsd',
84
+ 'ims_xml.xsd'
85
+ ];
86
+
87
+ case 'scorm2004':
88
+ default:
89
+ // SCORM 2004 4th Edition schema files
90
+ return [
91
+ 'imscp_v1p1.xsd',
92
+ 'adlcp_v1p3.xsd',
93
+ 'imsss_v1p0.xsd',
94
+ 'adlseq_v1p3.xsd',
95
+ 'adlnav_v1p3.xsd',
96
+ 'lom.xsd'
97
+ ];
98
+ }
99
+ }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * @file scorm-12-manifest.js
3
+ * @description Generates imsmanifest.xml for SCORM 1.2 packages.
4
+ *
5
+ * SCORM 1.2 uses a simpler manifest structure without:
6
+ * - Sequencing rules (imsss namespace)
7
+ * - Navigation controls (adlnav namespace)
8
+ * - 4th Edition schema references
9
+ */
10
+
11
+ /**
12
+ * Generates the SCORM 1.2 manifest.
13
+ * @param {Object} config - Course configuration
14
+ * @param {string[]} files - List of files to include in the manifest
15
+ * @returns {string} The manifest XML
16
+ */
17
+ export function generateScorm12Manifest(config, files) {
18
+ const resourceFiles = files.filter(f =>
19
+ f !== 'imsmanifest.xml' &&
20
+ !f.endsWith('.xsd') &&
21
+ !f.endsWith('.dtd') &&
22
+ !f.startsWith('common/')
23
+ );
24
+
25
+ const fileEntries = resourceFiles.map(f => ` <file href="${f}"/>`).join('\n');
26
+
27
+ // SCORM 1.2 uses ADLCP 1.2 schema and doesn't include sequencing
28
+ return `<?xml version="1.0" encoding="UTF-8"?>
29
+ <!-- SCORM 1.2 manifest - GENERATED FILE - DO NOT EDIT MANUALLY -->
30
+ <manifest identifier="${config.title.replace(/[^a-zA-Z0-9]/g, '-')}"
31
+ version="${config.version}"
32
+ xmlns="http://www.imsproject.org/xsd/imscp_rootv1p1p2"
33
+ xmlns:adlcp="http://www.adlnet.org/xsd/adlcp_rootv1p2"
34
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
35
+ xsi:schemaLocation="
36
+ http://www.imsproject.org/xsd/imscp_rootv1p1p2 imscp_rootv1p1p2.xsd
37
+ http://www.adlnet.org/xsd/adlcp_rootv1p2 adlcp_rootv1p2.xsd">
38
+
39
+ <metadata>
40
+ <schema>ADL SCORM</schema>
41
+ <schemaversion>1.2</schemaversion>
42
+ </metadata>
43
+
44
+ <organizations default="org-1">
45
+ <organization identifier="org-1">
46
+ <title>${config.title}</title>
47
+ <item identifier="item-1" identifierref="res-1" isvisible="true">
48
+ <title>${config.title}</title>
49
+ <adlcp:masteryscore>80</adlcp:masteryscore>
50
+ </item>
51
+ </organization>
52
+ </organizations>
53
+
54
+ <resources>
55
+ <resource identifier="res-1" type="webcontent" adlcp:scormtype="sco" href="index.html">
56
+ ${fileEntries}
57
+ </resource>
58
+ </resources>
59
+ </manifest>
60
+ `;
61
+ }
@@ -0,0 +1,94 @@
1
+ /**
2
+ * @file scorm-2004-manifest.js
3
+ * @description Generates imsmanifest.xml for SCORM 2004 4th Edition packages.
4
+ */
5
+
6
+ /**
7
+ * Generates the SCORM 2004 4th Edition manifest.
8
+ * @param {Object} config - Course configuration
9
+ * @param {string[]} files - List of files to include in the manifest
10
+ * @returns {string} The manifest XML
11
+ */
12
+ export function generateScorm2004Manifest(config, files) {
13
+ const resourceFiles = files.filter(f =>
14
+ f !== 'imsmanifest.xml' &&
15
+ !f.endsWith('.xsd') &&
16
+ !f.endsWith('.dtd') &&
17
+ !f.startsWith('common/')
18
+ );
19
+
20
+ const fileEntries = resourceFiles.map(f => ` <file href="${f}"/>`).join('\n');
21
+
22
+ return `<?xml version="1.0" encoding="UTF-8"?>
23
+ <!-- SCORM 2004 4th Edition manifest - GENERATED FILE - DO NOT EDIT MANUALLY -->
24
+ <manifest identifier="${config.title.replace(/[^a-zA-Z0-9]/g, '-')}"
25
+ version="${config.version}"
26
+ xmlns="http://www.imsglobal.org/xsd/imscp_v1p1"
27
+ xmlns:imscp="http://www.imsglobal.org/xsd/imscp_v1p1"
28
+ xmlns:imsss="http://www.imsglobal.org/xsd/imsss"
29
+ xmlns:adlcp="http://www.adlnet.org/xsd/adlcp_v1p3"
30
+ xmlns:adlseq="http://www.adlnet.org/xsd/adlseq_v1p3"
31
+ xmlns:adlnav="http://www.adlnet.org/xsd/adlnav_v1p3"
32
+ xmlns:lom="http://ltsc.ieee.org/xsd/LOM"
33
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
34
+ xsi:schemaLocation="
35
+ http://www.imsglobal.org/xsd/imscp_v1p1 imscp_v1p1.xsd
36
+ http://www.imsglobal.org/xsd/imsss imsss_v1p0.xsd
37
+ http://www.adlnet.org/xsd/adlcp_v1p3 adlcp_v1p3.xsd
38
+ http://www.adlnet.org/xsd/adlseq_v1p3 adlseq_v1p3.xsd
39
+ http://www.adlnet.org/xsd/adlnav_v1p3 adlnav_v1p3.xsd
40
+ http://ltsc.ieee.org/xsd/LOM lom.xsd"
41
+ xml:base="./">
42
+
43
+ <metadata>
44
+ <schema>ADL SCORM</schema>
45
+ <schemaversion>2004 4th Edition</schemaversion>
46
+ <lom:lom>
47
+ <lom:general>
48
+ <lom:title><lom:string language="${config.language}">${config.title}</lom:string></lom:title>
49
+ <lom:description><lom:string language="${config.language}">${config.description}</lom:string></lom:description>
50
+ <lom:language>${config.language}</lom:language>
51
+ </lom:general>
52
+ <lom:lifecycle>
53
+ <lom:version><lom:string>${config.version}</lom:string></lom:version>
54
+ <lom:contribute>
55
+ <lom:role>
56
+ <lom:source><lom:string>LOMv1.0</lom:string></lom:source>
57
+ <lom:value><lom:string>author</lom:string></lom:value>
58
+ </lom:role>
59
+ <lom:entity>${config.author}</lom:entity>
60
+ </lom:contribute>
61
+ </lom:lifecycle>
62
+ <lom:technical>
63
+ <lom:format>text/html</lom:format>
64
+ </lom:technical>
65
+ </lom:lom>
66
+ </metadata>
67
+
68
+ <organizations default="org-1">
69
+ <organization identifier="org-1" adlseq:objectivesGlobalToSystem="false">
70
+ <title>${config.title}</title>
71
+ <item identifier="item-1" identifierref="res-1" isvisible="true">
72
+ <title>${config.title}</title>
73
+ <imsss:sequencing>
74
+ <imsss:controlMode choiceExit="true" forwardOnly="false"/>
75
+ <imsss:deliveryControls tracked="true" completionSetByContent="true" objectiveSetByContent="true"/>
76
+ <adlnav:presentation>
77
+ <adlnav:navigationInterface>
78
+ <adlnav:hideLMSUI>continue</adlnav:hideLMSUI>
79
+ <adlnav:hideLMSUI>previous</adlnav:hideLMSUI>
80
+ </adlnav:navigationInterface>
81
+ </adlnav:presentation>
82
+ </imsss:sequencing>
83
+ </item>
84
+ </organization>
85
+ </organizations>
86
+
87
+ <resources>
88
+ <resource identifier="res-1" type="webcontent" adlcp:scormType="sco" href="index.html">
89
+ ${fileEntries}
90
+ </resource>
91
+ </resources>
92
+ </manifest>
93
+ `;
94
+ }
@@ -0,0 +1,104 @@
1
+ /**
2
+ * @file scorm-proxy-manifest.js
3
+ * @description Generates minimal SCORM manifest for proxy packages.
4
+ *
5
+ * Proxy packages contain only:
6
+ * - proxy.html (entry point)
7
+ * - scorm-bridge.js (postMessage → SCORM bridge)
8
+ * - pipwerks.js (SCORM API wrapper)
9
+ *
10
+ * Works for both SCORM 1.2 and 2004 - pipwerks auto-detects.
11
+ */
12
+
13
+ /**
14
+ * Generate SCORM 1.2 proxy manifest
15
+ * @param {Object} config - Course configuration
16
+ * @returns {string} imsmanifest.xml content
17
+ */
18
+ export function generateScorm12ProxyManifest(config) {
19
+ const identifier = config.identifier ||
20
+ config.title.replace(/[^a-zA-Z0-9]/g, '_').toLowerCase();
21
+
22
+ return `<?xml version="1.0" encoding="UTF-8"?>
23
+ <!-- SCORM 1.2 Proxy Manifest - Generated by CourseCode -->
24
+ <manifest identifier="${identifier}_proxy" version="1.0"
25
+ xmlns="http://www.imsproject.org/xsd/imscp_rootv1p1p2"
26
+ xmlns:adlcp="http://www.adlnet.org/xsd/adlcp_rootv1p2">
27
+
28
+ <metadata>
29
+ <schema>ADL SCORM</schema>
30
+ <schemaversion>1.2</schemaversion>
31
+ </metadata>
32
+
33
+ <organizations default="org_${identifier}">
34
+ <organization identifier="org_${identifier}">
35
+ <title>${escapeXml(config.title)}</title>
36
+ <item identifier="item_${identifier}" identifierref="res_${identifier}">
37
+ <title>${escapeXml(config.title)}</title>
38
+ </item>
39
+ </organization>
40
+ </organizations>
41
+
42
+ <resources>
43
+ <resource identifier="res_${identifier}" type="webcontent" adlcp:scormtype="sco" href="proxy.html">
44
+ <file href="proxy.html"/>
45
+ <file href="scorm-bridge.js"/>
46
+ <file href="pipwerks.js"/>
47
+ </resource>
48
+ </resources>
49
+ </manifest>`;
50
+ }
51
+
52
+ /**
53
+ * Generate SCORM 2004 proxy manifest
54
+ * @param {Object} config - Course configuration
55
+ * @returns {string} imsmanifest.xml content
56
+ */
57
+ export function generateScorm2004ProxyManifest(config) {
58
+ const identifier = config.identifier ||
59
+ config.title.replace(/[^a-zA-Z0-9]/g, '_').toLowerCase();
60
+
61
+ return `<?xml version="1.0" encoding="UTF-8"?>
62
+ <!-- SCORM 2004 Proxy Manifest - Generated by CourseCode -->
63
+ <manifest identifier="${identifier}_proxy" version="1.0"
64
+ xmlns="http://www.imsglobal.org/xsd/imscp_v1p1"
65
+ xmlns:adlcp="http://www.adlnet.org/xsd/adlcp_v1p3"
66
+ xmlns:adlseq="http://www.adlnet.org/xsd/adlseq_v1p3"
67
+ xmlns:adlnav="http://www.adlnet.org/xsd/adlnav_v1p3"
68
+ xmlns:imsss="http://www.imsglobal.org/xsd/imsss">
69
+
70
+ <metadata>
71
+ <schema>ADL SCORM</schema>
72
+ <schemaversion>2004 4th Edition</schemaversion>
73
+ </metadata>
74
+
75
+ <organizations default="org_${identifier}">
76
+ <organization identifier="org_${identifier}">
77
+ <title>${escapeXml(config.title)}</title>
78
+ <item identifier="item_${identifier}" identifierref="res_${identifier}">
79
+ <title>${escapeXml(config.title)}</title>
80
+ </item>
81
+ </organization>
82
+ </organizations>
83
+
84
+ <resources>
85
+ <resource identifier="res_${identifier}" type="webcontent" adlcp:scormType="sco" href="proxy.html">
86
+ <file href="proxy.html"/>
87
+ <file href="scorm-bridge.js"/>
88
+ <file href="pipwerks.js"/>
89
+ </resource>
90
+ </resources>
91
+ </manifest>`;
92
+ }
93
+
94
+ /**
95
+ * Escape special XML characters
96
+ */
97
+ function escapeXml(str) {
98
+ return String(str)
99
+ .replace(/&/g, '&amp;')
100
+ .replace(/</g, '&lt;')
101
+ .replace(/>/g, '&gt;')
102
+ .replace(/"/g, '&quot;')
103
+ .replace(/'/g, '&apos;');
104
+ }
@@ -0,0 +1,96 @@
1
+ /**
2
+ * manifest-parser.js - Parse SCORM imsmanifest.xml and cmi5.xml files
3
+ *
4
+ * Extracts key metadata for preview export and other tools.
5
+ */
6
+
7
+ /**
8
+ * Parse imsmanifest.xml content and extract key fields
9
+ * @param {string} xmlContent - Raw XML content of imsmanifest.xml
10
+ * @returns {{ identifier: string, title: string, launchFile: string, version: string | null }}
11
+ */
12
+ export function parseManifest(xmlContent) {
13
+ // Extract manifest identifier
14
+ const identifierMatch = xmlContent.match(/<manifest\s+[^>]*identifier=["']([^"']+)["']/);
15
+ const identifier = identifierMatch ? identifierMatch[1] : 'unknown-course';
16
+
17
+ // Extract version from manifest element
18
+ const versionMatch = xmlContent.match(/<manifest\s+[^>]*version=["']([^"']+)["']/);
19
+ const version = versionMatch ? versionMatch[1] : null;
20
+
21
+ // Extract title from metadata (LOM format)
22
+ // Look for: <lom:general><lom:title><lom:string>Title</lom:string></lom:title></lom:general>
23
+ let title = 'SCORM Course';
24
+ const lomTitleMatch = xmlContent.match(/<lom:title>\s*<lom:string[^>]*>([^<]+)<\/lom:string>/);
25
+ if (lomTitleMatch) {
26
+ title = lomTitleMatch[1].trim();
27
+ } else {
28
+ // Fallback: try organization title
29
+ const orgTitleMatch = xmlContent.match(/<organization[^>]*>[\s\S]*?<title>([^<]+)<\/title>/);
30
+ if (orgTitleMatch) {
31
+ title = orgTitleMatch[1].trim();
32
+ }
33
+ }
34
+
35
+ // Extract launch file from resource href
36
+ // Look for: <resource ... adlcp:scormType="sco" ... href="index.html">
37
+ let launchFile = 'index.html';
38
+ const resourceMatch = xmlContent.match(/<resource[^>]*adlcp:scormType=["']sco["'][^>]*href=["']([^"']+)["']/);
39
+ if (resourceMatch) {
40
+ launchFile = resourceMatch[1];
41
+ } else {
42
+ // Try alternate ordering (href before scormType)
43
+ const altMatch = xmlContent.match(/<resource[^>]*href=["']([^"']+)["'][^>]*adlcp:scormType=["']sco["']/);
44
+ if (altMatch) {
45
+ launchFile = altMatch[1];
46
+ }
47
+ }
48
+
49
+ return {
50
+ identifier,
51
+ title,
52
+ launchFile,
53
+ version
54
+ };
55
+ }
56
+
57
+ /**
58
+ * Parse cmi5.xml content and extract key fields
59
+ * @param {string} xmlContent - Raw XML content of cmi5.xml
60
+ * @returns {{ identifier: string, title: string, launchFile: string, version: string | null }}
61
+ */
62
+ export function parseCmi5Manifest(xmlContent) {
63
+ // Extract course id
64
+ const idMatch = xmlContent.match(/<course\s+id=["']([^"']+)["']/);
65
+ const identifier = idMatch ? idMatch[1] : 'unknown-course';
66
+
67
+ // Extract title from course > title > langstring
68
+ let title = 'cmi5 Course';
69
+ const titleMatch = xmlContent.match(/<course[^>]*>[\s\S]*?<title>\s*<langstring[^>]*>([^<]+)<\/langstring>/i);
70
+ if (titleMatch) {
71
+ title = titleMatch[1].trim();
72
+ }
73
+
74
+ // Extract launch URL from first AU
75
+ let launchFile = 'index.html';
76
+ const urlMatch = xmlContent.match(/<au[^>]*>[\s\S]*?<url>([^<]+)<\/url>/i);
77
+ if (urlMatch) {
78
+ launchFile = urlMatch[1].trim();
79
+ }
80
+
81
+ return {
82
+ identifier,
83
+ title,
84
+ launchFile,
85
+ version: null
86
+ };
87
+ }
88
+
89
+ /**
90
+ * Sanitize identifier for use as localStorage key
91
+ * @param {string} identifier - Raw manifest identifier
92
+ * @returns {string} - Safe key for localStorage
93
+ */
94
+ export function sanitizeIdentifier(identifier) {
95
+ return identifier.replace(/[^a-zA-Z0-9_-]/g, '_').substring(0, 64);
96
+ }