From b780f3ad2e186505c43d9b86b782e90572da0571 Mon Sep 17 00:00:00 2001
From: Deeksha Deepak
Date: Wed, 15 Jul 2026 11:50:21 +0530
Subject: [PATCH] Remove React QuML player (migrated to
Sunbird-inQuiry/player-v2)
---
.../workflows/publish_web_component_react.yml | 43 -
projects/sunbird-quml-player-react/.gitignore | 27 -
.../sunbird-quml-player-react/.oxlintrc.json | 8 -
projects/sunbird-quml-player-react/README.md | 32 -
projects/sunbird-quml-player-react/index.html | 19 -
.../package-lock.json | 5641 -----------------
.../sunbird-quml-player-react/package.json | 53 -
.../public/favicon.svg | 1 -
.../public/icons.svg | 24 -
.../scripts/build-wc.js | 126 -
.../sunbird-quml-player-react/src/App.css | 184 -
.../sunbird-quml-player-react/src/App.tsx | 50 -
.../src/assets/hero.png | Bin 13057 -> 0 bytes
.../src/assets/react.svg | 1 -
.../src/assets/vite.svg | 1 -
.../src/components/Alert/Alert.module.scss | 94 -
.../src/components/Alert/Alert.test.tsx | 59 -
.../src/components/Alert/Alert.tsx | 76 -
.../src/components/Header/Header.module.scss | 116 -
.../src/components/Header/Header.test.tsx | 53 -
.../src/components/Header/Header.tsx | 106 -
.../src/components/Hint/Hint.module.scss | 56 -
.../src/components/Hint/Hint.test.tsx | 52 -
.../src/components/Hint/Hint.tsx | 129 -
.../components/ImageViewer/ImageViewer.tsx | 41 -
.../components/ImageViewer/image-viewer.css | 141 -
.../components/ImageViewer/useImageZoom.ts | 103 -
.../MainPlayer.embedded-render.test.tsx | 117 -
.../MainPlayer.max-attempts.test.tsx | 147 -
.../MainPlayer.metadata-config.test.tsx | 79 -
.../MainPlayer/MainPlayer.module.scss | 108 -
.../MainPlayer.portal-fetch.test.tsx | 104 -
.../MainPlayer.preview-config.test.tsx | 119 -
.../MainPlayer.reorder-telemetry.test.tsx | 83 -
.../components/MainPlayer/MainPlayer.test.tsx | 176 -
...MainPlayer.timer-showtimer-parity.test.tsx | 87 -
.../src/components/MainPlayer/MainPlayer.tsx | 668 --
.../MobileSectionsDrawer.module.scss | 93 -
.../MobileSectionsDrawer.test.tsx | 62 -
.../MobileSectionsDrawer.tsx | 117 -
.../PlayerHeader/PlayerHeader.module.scss | 320 -
.../PlayerHeader/PlayerHeader.test.tsx | 53 -
.../components/PlayerHeader/PlayerHeader.tsx | 166 -
.../ProgressIndicators.module.scss | 90 -
.../ProgressIndicators.test.tsx | 39 -
.../ProgressIndicators/ProgressIndicators.tsx | 79 -
.../QuestionBody/QuestionBody.module.scss | 67 -
.../QuestionBody/QuestionBody.test.tsx | 54 -
.../components/QuestionBody/QuestionBody.tsx | 95 -
.../QuestionCard/QuestionCard.module.scss | 85 -
.../QuestionCard/QuestionCard.test.tsx | 32 -
.../components/QuestionCard/QuestionCard.tsx | 45 -
.../QuestionPalette.module.scss | 76 -
.../QuestionPalette/QuestionPalette.test.tsx | 43 -
.../QuestionPalette/QuestionPalette.tsx | 80 -
.../QuestionRenderer.module.scss | 15 -
.../QuestionRenderer.test.tsx | 39 -
.../QuestionRenderer/QuestionRenderer.tsx | 89 -
.../ResultsScreen/ResultsScreen.module.scss | 101 -
.../ResultsScreen/ResultsScreen.test.tsx | 97 -
.../ResultsScreen/ResultsScreen.tsx | 93 -
.../ReviewScreen/ReviewScreen.module.scss | 230 -
.../ReviewScreen/ReviewScreen.test.tsx | 76 -
.../components/ReviewScreen/ReviewScreen.tsx | 204 -
.../Scoreboard/Scoreboard.module.scss | 111 -
.../components/Scoreboard/Scoreboard.test.tsx | 37 -
.../src/components/Scoreboard/Scoreboard.tsx | 69 -
.../SectionIntro/SectionIntro.module.scss | 218 -
.../SectionIntro/SectionIntro.test.tsx | 68 -
.../components/SectionIntro/SectionIntro.tsx | 81 -
.../SectionPlayer.feedback.test.tsx | 112 -
.../SectionPlayer/SectionPlayer.module.scss | 187 -
.../SectionPlayer/SectionPlayer.test.tsx | 113 -
.../SectionPlayer/SectionPlayer.tsx | 296 -
.../components/Sidebar/Sidebar.module.scss | 134 -
.../src/components/Sidebar/Sidebar.test.tsx | 66 -
.../src/components/Sidebar/Sidebar.tsx | 76 -
.../StartPage/StartPage.module.scss | 500 --
.../components/StartPage/StartPage.test.tsx | 72 -
.../src/components/StartPage/StartPage.tsx | 206 -
.../StartPage/useIsCompactViewport.ts | 48 -
.../SubmitModal/SubmitModal.module.scss | 147 -
.../SubmitModal/SubmitModal.test.tsx | 37 -
.../components/SubmitModal/SubmitModal.tsx | 118 -
.../src/components/Toast/Toast.module.scss | 104 -
.../src/components/Toast/Toast.test.tsx | 38 -
.../src/components/Toast/Toast.tsx | 59 -
.../src/components/icons/AttemptsIcon.tsx | 25 -
.../src/components/icons/CheckIcon.tsx | 24 -
.../src/components/icons/ChevronRightIcon.tsx | 23 -
.../src/components/icons/ClipboardIcon.tsx | 24 -
.../src/components/icons/CloseIcon.tsx | 24 -
.../src/components/icons/GridIcon.tsx | 26 -
.../src/components/icons/HintIcon.tsx | 25 -
.../src/components/icons/MenuIcon.tsx | 25 -
.../src/components/icons/NextIcon.tsx | 23 -
.../src/components/icons/PreviousIcon.tsx | 23 -
.../src/components/icons/ShieldIcon.tsx | 23 -
.../src/components/icons/TimerIcon.tsx | 25 -
.../src/components/icons/ZoomInIcon.tsx | 26 -
.../src/components/icons/ZoomOutIcon.tsx | 25 -
.../src/components/icons/icons.test.tsx | 64 -
.../src/components/icons/index.tsx | 16 -
.../src/components/icons/types.ts | 9 -
.../BooleanQuestion.module.scss | 89 -
.../BooleanQuestion/BooleanQuestion.test.tsx | 112 -
.../BooleanQuestion/BooleanQuestion.tsx | 105 -
.../FtbQuestion/FtbQuestion.module.scss | 81 -
.../FtbQuestion/FtbQuestion.test.tsx | 57 -
.../questions/FtbQuestion/FtbQuestion.tsx | 105 -
.../McqQuestion/McqQuestion.module.scss | 102 -
.../McqQuestion/McqQuestion.test.tsx | 75 -
.../questions/McqQuestion/McqQuestion.tsx | 87 -
.../MtfQuestion/MtfQuestion.module.scss | 97 -
.../MtfQuestion/MtfQuestion.test.tsx | 54 -
.../questions/MtfQuestion/MtfQuestion.tsx | 180 -
.../ReoQuestion/ReoQuestion.module.scss | 119 -
.../ReoQuestion/ReoQuestion.test.tsx | 127 -
.../questions/ReoQuestion/ReoQuestion.tsx | 200 -
.../SaQuestion/SaQuestion.module.scss | 60 -
.../questions/SaQuestion/SaQuestion.test.tsx | 54 -
.../questions/SaQuestion/SaQuestion.tsx | 80 -
.../SeqQuestion/SeqQuestion.module.scss | 62 -
.../SeqQuestion/SeqQuestion.test.tsx | 47 -
.../questions/SeqQuestion/SeqQuestion.tsx | 159 -
.../components/questions/question-utils.ts | 61 -
.../src/components/questions/types.ts | 23 -
.../src/context/QumlContext.test.tsx | 240 -
.../src/context/QumlContext.tsx | 330 -
.../src/context/useQuml.test.tsx | 56 -
.../src/context/useQuml.ts | 47 -
.../src/context/useTelemetry.test.tsx | 48 -
.../src/context/useTelemetry.ts | 52 -
.../src/dev/sample-data.ts | 330 -
.../src/i18n/translations-ar.ts | 130 -
.../src/i18n/translations-en.ts | 126 -
.../src/i18n/translations-fr.ts | 132 -
.../src/i18n/translations-pt.ts | 132 -
.../src/i18n/translations.test.ts | 81 -
.../src/i18n/translations.ts | 105 -
.../sunbird-quml-player-react/src/index.css | 111 -
.../sunbird-quml-player-react/src/main.tsx | 10 -
.../registry/question-type-registry.test.ts | 74 -
.../src/registry/question-type-registry.ts | 87 -
.../src/registry/scoring-registry.test.ts | 50 -
.../src/registry/scoring-registry.ts | 53 -
.../services/data-service.embedded.test.ts | 138 -
.../services/data-service.realpayload.test.ts | 80 -
.../src/services/data-service.test.ts | 216 -
.../src/services/data-service.ts | 220 -
.../src/services/http-client.test.ts | 54 -
.../src/services/http-client.ts | 103 -
.../src/services/navigation-service.test.ts | 63 -
.../src/services/navigation-service.ts | 91 -
.../src/services/quml-library-service.ts | 31 -
.../src/services/storage-service.test.ts | 45 -
.../src/services/storage-service.ts | 58 -
.../src/services/telemetry-service.test.ts | 82 -
.../src/services/telemetry-service.ts | 118 -
.../services/transformation-service.test.ts | 182 -
.../src/services/transformation-service.ts | 333 -
.../src/styles/global.scss | 41 -
.../src/styles/mixins.scss | 105 -
.../src/styles/variables.scss | 115 -
.../src/test-setup.ts | 15 -
.../src/types/api.ts | 86 -
.../src/types/index.ts | 212 -
.../src/utils/answered.test.ts | 39 -
.../src/utils/answered.ts | 46 -
.../src/utils/api-endpoints.ts | 35 -
.../src/utils/constants.ts | 112 -
.../src/utils/id.test.ts | 11 -
.../sunbird-quml-player-react/src/utils/id.ts | 6 -
.../src/utils/media.test.ts | 118 -
.../src/utils/media.ts | 172 -
.../src/utils/object.test.ts | 18 -
.../src/utils/object.ts | 9 -
.../src/utils/score.test.ts | 233 -
.../src/utils/score.ts | Bin 10648 -> 0 bytes
.../src/utils/shuffle.ts | 14 -
.../src/utils/time.test.ts | 10 -
.../src/utils/time.ts | 9 -
.../src/utils/validation.test.ts | 14 -
.../src/utils/validation.ts | 5 -
.../web-component/element-registration.tsx | 178 -
.../tsconfig.app.json | 25 -
.../sunbird-quml-player-react/tsconfig.json | 7 -
.../tsconfig.node.json | 25 -
.../sunbird-quml-player-react/vite.config.ts | 95 -
.../vitest.config.ts | 16 -
190 files changed, 22706 deletions(-)
delete mode 100644 .github/workflows/publish_web_component_react.yml
delete mode 100644 projects/sunbird-quml-player-react/.gitignore
delete mode 100644 projects/sunbird-quml-player-react/.oxlintrc.json
delete mode 100644 projects/sunbird-quml-player-react/README.md
delete mode 100644 projects/sunbird-quml-player-react/index.html
delete mode 100644 projects/sunbird-quml-player-react/package-lock.json
delete mode 100644 projects/sunbird-quml-player-react/package.json
delete mode 100644 projects/sunbird-quml-player-react/public/favicon.svg
delete mode 100644 projects/sunbird-quml-player-react/public/icons.svg
delete mode 100644 projects/sunbird-quml-player-react/scripts/build-wc.js
delete mode 100644 projects/sunbird-quml-player-react/src/App.css
delete mode 100644 projects/sunbird-quml-player-react/src/App.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/assets/hero.png
delete mode 100644 projects/sunbird-quml-player-react/src/assets/react.svg
delete mode 100644 projects/sunbird-quml-player-react/src/assets/vite.svg
delete mode 100644 projects/sunbird-quml-player-react/src/components/Alert/Alert.module.scss
delete mode 100644 projects/sunbird-quml-player-react/src/components/Alert/Alert.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/Alert/Alert.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/Header/Header.module.scss
delete mode 100644 projects/sunbird-quml-player-react/src/components/Header/Header.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/Header/Header.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/Hint/Hint.module.scss
delete mode 100644 projects/sunbird-quml-player-react/src/components/Hint/Hint.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/Hint/Hint.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/ImageViewer/ImageViewer.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/ImageViewer/image-viewer.css
delete mode 100644 projects/sunbird-quml-player-react/src/components/ImageViewer/useImageZoom.ts
delete mode 100644 projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.embedded-render.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.max-attempts.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.metadata-config.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.module.scss
delete mode 100644 projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.portal-fetch.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.preview-config.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.reorder-telemetry.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.timer-showtimer-parity.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/MobileSectionsDrawer/MobileSectionsDrawer.module.scss
delete mode 100644 projects/sunbird-quml-player-react/src/components/MobileSectionsDrawer/MobileSectionsDrawer.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/MobileSectionsDrawer/MobileSectionsDrawer.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/PlayerHeader/PlayerHeader.module.scss
delete mode 100644 projects/sunbird-quml-player-react/src/components/PlayerHeader/PlayerHeader.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/PlayerHeader/PlayerHeader.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/ProgressIndicators/ProgressIndicators.module.scss
delete mode 100644 projects/sunbird-quml-player-react/src/components/ProgressIndicators/ProgressIndicators.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/ProgressIndicators/ProgressIndicators.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/QuestionBody/QuestionBody.module.scss
delete mode 100644 projects/sunbird-quml-player-react/src/components/QuestionBody/QuestionBody.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/QuestionBody/QuestionBody.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/QuestionCard/QuestionCard.module.scss
delete mode 100644 projects/sunbird-quml-player-react/src/components/QuestionCard/QuestionCard.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/QuestionCard/QuestionCard.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/QuestionPalette/QuestionPalette.module.scss
delete mode 100644 projects/sunbird-quml-player-react/src/components/QuestionPalette/QuestionPalette.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/QuestionPalette/QuestionPalette.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/QuestionRenderer/QuestionRenderer.module.scss
delete mode 100644 projects/sunbird-quml-player-react/src/components/QuestionRenderer/QuestionRenderer.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/QuestionRenderer/QuestionRenderer.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/ResultsScreen/ResultsScreen.module.scss
delete mode 100644 projects/sunbird-quml-player-react/src/components/ResultsScreen/ResultsScreen.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/ResultsScreen/ResultsScreen.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/ReviewScreen/ReviewScreen.module.scss
delete mode 100644 projects/sunbird-quml-player-react/src/components/ReviewScreen/ReviewScreen.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/ReviewScreen/ReviewScreen.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/Scoreboard/Scoreboard.module.scss
delete mode 100644 projects/sunbird-quml-player-react/src/components/Scoreboard/Scoreboard.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/Scoreboard/Scoreboard.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/SectionIntro/SectionIntro.module.scss
delete mode 100644 projects/sunbird-quml-player-react/src/components/SectionIntro/SectionIntro.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/SectionIntro/SectionIntro.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/SectionPlayer/SectionPlayer.feedback.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/SectionPlayer/SectionPlayer.module.scss
delete mode 100644 projects/sunbird-quml-player-react/src/components/SectionPlayer/SectionPlayer.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/SectionPlayer/SectionPlayer.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/Sidebar/Sidebar.module.scss
delete mode 100644 projects/sunbird-quml-player-react/src/components/Sidebar/Sidebar.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/Sidebar/Sidebar.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/StartPage/StartPage.module.scss
delete mode 100644 projects/sunbird-quml-player-react/src/components/StartPage/StartPage.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/StartPage/StartPage.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/StartPage/useIsCompactViewport.ts
delete mode 100644 projects/sunbird-quml-player-react/src/components/SubmitModal/SubmitModal.module.scss
delete mode 100644 projects/sunbird-quml-player-react/src/components/SubmitModal/SubmitModal.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/SubmitModal/SubmitModal.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/Toast/Toast.module.scss
delete mode 100644 projects/sunbird-quml-player-react/src/components/Toast/Toast.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/Toast/Toast.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/icons/AttemptsIcon.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/icons/CheckIcon.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/icons/ChevronRightIcon.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/icons/ClipboardIcon.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/icons/CloseIcon.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/icons/GridIcon.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/icons/HintIcon.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/icons/MenuIcon.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/icons/NextIcon.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/icons/PreviousIcon.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/icons/ShieldIcon.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/icons/TimerIcon.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/icons/ZoomInIcon.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/icons/ZoomOutIcon.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/icons/icons.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/icons/index.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/icons/types.ts
delete mode 100644 projects/sunbird-quml-player-react/src/components/questions/BooleanQuestion/BooleanQuestion.module.scss
delete mode 100644 projects/sunbird-quml-player-react/src/components/questions/BooleanQuestion/BooleanQuestion.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/questions/BooleanQuestion/BooleanQuestion.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/questions/FtbQuestion/FtbQuestion.module.scss
delete mode 100644 projects/sunbird-quml-player-react/src/components/questions/FtbQuestion/FtbQuestion.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/questions/FtbQuestion/FtbQuestion.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/questions/McqQuestion/McqQuestion.module.scss
delete mode 100644 projects/sunbird-quml-player-react/src/components/questions/McqQuestion/McqQuestion.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/questions/McqQuestion/McqQuestion.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/questions/MtfQuestion/MtfQuestion.module.scss
delete mode 100644 projects/sunbird-quml-player-react/src/components/questions/MtfQuestion/MtfQuestion.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/questions/MtfQuestion/MtfQuestion.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/questions/ReoQuestion/ReoQuestion.module.scss
delete mode 100644 projects/sunbird-quml-player-react/src/components/questions/ReoQuestion/ReoQuestion.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/questions/ReoQuestion/ReoQuestion.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/questions/SaQuestion/SaQuestion.module.scss
delete mode 100644 projects/sunbird-quml-player-react/src/components/questions/SaQuestion/SaQuestion.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/questions/SaQuestion/SaQuestion.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/questions/SeqQuestion/SeqQuestion.module.scss
delete mode 100644 projects/sunbird-quml-player-react/src/components/questions/SeqQuestion/SeqQuestion.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/questions/SeqQuestion/SeqQuestion.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/components/questions/question-utils.ts
delete mode 100644 projects/sunbird-quml-player-react/src/components/questions/types.ts
delete mode 100644 projects/sunbird-quml-player-react/src/context/QumlContext.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/context/QumlContext.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/context/useQuml.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/context/useQuml.ts
delete mode 100644 projects/sunbird-quml-player-react/src/context/useTelemetry.test.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/context/useTelemetry.ts
delete mode 100644 projects/sunbird-quml-player-react/src/dev/sample-data.ts
delete mode 100644 projects/sunbird-quml-player-react/src/i18n/translations-ar.ts
delete mode 100644 projects/sunbird-quml-player-react/src/i18n/translations-en.ts
delete mode 100644 projects/sunbird-quml-player-react/src/i18n/translations-fr.ts
delete mode 100644 projects/sunbird-quml-player-react/src/i18n/translations-pt.ts
delete mode 100644 projects/sunbird-quml-player-react/src/i18n/translations.test.ts
delete mode 100644 projects/sunbird-quml-player-react/src/i18n/translations.ts
delete mode 100644 projects/sunbird-quml-player-react/src/index.css
delete mode 100644 projects/sunbird-quml-player-react/src/main.tsx
delete mode 100644 projects/sunbird-quml-player-react/src/registry/question-type-registry.test.ts
delete mode 100644 projects/sunbird-quml-player-react/src/registry/question-type-registry.ts
delete mode 100644 projects/sunbird-quml-player-react/src/registry/scoring-registry.test.ts
delete mode 100644 projects/sunbird-quml-player-react/src/registry/scoring-registry.ts
delete mode 100644 projects/sunbird-quml-player-react/src/services/data-service.embedded.test.ts
delete mode 100644 projects/sunbird-quml-player-react/src/services/data-service.realpayload.test.ts
delete mode 100644 projects/sunbird-quml-player-react/src/services/data-service.test.ts
delete mode 100644 projects/sunbird-quml-player-react/src/services/data-service.ts
delete mode 100644 projects/sunbird-quml-player-react/src/services/http-client.test.ts
delete mode 100644 projects/sunbird-quml-player-react/src/services/http-client.ts
delete mode 100644 projects/sunbird-quml-player-react/src/services/navigation-service.test.ts
delete mode 100644 projects/sunbird-quml-player-react/src/services/navigation-service.ts
delete mode 100644 projects/sunbird-quml-player-react/src/services/quml-library-service.ts
delete mode 100644 projects/sunbird-quml-player-react/src/services/storage-service.test.ts
delete mode 100644 projects/sunbird-quml-player-react/src/services/storage-service.ts
delete mode 100644 projects/sunbird-quml-player-react/src/services/telemetry-service.test.ts
delete mode 100644 projects/sunbird-quml-player-react/src/services/telemetry-service.ts
delete mode 100644 projects/sunbird-quml-player-react/src/services/transformation-service.test.ts
delete mode 100644 projects/sunbird-quml-player-react/src/services/transformation-service.ts
delete mode 100644 projects/sunbird-quml-player-react/src/styles/global.scss
delete mode 100644 projects/sunbird-quml-player-react/src/styles/mixins.scss
delete mode 100644 projects/sunbird-quml-player-react/src/styles/variables.scss
delete mode 100644 projects/sunbird-quml-player-react/src/test-setup.ts
delete mode 100644 projects/sunbird-quml-player-react/src/types/api.ts
delete mode 100644 projects/sunbird-quml-player-react/src/types/index.ts
delete mode 100644 projects/sunbird-quml-player-react/src/utils/answered.test.ts
delete mode 100644 projects/sunbird-quml-player-react/src/utils/answered.ts
delete mode 100644 projects/sunbird-quml-player-react/src/utils/api-endpoints.ts
delete mode 100644 projects/sunbird-quml-player-react/src/utils/constants.ts
delete mode 100644 projects/sunbird-quml-player-react/src/utils/id.test.ts
delete mode 100644 projects/sunbird-quml-player-react/src/utils/id.ts
delete mode 100644 projects/sunbird-quml-player-react/src/utils/media.test.ts
delete mode 100644 projects/sunbird-quml-player-react/src/utils/media.ts
delete mode 100644 projects/sunbird-quml-player-react/src/utils/object.test.ts
delete mode 100644 projects/sunbird-quml-player-react/src/utils/object.ts
delete mode 100644 projects/sunbird-quml-player-react/src/utils/score.test.ts
delete mode 100644 projects/sunbird-quml-player-react/src/utils/score.ts
delete mode 100644 projects/sunbird-quml-player-react/src/utils/shuffle.ts
delete mode 100644 projects/sunbird-quml-player-react/src/utils/time.test.ts
delete mode 100644 projects/sunbird-quml-player-react/src/utils/time.ts
delete mode 100644 projects/sunbird-quml-player-react/src/utils/validation.test.ts
delete mode 100644 projects/sunbird-quml-player-react/src/utils/validation.ts
delete mode 100644 projects/sunbird-quml-player-react/src/web-component/element-registration.tsx
delete mode 100644 projects/sunbird-quml-player-react/tsconfig.app.json
delete mode 100644 projects/sunbird-quml-player-react/tsconfig.json
delete mode 100644 projects/sunbird-quml-player-react/tsconfig.node.json
delete mode 100644 projects/sunbird-quml-player-react/vite.config.ts
delete mode 100644 projects/sunbird-quml-player-react/vitest.config.ts
diff --git a/.github/workflows/publish_web_component_react.yml b/.github/workflows/publish_web_component_react.yml
deleted file mode 100644
index f30f4aa4..00000000
--- a/.github/workflows/publish_web_component_react.yml
+++ /dev/null
@@ -1,43 +0,0 @@
-name: Publish sunbird-quml-player-web-component-react
-
-# Publish on a React-specific tag (e.g. react-v0.1.0). A tag push runs the
-# workflow file from the tagged commit's branch, so this works without the file
-# being on the default branch. Note: the Angular publish_web_component.yml
-# triggers on any tag ('*') and will also fire on these tags — its run fails
-# harmlessly on the duplicate version and does not affect this publish.
-on:
- push:
- tags:
- - '*'
-
-defaults:
- run:
- working-directory: projects/sunbird-quml-player-react
-
-jobs:
- publish-npm:
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout code
- uses: actions/checkout@v4
-
- - name: Set up Node.js
- uses: actions/setup-node@v4
- with:
- node-version: '22.21.1'
- registry-url: 'https://registry.npmjs.org'
-
- - name: Install dependencies
- run: npm ci --legacy-peer-deps
-
- - name: Build web component
- # tsc -b && vite build && build:wc — emits web-component/ (assets + manifest)
- run: npm run build
-
- - name: Publish to NPM
- env:
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- run: |
- echo "//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}" > ~/.npmrc
- npm publish ./web-component --access public
diff --git a/projects/sunbird-quml-player-react/.gitignore b/projects/sunbird-quml-player-react/.gitignore
deleted file mode 100644
index 93769bcd..00000000
--- a/projects/sunbird-quml-player-react/.gitignore
+++ /dev/null
@@ -1,27 +0,0 @@
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-pnpm-debug.log*
-lerna-debug.log*
-
-node_modules
-dist
-dist-ssr
-*.local
-
-# Web component build output (root only — NOT src/web-component/)
-/web-component/
-
-# Editor directories and files
-.vscode/*
-!.vscode/extensions.json
-.idea
-.DS_Store
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
diff --git a/projects/sunbird-quml-player-react/.oxlintrc.json b/projects/sunbird-quml-player-react/.oxlintrc.json
deleted file mode 100644
index 6fa991da..00000000
--- a/projects/sunbird-quml-player-react/.oxlintrc.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "$schema": "./node_modules/oxlint/configuration_schema.json",
- "plugins": ["react", "typescript", "oxc"],
- "rules": {
- "react/rules-of-hooks": "error",
- "react/only-export-components": ["warn", { "allowConstantExport": true }]
- }
-}
diff --git a/projects/sunbird-quml-player-react/README.md b/projects/sunbird-quml-player-react/README.md
deleted file mode 100644
index d6af7e39..00000000
--- a/projects/sunbird-quml-player-react/README.md
+++ /dev/null
@@ -1,32 +0,0 @@
-# React + TypeScript + Vite
-
-This template provides a minimal setup to get React working in Vite with HMR and some Oxlint rules.
-
-Currently, two official plugins are available:
-
-- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Oxc](https://oxc.rs)
-- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/)
-
-## React Compiler
-
-The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
-
-## Expanding the Oxlint configuration
-
-If you are developing a production application, we recommend enabling type-aware lint rules by installing `oxlint-tsgolint` and editing `.oxlintrc.json`:
-
-```json
-{
- "$schema": "./node_modules/oxlint/configuration_schema.json",
- "plugins": ["react", "typescript", "oxc"],
- "options": {
- "typeAware": true
- },
- "rules": {
- "react/rules-of-hooks": "error",
- "react/only-export-components": ["warn", { "allowConstantExport": true }]
- }
-}
-```
-
-See the [Oxlint rules documentation](https://oxc.rs/docs/guide/usage/linter/rules) for the full list of rules and categories.
diff --git a/projects/sunbird-quml-player-react/index.html b/projects/sunbird-quml-player-react/index.html
deleted file mode 100644
index be341868..00000000
--- a/projects/sunbird-quml-player-react/index.html
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
-
-
- QUML Player
-
-
-
-
-
-
diff --git a/projects/sunbird-quml-player-react/package-lock.json b/projects/sunbird-quml-player-react/package-lock.json
deleted file mode 100644
index 6d9d9195..00000000
--- a/projects/sunbird-quml-player-react/package-lock.json
+++ /dev/null
@@ -1,5641 +0,0 @@
-{
- "name": "@project-sunbird/sunbird-quml-player-web-component-react",
- "version": "0.1.8",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "@project-sunbird/sunbird-quml-player-web-component-react",
- "version": "0.1.8",
- "dependencies": {
- "@dnd-kit/core": "^6.3.1",
- "@dnd-kit/sortable": "^8.0.0",
- "@dnd-kit/utilities": "^3.2.2",
- "@project-sunbird/client-services": "^8.1.4",
- "@project-sunbird/sb-styles": "0.0.16",
- "@project-sunbird/sunbird-player-sdk-v9": "6.0.5",
- "@project-sunbird/telemetry-sdk": "1.3.0",
- "axios": "^1.7.2",
- "bootstrap": "5.3.3",
- "classnames": "2.3.2",
- "jquery": "3.7.1",
- "katex": "0.16.10",
- "lodash-es": "4.17.21",
- "react": "18.2.0",
- "react-dnd": "16.0.1",
- "react-dnd-html5-backend": "16.0.1",
- "react-dom": "18.2.0",
- "uuid": "9.0.1"
- },
- "devDependencies": {
- "@rollup/plugin-terser": "0.4.4",
- "@testing-library/jest-dom": "6.1.0",
- "@testing-library/react": "14.0.0",
- "@types/node": "^20.11.0",
- "@types/react": "^18.2.0",
- "@types/react-dom": "^18.2.0",
- "@vitejs/plugin-react": "4.0.0",
- "fs-extra": "11.1.1",
- "jsdom": "^22.1.0",
- "rollup": "3.29.0",
- "sass": "1.69.0",
- "typescript": "^5.3.0",
- "vite": "^4.4.0",
- "vitest": "0.34.0"
- }
- },
- "node_modules/@adobe/css-tools": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.5.0.tgz",
- "integrity": "sha512-6OzddxPio9UiWTCemp4N8cYLV2ZN1ncRnV1cVGtve7dhPOtRkleRyx32GQCYSwDYgaHU3USMm84tNsvKzRCa1Q==",
- "dev": true
- },
- "node_modules/@angular/common": {
- "version": "16.2.12",
- "resolved": "https://registry.npmjs.org/@angular/common/-/common-16.2.12.tgz",
- "integrity": "sha512-B+WY/cT2VgEaz9HfJitBmgdk4I333XG/ybC98CMC4Wz8E49T8yzivmmxXB3OD6qvjcOB6ftuicl6WBqLbZNg2w==",
- "peer": true,
- "dependencies": {
- "tslib": "^2.3.0"
- },
- "engines": {
- "node": "^16.14.0 || >=18.10.0"
- },
- "peerDependencies": {
- "@angular/core": "16.2.12",
- "rxjs": "^6.5.3 || ^7.4.0"
- }
- },
- "node_modules/@angular/core": {
- "version": "16.2.12",
- "resolved": "https://registry.npmjs.org/@angular/core/-/core-16.2.12.tgz",
- "integrity": "sha512-GLLlDeke/NjroaLYOks0uyzFVo6HyLl7VOm0K1QpLXnYvW63W9Ql/T3yguRZa7tRkOAeFZ3jw+1wnBD4O8MoUA==",
- "peer": true,
- "dependencies": {
- "tslib": "^2.3.0"
- },
- "engines": {
- "node": "^16.14.0 || >=18.10.0"
- },
- "peerDependencies": {
- "rxjs": "^6.5.3 || ^7.4.0",
- "zone.js": "~0.13.0"
- }
- },
- "node_modules/@babel/code-frame": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz",
- "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==",
- "dev": true,
- "dependencies": {
- "@babel/helper-validator-identifier": "^7.29.7",
- "js-tokens": "^4.0.0",
- "picocolors": "^1.1.1"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/compat-data": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz",
- "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==",
- "dev": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/core": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz",
- "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==",
- "dev": true,
- "dependencies": {
- "@babel/code-frame": "^7.29.7",
- "@babel/generator": "^7.29.7",
- "@babel/helper-compilation-targets": "^7.29.7",
- "@babel/helper-module-transforms": "^7.29.7",
- "@babel/helpers": "^7.29.7",
- "@babel/parser": "^7.29.7",
- "@babel/template": "^7.29.7",
- "@babel/traverse": "^7.29.7",
- "@babel/types": "^7.29.7",
- "@jridgewell/remapping": "^2.3.5",
- "convert-source-map": "^2.0.0",
- "debug": "^4.1.0",
- "gensync": "^1.0.0-beta.2",
- "json5": "^2.2.3",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/babel"
- }
- },
- "node_modules/@babel/generator": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz",
- "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==",
- "dev": true,
- "dependencies": {
- "@babel/parser": "^7.29.7",
- "@babel/types": "^7.29.7",
- "@jridgewell/gen-mapping": "^0.3.12",
- "@jridgewell/trace-mapping": "^0.3.28",
- "jsesc": "^3.0.2"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-compilation-targets": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz",
- "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==",
- "dev": true,
- "dependencies": {
- "@babel/compat-data": "^7.29.7",
- "@babel/helper-validator-option": "^7.29.7",
- "browserslist": "^4.24.0",
- "lru-cache": "^5.1.1",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-globals": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz",
- "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==",
- "dev": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-module-imports": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz",
- "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==",
- "dev": true,
- "dependencies": {
- "@babel/traverse": "^7.29.7",
- "@babel/types": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-module-transforms": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz",
- "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==",
- "dev": true,
- "dependencies": {
- "@babel/helper-module-imports": "^7.29.7",
- "@babel/helper-validator-identifier": "^7.29.7",
- "@babel/traverse": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/helper-plugin-utils": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz",
- "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==",
- "dev": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-string-parser": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
- "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",
- "dev": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-identifier": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
- "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
- "dev": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-option": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz",
- "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==",
- "dev": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helpers": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz",
- "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==",
- "dev": true,
- "dependencies": {
- "@babel/template": "^7.29.7",
- "@babel/types": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/parser": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz",
- "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==",
- "dev": true,
- "dependencies": {
- "@babel/types": "^7.29.7"
- },
- "bin": {
- "parser": "bin/babel-parser.js"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@babel/plugin-transform-react-jsx-self": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz",
- "integrity": "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==",
- "dev": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-react-jsx-source": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz",
- "integrity": "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==",
- "dev": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/runtime": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz",
- "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/template": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz",
- "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==",
- "dev": true,
- "dependencies": {
- "@babel/code-frame": "^7.29.7",
- "@babel/parser": "^7.29.7",
- "@babel/types": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/traverse": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz",
- "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==",
- "dev": true,
- "dependencies": {
- "@babel/code-frame": "^7.29.7",
- "@babel/generator": "^7.29.7",
- "@babel/helper-globals": "^7.29.7",
- "@babel/parser": "^7.29.7",
- "@babel/template": "^7.29.7",
- "@babel/types": "^7.29.7",
- "debug": "^4.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/types": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz",
- "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==",
- "dev": true,
- "dependencies": {
- "@babel/helper-string-parser": "^7.29.7",
- "@babel/helper-validator-identifier": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@digitalbazaar/http-client": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@digitalbazaar/http-client/-/http-client-1.2.0.tgz",
- "integrity": "sha512-W9KQQ5pUJcaR0I4c2HPJC0a7kRbZApIorZgPnEDwMBgj16iQzutGLrCXYaZOmxqVLVNqqlQ4aUJh+HBQZy4W6Q==",
- "dependencies": {
- "esm": "^3.2.22",
- "ky": "^0.25.1",
- "ky-universal": "^0.8.2"
- },
- "engines": {
- "node": ">=10.0.0"
- }
- },
- "node_modules/@dnd-kit/accessibility": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.1.1.tgz",
- "integrity": "sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==",
- "dependencies": {
- "tslib": "^2.0.0"
- },
- "peerDependencies": {
- "react": ">=16.8.0"
- }
- },
- "node_modules/@dnd-kit/core": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.3.1.tgz",
- "integrity": "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==",
- "dependencies": {
- "@dnd-kit/accessibility": "^3.1.1",
- "@dnd-kit/utilities": "^3.2.2",
- "tslib": "^2.0.0"
- },
- "peerDependencies": {
- "react": ">=16.8.0",
- "react-dom": ">=16.8.0"
- }
- },
- "node_modules/@dnd-kit/sortable": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/@dnd-kit/sortable/-/sortable-8.0.0.tgz",
- "integrity": "sha512-U3jk5ebVXe1Lr7c2wU7SBZjcWdQP+j7peHJfCspnA81enlu88Mgd7CC8Q+pub9ubP7eKVETzJW+IBAhsqbSu/g==",
- "dependencies": {
- "@dnd-kit/utilities": "^3.2.2",
- "tslib": "^2.0.0"
- },
- "peerDependencies": {
- "@dnd-kit/core": "^6.1.0",
- "react": ">=16.8.0"
- }
- },
- "node_modules/@dnd-kit/utilities": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.2.tgz",
- "integrity": "sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==",
- "dependencies": {
- "tslib": "^2.0.0"
- },
- "peerDependencies": {
- "react": ">=16.8.0"
- }
- },
- "node_modules/@esbuild/android-arm": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
- "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/android-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
- "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/android-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
- "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/darwin-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
- "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/darwin-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
- "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/freebsd-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
- "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/freebsd-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
- "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-arm": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
- "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
- "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-ia32": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
- "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-loong64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
- "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-mips64el": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
- "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
- "cpu": [
- "mips64el"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-ppc64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
- "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-riscv64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
- "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-s390x": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
- "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
- "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/netbsd-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
- "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/openbsd-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
- "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/sunos-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
- "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "sunos"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/win32-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
- "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/win32-ia32": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
- "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/win32-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
- "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@jest/schemas": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
- "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
- "dev": true,
- "dependencies": {
- "@sinclair/typebox": "^0.27.8"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.13",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
- "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
- "dev": true,
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.0",
- "@jridgewell/trace-mapping": "^0.3.24"
- }
- },
- "node_modules/@jridgewell/remapping": {
- "version": "2.3.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
- "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
- "dev": true,
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.24"
- }
- },
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
- "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
- "dev": true,
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/source-map": {
- "version": "0.3.11",
- "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz",
- "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
- "dev": true,
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.25"
- }
- },
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
- "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
- "dev": true
- },
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.31",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
- "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
- "dev": true,
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
- }
- },
- "node_modules/@popperjs/core": {
- "version": "2.11.8",
- "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
- "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
- "peer": true,
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/popperjs"
- }
- },
- "node_modules/@project-sunbird/client-services": {
- "version": "8.1.4",
- "resolved": "https://registry.npmjs.org/@project-sunbird/client-services/-/client-services-8.1.4.tgz",
- "integrity": "sha512-0/VFo1x+v/wdCltMjmdhXA90Nq0N0CQARjJliYWSxo+krDiWUYO0dIUT5P847yL4v8LedvJjjwUiKrjlh1FC0w==",
- "dependencies": {
- "@project-sunbird/telemetry-sdk": "1.3.0",
- "crypto-ld": "3.9.0",
- "dayjs": "1.9.8",
- "global": "^4.4.0",
- "inversify": "5.1.1",
- "jsonld": "5.2.0",
- "jsonld-signatures": "7.0.0",
- "jszip": "3.10.1",
- "node-fetch": "2.7.0",
- "path-browserify": "^1.0.1",
- "qs": "6.9.7",
- "reflect-metadata": "0.1.13",
- "security-context": "4.0.0",
- "whatwg-fetch": "3.6.19"
- },
- "peerDependencies": {
- "rxjs": ">=6"
- }
- },
- "node_modules/@project-sunbird/sb-styles": {
- "version": "0.0.16",
- "resolved": "https://registry.npmjs.org/@project-sunbird/sb-styles/-/sb-styles-0.0.16.tgz",
- "integrity": "sha512-bQB1ZGEdxk7/mcDMjcY9d7C2tpJpinmBzbxOPV0YDoOiZVHv1haS+yFlUbxxgDz9hhrr3u6A+vBoBUaX2We5gA=="
- },
- "node_modules/@project-sunbird/sunbird-player-sdk-v9": {
- "version": "6.0.5",
- "resolved": "https://registry.npmjs.org/@project-sunbird/sunbird-player-sdk-v9/-/sunbird-player-sdk-v9-6.0.5.tgz",
- "integrity": "sha512-TN6Dn/BFhZ5ETxdLulZvYO4N+LTRp1ZznkHxAcfDGLl0c1L2wCEH4dEVAzcFvjgXMXwVjac400gDWL0ElCXTYw==",
- "dependencies": {
- "tslib": "^2.0.0"
- },
- "peerDependencies": {
- "@angular/common": "^16.2.12",
- "@angular/core": "^16.2.12",
- "@project-sunbird/sb-styles": ">= 0.0.7",
- "ally.js": "1.4.1"
- }
- },
- "node_modules/@project-sunbird/telemetry-sdk": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/@project-sunbird/telemetry-sdk/-/telemetry-sdk-1.3.0.tgz",
- "integrity": "sha512-9vocPJpB08/8pAXDUKQmhCiBxJ9qHxORF1+ot3kJczSnRh/K+POpAWDCR4iJ2+gWXPDE03WIWezshKpyf0RdYQ=="
- },
- "node_modules/@react-dnd/asap": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-5.0.2.tgz",
- "integrity": "sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A=="
- },
- "node_modules/@react-dnd/invariant": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-4.0.2.tgz",
- "integrity": "sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw=="
- },
- "node_modules/@react-dnd/shallowequal": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-4.0.2.tgz",
- "integrity": "sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA=="
- },
- "node_modules/@rollup/plugin-terser": {
- "version": "0.4.4",
- "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz",
- "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==",
- "dev": true,
- "dependencies": {
- "serialize-javascript": "^6.0.1",
- "smob": "^1.0.0",
- "terser": "^5.17.4"
- },
- "engines": {
- "node": ">=14.0.0"
- },
- "peerDependencies": {
- "rollup": "^2.0.0||^3.0.0||^4.0.0"
- },
- "peerDependenciesMeta": {
- "rollup": {
- "optional": true
- }
- }
- },
- "node_modules/@sinclair/typebox": {
- "version": "0.27.10",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.10.tgz",
- "integrity": "sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==",
- "dev": true
- },
- "node_modules/@testing-library/dom": {
- "version": "9.3.4",
- "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.4.tgz",
- "integrity": "sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==",
- "dev": true,
- "dependencies": {
- "@babel/code-frame": "^7.10.4",
- "@babel/runtime": "^7.12.5",
- "@types/aria-query": "^5.0.1",
- "aria-query": "5.1.3",
- "chalk": "^4.1.0",
- "dom-accessibility-api": "^0.5.9",
- "lz-string": "^1.5.0",
- "pretty-format": "^27.0.2"
- },
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/@testing-library/dom/node_modules/aria-query": {
- "version": "5.1.3",
- "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz",
- "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==",
- "dev": true,
- "dependencies": {
- "deep-equal": "^2.0.5"
- }
- },
- "node_modules/@testing-library/dom/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/@testing-library/jest-dom": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.1.0.tgz",
- "integrity": "sha512-EUAg9pvOkzmGXUSyAPt0h6yAXHxsn+FMNS1o7OX8TErmldZML2ywt10lotZXx/a1PDiSnq0fGGyEV/ybKSLPWQ==",
- "dev": true,
- "dependencies": {
- "@adobe/css-tools": "^4.0.1",
- "@babel/runtime": "^7.9.2",
- "aria-query": "^5.0.0",
- "chalk": "^3.0.0",
- "css.escape": "^1.5.1",
- "dom-accessibility-api": "^0.5.6",
- "lodash": "^4.17.15",
- "redent": "^3.0.0"
- },
- "engines": {
- "node": ">=14",
- "npm": ">=6",
- "yarn": ">=1"
- },
- "peerDependencies": {
- "@jest/globals": ">= 28",
- "@types/jest": ">= 28",
- "jest": ">= 28",
- "vitest": ">= 0.32"
- },
- "peerDependenciesMeta": {
- "@jest/globals": {
- "optional": true
- },
- "@types/jest": {
- "optional": true
- },
- "jest": {
- "optional": true
- },
- "vitest": {
- "optional": true
- }
- }
- },
- "node_modules/@testing-library/react": {
- "version": "14.0.0",
- "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-14.0.0.tgz",
- "integrity": "sha512-S04gSNJbYE30TlIMLTzv6QCTzt9AqIF5y6s6SzVFILNcNvbV/jU96GeiTPillGQo+Ny64M/5PV7klNYYgv5Dfg==",
- "dev": true,
- "dependencies": {
- "@babel/runtime": "^7.12.5",
- "@testing-library/dom": "^9.0.0",
- "@types/react-dom": "^18.0.0"
- },
- "engines": {
- "node": ">=14"
- },
- "peerDependencies": {
- "react": "^18.0.0",
- "react-dom": "^18.0.0"
- }
- },
- "node_modules/@tootallnate/once": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.1.tgz",
- "integrity": "sha512-HqmEUIGRJ5fSXchkVgR5F7qn48bDBzv0kWj/Kfu5e6uci4UlEeng4331LnBkWffb++Ei3FOVLxo8JJWMFBDMeQ==",
- "dev": true,
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@types/aria-query": {
- "version": "5.0.4",
- "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
- "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==",
- "dev": true
- },
- "node_modules/@types/chai": {
- "version": "4.3.20",
- "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.20.tgz",
- "integrity": "sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==",
- "dev": true
- },
- "node_modules/@types/chai-subset": {
- "version": "1.3.6",
- "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.6.tgz",
- "integrity": "sha512-m8lERkkQj+uek18hXOZuec3W/fCRTrU4hrnXjH3qhHy96ytuPaPiWGgu7sJb7tZxZonO75vYAjCvpe/e4VUwRw==",
- "dev": true,
- "peerDependencies": {
- "@types/chai": "<5.2.0"
- }
- },
- "node_modules/@types/node": {
- "version": "20.19.43",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.43.tgz",
- "integrity": "sha512-6oYBAi5ikg4Pl+kGsoYtawUMBT2zZMCvPNF7pVLnHZfd1zf38DRiWn/gT01RYCdUqkv7Fhr+C9ot4/tb+2sVvA==",
- "devOptional": true,
- "dependencies": {
- "undici-types": "~6.21.0"
- }
- },
- "node_modules/@types/prop-types": {
- "version": "15.7.15",
- "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz",
- "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==",
- "devOptional": true
- },
- "node_modules/@types/react": {
- "version": "18.3.31",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.31.tgz",
- "integrity": "sha512-vfEqpXTvwT91yhmwdfouStN2hSKwTvyRs8qpLfADyrq/kxDw0hZM7Wk9Ug1FELj8hIby+S/+kQCSRFF32nv2Qw==",
- "devOptional": true,
- "dependencies": {
- "@types/prop-types": "*",
- "csstype": "^3.2.2"
- }
- },
- "node_modules/@types/react-dom": {
- "version": "18.3.7",
- "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz",
- "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==",
- "dev": true,
- "peerDependencies": {
- "@types/react": "^18.0.0"
- }
- },
- "node_modules/@vitejs/plugin-react": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.0.0.tgz",
- "integrity": "sha512-HX0XzMjL3hhOYm+0s95pb0Z7F8O81G7joUHgfDd/9J/ZZf5k4xX6QAMFkKsHFxaHlf6X7GD7+XuaZ66ULiJuhQ==",
- "dev": true,
- "dependencies": {
- "@babel/core": "^7.21.4",
- "@babel/plugin-transform-react-jsx-self": "^7.21.0",
- "@babel/plugin-transform-react-jsx-source": "^7.19.6",
- "react-refresh": "^0.14.0"
- },
- "engines": {
- "node": "^14.18.0 || >=16.0.0"
- },
- "peerDependencies": {
- "vite": "^4.2.0"
- }
- },
- "node_modules/@vitest/expect": {
- "version": "0.34.0",
- "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.34.0.tgz",
- "integrity": "sha512-d1ZU0XomWFAFyYIc6uNuY0N8NJIWESyO/6ZmwLvlHZw0GevH4AEEpq178KjXIvSCrbHN0GnzYzitd0yjfy7+Ow==",
- "dev": true,
- "dependencies": {
- "@vitest/spy": "0.34.0",
- "@vitest/utils": "0.34.0",
- "chai": "^4.3.7"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/runner": {
- "version": "0.34.0",
- "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.34.0.tgz",
- "integrity": "sha512-xaqM+oArJothtYXzy/dwu/iHe93Khq5QkvnYbzTxiLA0enD2peft1cask3yE6cJpwMkr7C2D1uMJwnTt4mquDw==",
- "dev": true,
- "dependencies": {
- "@vitest/utils": "0.34.0",
- "p-limit": "^4.0.0",
- "pathe": "^1.1.1"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/snapshot": {
- "version": "0.34.0",
- "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.34.0.tgz",
- "integrity": "sha512-eGN5XBZHYOghxCOQbf8dcn6/3g7IW77GOOOC/mNFYwRXsPeoQgcgWnhj+6wgJ04pVv25wpxWL9jUkzaQ7LoFtg==",
- "dev": true,
- "dependencies": {
- "magic-string": "^0.30.1",
- "pathe": "^1.1.1",
- "pretty-format": "^29.5.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/snapshot/node_modules/ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/@vitest/snapshot/node_modules/pretty-format": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
- "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
- "dev": true,
- "dependencies": {
- "@jest/schemas": "^29.6.3",
- "ansi-styles": "^5.0.0",
- "react-is": "^18.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@vitest/snapshot/node_modules/react-is": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
- "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
- "dev": true
- },
- "node_modules/@vitest/spy": {
- "version": "0.34.0",
- "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.34.0.tgz",
- "integrity": "sha512-0SZaWrQvL9ZiF/uJvyWSvsKjfuMvD1M6dE5BbE4Dmt8Vh3k4htwCV8g3ce8YOYmJSxkbh6TNOpippD6NVsxW6w==",
- "dev": true,
- "dependencies": {
- "tinyspy": "^2.1.1"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/utils": {
- "version": "0.34.0",
- "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.0.tgz",
- "integrity": "sha512-IktrDLhBKf3dEUUxH+lcHiPnaw952+GdGvoxg99liMscgP6IePf6LuMY7B9dEIHkFunB1R8VMR/wmI/4UGg1aw==",
- "dev": true,
- "dependencies": {
- "diff-sequences": "^29.4.3",
- "loupe": "^2.3.6",
- "pretty-format": "^29.5.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/utils/node_modules/ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/@vitest/utils/node_modules/pretty-format": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
- "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
- "dev": true,
- "dependencies": {
- "@jest/schemas": "^29.6.3",
- "ansi-styles": "^5.0.0",
- "react-is": "^18.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@vitest/utils/node_modules/react-is": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
- "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
- "dev": true
- },
- "node_modules/abab": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
- "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==",
- "deprecated": "Use your platform's native atob() and btoa() methods instead",
- "dev": true
- },
- "node_modules/abort-controller": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
- "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
- "dependencies": {
- "event-target-shim": "^5.0.0"
- },
- "engines": {
- "node": ">=6.5"
- }
- },
- "node_modules/acorn": {
- "version": "8.17.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz",
- "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==",
- "dev": true,
- "bin": {
- "acorn": "bin/acorn"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/acorn-walk": {
- "version": "8.3.5",
- "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz",
- "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==",
- "dev": true,
- "dependencies": {
- "acorn": "^8.11.0"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/agent-base": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
- "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
- "dev": true,
- "dependencies": {
- "debug": "4"
- },
- "engines": {
- "node": ">= 6.0.0"
- }
- },
- "node_modules/ajv": {
- "version": "6.15.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz",
- "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==",
- "dependencies": {
- "fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
- "uri-js": "^4.2.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "node_modules/ally.js": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/ally.js/-/ally.js-1.4.1.tgz",
- "integrity": "sha512-ZewdfuwP6VewtMN36QY0gmiyvBfMnmEaNwbVu2nTS6zRt069viTgkYgaDiqu6vRJ1VJCriNqV0jGMu44R8zNbA==",
- "peer": true,
- "dependencies": {
- "css.escape": "^1.5.0",
- "platform": "1.3.3"
- }
- },
- "node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/anymatch": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
- "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
- "dev": true,
- "dependencies": {
- "normalize-path": "^3.0.0",
- "picomatch": "^2.0.4"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/aria-query": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz",
- "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==",
- "dev": true,
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/array-buffer-byte-length": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz",
- "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==",
- "dependencies": {
- "call-bound": "^1.0.3",
- "is-array-buffer": "^3.0.5"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/arraybuffer.prototype.slice": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz",
- "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==",
- "dependencies": {
- "array-buffer-byte-length": "^1.0.1",
- "call-bind": "^1.0.8",
- "define-properties": "^1.2.1",
- "es-abstract": "^1.23.5",
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.6",
- "is-array-buffer": "^3.0.4"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/asn1": {
- "version": "0.2.6",
- "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
- "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
- "dependencies": {
- "safer-buffer": "~2.1.0"
- }
- },
- "node_modules/assert-plus": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
- "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==",
- "engines": {
- "node": ">=0.8"
- }
- },
- "node_modules/assertion-error": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
- "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
- "dev": true,
- "engines": {
- "node": "*"
- }
- },
- "node_modules/async-function": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz",
- "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/asynckit": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
- },
- "node_modules/available-typed-arrays": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
- "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
- "dependencies": {
- "possible-typed-array-names": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/aws-sign2": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
- "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==",
- "engines": {
- "node": "*"
- }
- },
- "node_modules/aws4": {
- "version": "1.13.2",
- "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz",
- "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw=="
- },
- "node_modules/axios": {
- "version": "1.7.2",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz",
- "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
- "dependencies": {
- "follow-redirects": "^1.15.6",
- "form-data": "^4.0.0",
- "proxy-from-env": "^1.1.0"
- }
- },
- "node_modules/base-x": {
- "version": "3.0.11",
- "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.11.tgz",
- "integrity": "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==",
- "dependencies": {
- "safe-buffer": "^5.0.1"
- }
- },
- "node_modules/base64url": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz",
- "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/base64url-universal": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/base64url-universal/-/base64url-universal-1.1.0.tgz",
- "integrity": "sha512-WyftvZqye29YQ10ZnuiBeEj0lk8SN8xHU9hOznkLc85wS1cLTp6RpzlMrHxMPD9nH7S55gsBqMqgGyz93rqmkA==",
- "dependencies": {
- "base64url": "^3.0.0"
- },
- "engines": {
- "node": ">=8.3.0"
- }
- },
- "node_modules/baseline-browser-mapping": {
- "version": "2.10.40",
- "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.40.tgz",
- "integrity": "sha512-BSSLZ9/Cjjv7Gtj5B68ZzXcXUg8iOf3fme+FCuh8rC/Go+Kmh8cox7M3A8dolou16s64QjLPOSdngh7GxXvkSw==",
- "dev": true,
- "bin": {
- "baseline-browser-mapping": "dist/cli.cjs"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/bcrypt-pbkdf": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
- "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
- "dependencies": {
- "tweetnacl": "^0.14.3"
- }
- },
- "node_modules/binary-extensions": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
- "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
- "dev": true,
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/bootstrap": {
- "version": "5.3.3",
- "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.3.tgz",
- "integrity": "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/twbs"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/bootstrap"
- }
- ],
- "peerDependencies": {
- "@popperjs/core": "^2.11.8"
- }
- },
- "node_modules/braces": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
- "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
- "dev": true,
- "dependencies": {
- "fill-range": "^7.1.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/browserslist": {
- "version": "4.28.4",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.4.tgz",
- "integrity": "sha512-MTc8i/x9jBQd1iMw2CFGS+rwMa07eYjLR0CCTLDACl9xhxy+nIs3KeML/biicXtk9JrZ6dnnTatmc7ErPXIxqw==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "dependencies": {
- "baseline-browser-mapping": "^2.10.38",
- "caniuse-lite": "^1.0.30001799",
- "electron-to-chromium": "^1.5.376",
- "node-releases": "^2.0.48",
- "update-browserslist-db": "^1.2.3"
- },
- "bin": {
- "browserslist": "cli.js"
- },
- "engines": {
- "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
- }
- },
- "node_modules/bs58": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
- "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==",
- "dependencies": {
- "base-x": "^3.0.2"
- }
- },
- "node_modules/buffer-from": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
- "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
- "dev": true
- },
- "node_modules/cac": {
- "version": "6.7.14",
- "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
- "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/call-bind": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz",
- "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.2",
- "es-define-property": "^1.0.1",
- "get-intrinsic": "^1.3.0",
- "set-function-length": "^1.2.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/call-bind-apply-helpers": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
- "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
- "dependencies": {
- "es-errors": "^1.3.0",
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/call-bound": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
- "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.2",
- "get-intrinsic": "^1.3.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/caniuse-lite": {
- "version": "1.0.30001799",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001799.tgz",
- "integrity": "sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ]
- },
- "node_modules/canonicalize": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/canonicalize/-/canonicalize-1.0.8.tgz",
- "integrity": "sha512-0CNTVCLZggSh7bc5VkX5WWPWO+cyZbNd07IHIsSXLia/eAq+r836hgk+8BKoEh7949Mda87VUOitx5OddVj64A=="
- },
- "node_modules/caseless": {
- "version": "0.12.0",
- "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
- "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw=="
- },
- "node_modules/chai": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz",
- "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==",
- "dev": true,
- "dependencies": {
- "assertion-error": "^1.1.0",
- "check-error": "^1.0.3",
- "deep-eql": "^4.1.3",
- "get-func-name": "^2.0.2",
- "loupe": "^2.3.6",
- "pathval": "^1.1.1",
- "type-detect": "^4.1.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/chalk": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
- "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/check-error": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz",
- "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==",
- "dev": true,
- "dependencies": {
- "get-func-name": "^2.0.2"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/chokidar": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
- "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
- "dev": true,
- "dependencies": {
- "anymatch": "~3.1.2",
- "braces": "~3.0.2",
- "glob-parent": "~5.1.2",
- "is-binary-path": "~2.1.0",
- "is-glob": "~4.0.1",
- "normalize-path": "~3.0.0",
- "readdirp": "~3.6.0"
- },
- "engines": {
- "node": ">= 8.10.0"
- },
- "funding": {
- "url": "https://paulmillr.com/funding/"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
- }
- },
- "node_modules/classnames": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz",
- "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
- },
- "node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/combined-stream": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
- "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
- "dependencies": {
- "delayed-stream": "~1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/commander": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
- "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
- "engines": {
- "node": ">= 12"
- }
- },
- "node_modules/confbox": {
- "version": "0.1.8",
- "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
- "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
- "dev": true
- },
- "node_modules/convert-source-map": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
- "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
- "dev": true
- },
- "node_modules/core-util-is": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
- "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
- },
- "node_modules/crypto-ld": {
- "version": "3.9.0",
- "resolved": "https://registry.npmjs.org/crypto-ld/-/crypto-ld-3.9.0.tgz",
- "integrity": "sha512-PFE7V6A2QNnUp6iiPVEZI4p8wsztkEWLbY1BAXVnclm/aw4KGwpJ+1Ds4vQUCJ5BsWxj15fwE5rHQ8AWaWB2nw==",
- "dependencies": {
- "base64url-universal": "^1.0.1",
- "bs58": "^4.0.1",
- "node-forge": "~0.10.0",
- "semver": "^6.2.0"
- },
- "engines": {
- "node": ">=8.3.0"
- },
- "optionalDependencies": {
- "sodium-native": "^3.2.0"
- }
- },
- "node_modules/css.escape": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz",
- "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg=="
- },
- "node_modules/cssstyle": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz",
- "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==",
- "dev": true,
- "dependencies": {
- "rrweb-cssom": "^0.6.0"
- },
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/csstype": {
- "version": "3.2.3",
- "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
- "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
- "devOptional": true
- },
- "node_modules/dashdash": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
- "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==",
- "dependencies": {
- "assert-plus": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10"
- }
- },
- "node_modules/data-uri-to-buffer": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz",
- "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/data-urls": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-4.0.0.tgz",
- "integrity": "sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==",
- "dev": true,
- "dependencies": {
- "abab": "^2.0.6",
- "whatwg-mimetype": "^3.0.0",
- "whatwg-url": "^12.0.0"
- },
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/data-view-buffer": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz",
- "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==",
- "dependencies": {
- "call-bound": "^1.0.3",
- "es-errors": "^1.3.0",
- "is-data-view": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/data-view-byte-length": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz",
- "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==",
- "dependencies": {
- "call-bound": "^1.0.3",
- "es-errors": "^1.3.0",
- "is-data-view": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/inspect-js"
- }
- },
- "node_modules/data-view-byte-offset": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz",
- "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==",
- "dependencies": {
- "call-bound": "^1.0.2",
- "es-errors": "^1.3.0",
- "is-data-view": "^1.0.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/dayjs": {
- "version": "1.9.8",
- "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.9.8.tgz",
- "integrity": "sha512-F42qBtJRa30FKF7XDnOQyNUTsaxDkuaZRj/i7BejSHC34LlLfPoIU4aeopvWfM+m1dJ6/DHKAWLg2ur+pLgq1w=="
- },
- "node_modules/debug": {
- "version": "4.4.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
- "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
- "dev": true,
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/decimal.js": {
- "version": "10.6.0",
- "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz",
- "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==",
- "dev": true
- },
- "node_modules/deep-eql": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz",
- "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==",
- "dev": true,
- "dependencies": {
- "type-detect": "^4.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/deep-equal": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz",
- "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==",
- "dev": true,
- "dependencies": {
- "array-buffer-byte-length": "^1.0.0",
- "call-bind": "^1.0.5",
- "es-get-iterator": "^1.1.3",
- "get-intrinsic": "^1.2.2",
- "is-arguments": "^1.1.1",
- "is-array-buffer": "^3.0.2",
- "is-date-object": "^1.0.5",
- "is-regex": "^1.1.4",
- "is-shared-array-buffer": "^1.0.2",
- "isarray": "^2.0.5",
- "object-is": "^1.1.5",
- "object-keys": "^1.1.1",
- "object.assign": "^4.1.4",
- "regexp.prototype.flags": "^1.5.1",
- "side-channel": "^1.0.4",
- "which-boxed-primitive": "^1.0.2",
- "which-collection": "^1.0.1",
- "which-typed-array": "^1.1.13"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/deep-equal/node_modules/isarray": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
- "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
- "dev": true
- },
- "node_modules/define-data-property": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
- "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
- "dependencies": {
- "es-define-property": "^1.0.0",
- "es-errors": "^1.3.0",
- "gopd": "^1.0.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/define-properties": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
- "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
- "dependencies": {
- "define-data-property": "^1.0.1",
- "has-property-descriptors": "^1.0.0",
- "object-keys": "^1.1.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/delayed-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/diff-sequences": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz",
- "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==",
- "dev": true,
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/dnd-core": {
- "version": "16.0.1",
- "resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-16.0.1.tgz",
- "integrity": "sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==",
- "dependencies": {
- "@react-dnd/asap": "^5.0.1",
- "@react-dnd/invariant": "^4.0.1",
- "redux": "^4.2.0"
- }
- },
- "node_modules/dom-accessibility-api": {
- "version": "0.5.16",
- "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
- "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
- "dev": true
- },
- "node_modules/dom-walk": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
- "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w=="
- },
- "node_modules/domexception": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz",
- "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==",
- "deprecated": "Use your platform's native DOMException instead",
- "dev": true,
- "dependencies": {
- "webidl-conversions": "^7.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/dunder-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
- "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.1",
- "es-errors": "^1.3.0",
- "gopd": "^1.2.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/ecc-jsbn": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
- "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==",
- "dependencies": {
- "jsbn": "~0.1.0",
- "safer-buffer": "^2.1.0"
- }
- },
- "node_modules/electron-to-chromium": {
- "version": "1.5.381",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.381.tgz",
- "integrity": "sha512-n9Wa6yB+vDsGuA8AKbl/0z7HbvWqt5jxIdvr1IUicd0ryPrk7/xzwqLv8D9AbbvZ6avVNtXYLTfmgFHkwkyelg==",
- "dev": true
- },
- "node_modules/entities": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
- "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
- "dev": true,
- "engines": {
- "node": ">=0.12"
- },
- "funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
- }
- },
- "node_modules/es-abstract": {
- "version": "1.24.2",
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz",
- "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==",
- "dependencies": {
- "array-buffer-byte-length": "^1.0.2",
- "arraybuffer.prototype.slice": "^1.0.4",
- "available-typed-arrays": "^1.0.7",
- "call-bind": "^1.0.8",
- "call-bound": "^1.0.4",
- "data-view-buffer": "^1.0.2",
- "data-view-byte-length": "^1.0.2",
- "data-view-byte-offset": "^1.0.1",
- "es-define-property": "^1.0.1",
- "es-errors": "^1.3.0",
- "es-object-atoms": "^1.1.1",
- "es-set-tostringtag": "^2.1.0",
- "es-to-primitive": "^1.3.0",
- "function.prototype.name": "^1.1.8",
- "get-intrinsic": "^1.3.0",
- "get-proto": "^1.0.1",
- "get-symbol-description": "^1.1.0",
- "globalthis": "^1.0.4",
- "gopd": "^1.2.0",
- "has-property-descriptors": "^1.0.2",
- "has-proto": "^1.2.0",
- "has-symbols": "^1.1.0",
- "hasown": "^2.0.2",
- "internal-slot": "^1.1.0",
- "is-array-buffer": "^3.0.5",
- "is-callable": "^1.2.7",
- "is-data-view": "^1.0.2",
- "is-negative-zero": "^2.0.3",
- "is-regex": "^1.2.1",
- "is-set": "^2.0.3",
- "is-shared-array-buffer": "^1.0.4",
- "is-string": "^1.1.1",
- "is-typed-array": "^1.1.15",
- "is-weakref": "^1.1.1",
- "math-intrinsics": "^1.1.0",
- "object-inspect": "^1.13.4",
- "object-keys": "^1.1.1",
- "object.assign": "^4.1.7",
- "own-keys": "^1.0.1",
- "regexp.prototype.flags": "^1.5.4",
- "safe-array-concat": "^1.1.3",
- "safe-push-apply": "^1.0.0",
- "safe-regex-test": "^1.1.0",
- "set-proto": "^1.0.0",
- "stop-iteration-iterator": "^1.1.0",
- "string.prototype.trim": "^1.2.10",
- "string.prototype.trimend": "^1.0.9",
- "string.prototype.trimstart": "^1.0.8",
- "typed-array-buffer": "^1.0.3",
- "typed-array-byte-length": "^1.0.3",
- "typed-array-byte-offset": "^1.0.4",
- "typed-array-length": "^1.0.7",
- "unbox-primitive": "^1.1.0",
- "which-typed-array": "^1.1.19"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/es-abstract-get": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/es-abstract-get/-/es-abstract-get-1.0.0.tgz",
- "integrity": "sha512-6PMWXpdhshVvFp+FoWYs1EvG1Nj0tvk0dZM+XcK0xMEM1czRVcP6ohqPWHy6qPagSpC8j4+p89WXlT+xXJs/fg==",
- "dependencies": {
- "es-errors": "^1.3.0",
- "es-object-atoms": "^1.1.2",
- "is-callable": "^1.2.7",
- "object-inspect": "^1.13.4"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/es-define-property": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
- "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-errors": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
- "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-get-iterator": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz",
- "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==",
- "dev": true,
- "dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.1.3",
- "has-symbols": "^1.0.3",
- "is-arguments": "^1.1.1",
- "is-map": "^2.0.2",
- "is-set": "^2.0.2",
- "is-string": "^1.0.7",
- "isarray": "^2.0.5",
- "stop-iteration-iterator": "^1.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/es-get-iterator/node_modules/isarray": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
- "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
- "dev": true
- },
- "node_modules/es-object-atoms": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz",
- "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==",
- "dependencies": {
- "es-errors": "^1.3.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-set-tostringtag": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
- "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
- "dependencies": {
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.6",
- "has-tostringtag": "^1.0.2",
- "hasown": "^2.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-to-primitive": {
- "version": "1.3.4",
- "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.4.tgz",
- "integrity": "sha512-yPDz7wqpg1/mmHLmS3tcfTfbw5f1eryXvyghYBffGdERwe+mV7ZcWzTR8LR17Kvqt3qfPurjlonmnq3MKXIOXw==",
- "dependencies": {
- "es-abstract-get": "^1.0.0",
- "es-define-property": "^1.0.1",
- "es-errors": "^1.3.0",
- "is-callable": "^1.2.7",
- "is-date-object": "^1.1.0",
- "is-symbol": "^1.1.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/esbuild": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
- "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
- "dev": true,
- "hasInstallScript": true,
- "bin": {
- "esbuild": "bin/esbuild"
- },
- "engines": {
- "node": ">=12"
- },
- "optionalDependencies": {
- "@esbuild/android-arm": "0.18.20",
- "@esbuild/android-arm64": "0.18.20",
- "@esbuild/android-x64": "0.18.20",
- "@esbuild/darwin-arm64": "0.18.20",
- "@esbuild/darwin-x64": "0.18.20",
- "@esbuild/freebsd-arm64": "0.18.20",
- "@esbuild/freebsd-x64": "0.18.20",
- "@esbuild/linux-arm": "0.18.20",
- "@esbuild/linux-arm64": "0.18.20",
- "@esbuild/linux-ia32": "0.18.20",
- "@esbuild/linux-loong64": "0.18.20",
- "@esbuild/linux-mips64el": "0.18.20",
- "@esbuild/linux-ppc64": "0.18.20",
- "@esbuild/linux-riscv64": "0.18.20",
- "@esbuild/linux-s390x": "0.18.20",
- "@esbuild/linux-x64": "0.18.20",
- "@esbuild/netbsd-x64": "0.18.20",
- "@esbuild/openbsd-x64": "0.18.20",
- "@esbuild/sunos-x64": "0.18.20",
- "@esbuild/win32-arm64": "0.18.20",
- "@esbuild/win32-ia32": "0.18.20",
- "@esbuild/win32-x64": "0.18.20"
- }
- },
- "node_modules/escalade": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
- "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/esm": {
- "version": "3.2.25",
- "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
- "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/event-target-shim": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
- "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/extend": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
- "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
- },
- "node_modules/extsprintf": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
- "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==",
- "engines": [
- "node >=0.6.0"
- ]
- },
- "node_modules/fast-deep-equal": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
- },
- "node_modules/fast-json-stable-stringify": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
- "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
- },
- "node_modules/fetch-blob": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-2.1.2.tgz",
- "integrity": "sha512-YKqtUDwqLyfyMnmbw8XD6Q8j9i/HggKtPEI+pZ1+8bvheBu78biSmNaXWusx1TauGqtUUGx/cBb1mKdq2rLYow==",
- "engines": {
- "node": "^10.17.0 || >=12.3.0"
- },
- "peerDependenciesMeta": {
- "domexception": {
- "optional": true
- }
- }
- },
- "node_modules/fill-range": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
- "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
- "dev": true,
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/follow-redirects": {
- "version": "1.16.0",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz",
- "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==",
- "funding": [
- {
- "type": "individual",
- "url": "https://github.com/sponsors/RubenVerborgh"
- }
- ],
- "engines": {
- "node": ">=4.0"
- },
- "peerDependenciesMeta": {
- "debug": {
- "optional": true
- }
- }
- },
- "node_modules/for-each": {
- "version": "0.3.5",
- "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
- "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
- "dependencies": {
- "is-callable": "^1.2.7"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/forever-agent": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
- "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==",
- "engines": {
- "node": "*"
- }
- },
- "node_modules/form-data": {
- "version": "4.0.6",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz",
- "integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==",
- "dependencies": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.8",
- "es-set-tostringtag": "^2.1.0",
- "hasown": "^2.0.4",
- "mime-types": "^2.1.35"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/fs-extra": {
- "version": "11.1.1",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz",
- "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==",
- "dev": true,
- "dependencies": {
- "graceful-fs": "^4.2.0",
- "jsonfile": "^6.0.1",
- "universalify": "^2.0.0"
- },
- "engines": {
- "node": ">=14.14"
- }
- },
- "node_modules/fsevents": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
- "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "dev": true,
- "hasInstallScript": true,
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
- "node_modules/function-bind": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
- "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/function.prototype.name": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.2.0.tgz",
- "integrity": "sha512-jObKIik1P2QjPHP5nz5BaOtUlfgS0fWo8IUByNXkM+o+02sJOi94em77GwJKQSJ3gfPHdgzLNrHc1uokV4P/ew==",
- "dependencies": {
- "call-bind": "^1.0.9",
- "call-bound": "^1.0.4",
- "es-define-property": "^1.0.1",
- "es-errors": "^1.3.0",
- "functions-have-names": "^1.2.3",
- "has-property-descriptors": "^1.0.2",
- "hasown": "^2.0.4",
- "is-callable": "^1.2.7",
- "is-document.all": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/functions-have-names": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
- "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/generator-function": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz",
- "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/gensync": {
- "version": "1.0.0-beta.2",
- "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
- "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
- "dev": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/get-func-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz",
- "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==",
- "dev": true,
- "engines": {
- "node": "*"
- }
- },
- "node_modules/get-intrinsic": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
- "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.2",
- "es-define-property": "^1.0.1",
- "es-errors": "^1.3.0",
- "es-object-atoms": "^1.1.1",
- "function-bind": "^1.1.2",
- "get-proto": "^1.0.1",
- "gopd": "^1.2.0",
- "has-symbols": "^1.1.0",
- "hasown": "^2.0.2",
- "math-intrinsics": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/get-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
- "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
- "dependencies": {
- "dunder-proto": "^1.0.1",
- "es-object-atoms": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/get-symbol-description": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz",
- "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==",
- "dependencies": {
- "call-bound": "^1.0.3",
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.6"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/getpass": {
- "version": "0.1.7",
- "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
- "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==",
- "dependencies": {
- "assert-plus": "^1.0.0"
- }
- },
- "node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dev": true,
- "dependencies": {
- "is-glob": "^4.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/global": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz",
- "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==",
- "dependencies": {
- "min-document": "^2.19.0",
- "process": "^0.11.10"
- }
- },
- "node_modules/globalthis": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
- "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
- "dependencies": {
- "define-properties": "^1.2.1",
- "gopd": "^1.0.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/gopd": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
- "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/graceful-fs": {
- "version": "4.2.11",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
- "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
- "dev": true
- },
- "node_modules/har-schema": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
- "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/har-validator": {
- "version": "5.1.5",
- "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
- "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
- "deprecated": "this library is no longer supported",
- "dependencies": {
- "ajv": "^6.12.3",
- "har-schema": "^2.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/has-bigints": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
- "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/has-property-descriptors": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
- "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
- "dependencies": {
- "es-define-property": "^1.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/has-proto": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz",
- "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==",
- "dependencies": {
- "dunder-proto": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/has-symbols": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
- "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/has-tostringtag": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
- "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
- "dependencies": {
- "has-symbols": "^1.0.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/hasown": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz",
- "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
- "dependencies": {
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/hoist-non-react-statics": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
- "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
- "dependencies": {
- "react-is": "^16.7.0"
- }
- },
- "node_modules/hoist-non-react-statics/node_modules/react-is": {
- "version": "16.13.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
- "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
- },
- "node_modules/html-encoding-sniffer": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
- "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==",
- "dev": true,
- "dependencies": {
- "whatwg-encoding": "^2.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/http-proxy-agent": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
- "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
- "dev": true,
- "dependencies": {
- "@tootallnate/once": "2",
- "agent-base": "6",
- "debug": "4"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/http-signature": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
- "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==",
- "dependencies": {
- "assert-plus": "^1.0.0",
- "jsprim": "^1.2.2",
- "sshpk": "^1.7.0"
- },
- "engines": {
- "node": ">=0.8",
- "npm": ">=1.3.7"
- }
- },
- "node_modules/https-proxy-agent": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
- "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
- "dev": true,
- "dependencies": {
- "agent-base": "6",
- "debug": "4"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/iconv-lite": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
- "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
- "dev": true,
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/immediate": {
- "version": "3.0.6",
- "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
- "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="
- },
- "node_modules/immutable": {
- "version": "4.3.9",
- "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.9.tgz",
- "integrity": "sha512-ObHy4YN7ycwZOUCLI1/6svfyAFu7vL8RhAvVu/bh/RZW9EPlOyDaQ9jDQWCtdqzaXUjgXZCW1migtHE7YI7UGQ==",
- "dev": true
- },
- "node_modules/indent-string": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
- "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
- },
- "node_modules/internal-slot": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
- "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==",
- "dependencies": {
- "es-errors": "^1.3.0",
- "hasown": "^2.0.2",
- "side-channel": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/inversify": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/inversify/-/inversify-5.1.1.tgz",
- "integrity": "sha512-j8grHGDzv1v+8T1sAQ+3boTCntFPfvxLCkNcxB1J8qA0lUN+fAlSyYd+RXKvaPRL4AGyPxViutBEJHNXOyUdFQ=="
- },
- "node_modules/is-arguments": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz",
- "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==",
- "dev": true,
- "dependencies": {
- "call-bound": "^1.0.2",
- "has-tostringtag": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-array-buffer": {
- "version": "3.0.5",
- "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
- "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==",
- "dependencies": {
- "call-bind": "^1.0.8",
- "call-bound": "^1.0.3",
- "get-intrinsic": "^1.2.6"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-async-function": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz",
- "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==",
- "dependencies": {
- "async-function": "^1.0.0",
- "call-bound": "^1.0.3",
- "get-proto": "^1.0.1",
- "has-tostringtag": "^1.0.2",
- "safe-regex-test": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-bigint": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz",
- "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==",
- "dependencies": {
- "has-bigints": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-binary-path": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
- "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
- "dev": true,
- "dependencies": {
- "binary-extensions": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-boolean-object": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz",
- "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==",
- "dependencies": {
- "call-bound": "^1.0.3",
- "has-tostringtag": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-callable": {
- "version": "1.2.7",
- "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
- "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-data-view": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz",
- "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==",
- "dependencies": {
- "call-bound": "^1.0.2",
- "get-intrinsic": "^1.2.6",
- "is-typed-array": "^1.1.13"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-date-object": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
- "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
- "dependencies": {
- "call-bound": "^1.0.2",
- "has-tostringtag": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-document.all": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-document.all/-/is-document.all-1.0.0.tgz",
- "integrity": "sha512-+XSoyS05OdBbhFuELhgTCpFNHkpBOJqtsZfUFFpe5QTw+9Sjbh8zitxhQkYAo6wV7e1Vb8cAPvpCk9jGam/82g==",
- "dependencies": {
- "call-bound": "^1.0.4"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-finalizationregistry": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz",
- "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==",
- "dependencies": {
- "call-bound": "^1.0.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-generator-function": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz",
- "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==",
- "dependencies": {
- "call-bound": "^1.0.4",
- "generator-function": "^2.0.0",
- "get-proto": "^1.0.1",
- "has-tostringtag": "^1.0.2",
- "safe-regex-test": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dev": true,
- "dependencies": {
- "is-extglob": "^2.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-map": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
- "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-negative-zero": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
- "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true,
- "engines": {
- "node": ">=0.12.0"
- }
- },
- "node_modules/is-number-object": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz",
- "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==",
- "dependencies": {
- "call-bound": "^1.0.3",
- "has-tostringtag": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-potential-custom-element-name": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
- "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
- "dev": true
- },
- "node_modules/is-regex": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
- "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
- "dependencies": {
- "call-bound": "^1.0.2",
- "gopd": "^1.2.0",
- "has-tostringtag": "^1.0.2",
- "hasown": "^2.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-set": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
- "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-shared-array-buffer": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz",
- "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==",
- "dependencies": {
- "call-bound": "^1.0.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-string": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz",
- "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==",
- "dependencies": {
- "call-bound": "^1.0.3",
- "has-tostringtag": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-symbol": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz",
- "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==",
- "dependencies": {
- "call-bound": "^1.0.2",
- "has-symbols": "^1.1.0",
- "safe-regex-test": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-typed-array": {
- "version": "1.1.15",
- "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
- "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
- "dependencies": {
- "which-typed-array": "^1.1.16"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-typedarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
- "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA=="
- },
- "node_modules/is-weakmap": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
- "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-weakref": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz",
- "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==",
- "dependencies": {
- "call-bound": "^1.0.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-weakset": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz",
- "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==",
- "dependencies": {
- "call-bound": "^1.0.3",
- "get-intrinsic": "^1.2.6"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
- },
- "node_modules/isstream": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
- "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g=="
- },
- "node_modules/jquery": {
- "version": "3.7.1",
- "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz",
- "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg=="
- },
- "node_modules/js-tokens": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
- },
- "node_modules/jsbn": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
- "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg=="
- },
- "node_modules/jsdom": {
- "version": "22.1.0",
- "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-22.1.0.tgz",
- "integrity": "sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==",
- "dev": true,
- "dependencies": {
- "abab": "^2.0.6",
- "cssstyle": "^3.0.0",
- "data-urls": "^4.0.0",
- "decimal.js": "^10.4.3",
- "domexception": "^4.0.0",
- "form-data": "^4.0.0",
- "html-encoding-sniffer": "^3.0.0",
- "http-proxy-agent": "^5.0.0",
- "https-proxy-agent": "^5.0.1",
- "is-potential-custom-element-name": "^1.0.1",
- "nwsapi": "^2.2.4",
- "parse5": "^7.1.2",
- "rrweb-cssom": "^0.6.0",
- "saxes": "^6.0.0",
- "symbol-tree": "^3.2.4",
- "tough-cookie": "^4.1.2",
- "w3c-xmlserializer": "^4.0.0",
- "webidl-conversions": "^7.0.0",
- "whatwg-encoding": "^2.0.0",
- "whatwg-mimetype": "^3.0.0",
- "whatwg-url": "^12.0.1",
- "ws": "^8.13.0",
- "xml-name-validator": "^4.0.0"
- },
- "engines": {
- "node": ">=16"
- },
- "peerDependencies": {
- "canvas": "^2.5.0"
- },
- "peerDependenciesMeta": {
- "canvas": {
- "optional": true
- }
- }
- },
- "node_modules/jsesc": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
- "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
- "dev": true,
- "bin": {
- "jsesc": "bin/jsesc"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/json-schema": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
- "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
- },
- "node_modules/json-schema-traverse": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
- },
- "node_modules/json-stringify-safe": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
- "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="
- },
- "node_modules/json5": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
- "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
- "dev": true,
- "bin": {
- "json5": "lib/cli.js"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/jsonfile": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz",
- "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==",
- "dev": true,
- "dependencies": {
- "universalify": "^2.0.0"
- },
- "optionalDependencies": {
- "graceful-fs": "^4.1.6"
- }
- },
- "node_modules/jsonld": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/jsonld/-/jsonld-5.2.0.tgz",
- "integrity": "sha512-JymgT6Xzk5CHEmHuEyvoTNviEPxv6ihLWSPu1gFdtjSAyM6cFqNrv02yS/SIur3BBIkCf0HjizRc24d8/FfQKw==",
- "dependencies": {
- "@digitalbazaar/http-client": "^1.1.0",
- "canonicalize": "^1.0.1",
- "lru-cache": "^6.0.0",
- "rdf-canonize": "^3.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/jsonld-signatures": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/jsonld-signatures/-/jsonld-signatures-7.0.0.tgz",
- "integrity": "sha512-J/nA+llcYYjErPHG9WFpXvR82TOg5fbHk/7rXbx4Ts854DPReaKAAd0hAZ+s5/P2WIIAZPIHCqA+iz1QrOqeiQ==",
- "dependencies": {
- "base64url": "^3.0.1",
- "crypto-ld": "^3.7.0",
- "jsonld": "^4.0.1",
- "node-forge": "^0.10.0",
- "security-context": "^4.0.0",
- "serialize-error": "^5.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/jsonld-signatures/node_modules/jsonld": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/jsonld/-/jsonld-4.0.1.tgz",
- "integrity": "sha512-ltEqMQB37ZxZnsgmI+9rqHYkz1M6PqUykuS1t2aQNuH1oiLrUDYz5nyVkHQDgjFd7CFKTIWeLiNhwdwFrH5o5A==",
- "dependencies": {
- "canonicalize": "^1.0.1",
- "lru-cache": "^5.1.1",
- "object.fromentries": "^2.0.2",
- "rdf-canonize": "^2.0.1",
- "request": "^2.88.0",
- "semver": "^6.3.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/jsonld-signatures/node_modules/rdf-canonize": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/rdf-canonize/-/rdf-canonize-2.0.1.tgz",
- "integrity": "sha512-/GVELjrfW8G/wS4QfDZ5Kq68cS1belVNJqZlcwiErerexeBUsgOINCROnP7UumWIBNdeCwTVLE9NVXMnRYK0lA==",
- "dependencies": {
- "semver": "^6.3.0",
- "setimmediate": "^1.0.5"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/jsonld/node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/jsonld/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
- },
- "node_modules/jsprim": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
- "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
- "dependencies": {
- "assert-plus": "1.0.0",
- "extsprintf": "1.3.0",
- "json-schema": "0.4.0",
- "verror": "1.10.0"
- },
- "engines": {
- "node": ">=0.6.0"
- }
- },
- "node_modules/jszip": {
- "version": "3.10.1",
- "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
- "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==",
- "dependencies": {
- "lie": "~3.3.0",
- "pako": "~1.0.2",
- "readable-stream": "~2.3.6",
- "setimmediate": "^1.0.5"
- }
- },
- "node_modules/katex": {
- "version": "0.16.10",
- "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.10.tgz",
- "integrity": "sha512-ZiqaC04tp2O5utMsl2TEZTXxa6WSC4yo0fv5ML++D3QZv/vx2Mct0mTlRx3O+uUkjfuAgOkzsCmq5MiUEsDDdA==",
- "funding": [
- "https://opencollective.com/katex",
- "https://github.com/sponsors/katex"
- ],
- "dependencies": {
- "commander": "^8.3.0"
- },
- "bin": {
- "katex": "cli.js"
- }
- },
- "node_modules/ky": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/ky/-/ky-0.25.1.tgz",
- "integrity": "sha512-PjpCEWlIU7VpiMVrTwssahkYXX1by6NCT0fhTUX34F3DTinARlgMpriuroolugFPcMgpPWrOW4mTb984Qm1RXA==",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sindresorhus/ky?sponsor=1"
- }
- },
- "node_modules/ky-universal": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/ky-universal/-/ky-universal-0.8.2.tgz",
- "integrity": "sha512-xe0JaOH9QeYxdyGLnzUOVGK4Z6FGvDVzcXFTdrYA1f33MZdEa45sUDaMBy98xQMcsd2XIBrTXRrRYnegcSdgVQ==",
- "dependencies": {
- "abort-controller": "^3.0.0",
- "node-fetch": "3.0.0-beta.9"
- },
- "engines": {
- "node": ">=10.17"
- },
- "funding": {
- "url": "https://github.com/sindresorhus/ky-universal?sponsor=1"
- },
- "peerDependencies": {
- "ky": ">=0.17.0",
- "web-streams-polyfill": ">=2.0.0"
- },
- "peerDependenciesMeta": {
- "web-streams-polyfill": {
- "optional": true
- }
- }
- },
- "node_modules/ky-universal/node_modules/node-fetch": {
- "version": "3.0.0-beta.9",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.0.0-beta.9.tgz",
- "integrity": "sha512-RdbZCEynH2tH46+tj0ua9caUHVWrd/RHnRfvly2EVdqGmI3ndS1Vn/xjm5KuGejDt2RNDQsVRLPNd2QPwcewVg==",
- "dependencies": {
- "data-uri-to-buffer": "^3.0.1",
- "fetch-blob": "^2.1.1"
- },
- "engines": {
- "node": "^10.17 || >=12.3"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/node-fetch"
- }
- },
- "node_modules/lie": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
- "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
- "dependencies": {
- "immediate": "~3.0.5"
- }
- },
- "node_modules/local-pkg": {
- "version": "0.4.3",
- "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz",
- "integrity": "sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==",
- "dev": true,
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/antfu"
- }
- },
- "node_modules/lodash": {
- "version": "4.18.1",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
- "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
- "dev": true
- },
- "node_modules/lodash-es": {
- "version": "4.17.21",
- "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
- "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
- },
- "node_modules/loose-envify": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
- "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
- "dependencies": {
- "js-tokens": "^3.0.0 || ^4.0.0"
- },
- "bin": {
- "loose-envify": "cli.js"
- }
- },
- "node_modules/loupe": {
- "version": "2.3.7",
- "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz",
- "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==",
- "dev": true,
- "dependencies": {
- "get-func-name": "^2.0.1"
- }
- },
- "node_modules/lru-cache": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
- "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
- "dependencies": {
- "yallist": "^3.0.2"
- }
- },
- "node_modules/lz-string": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
- "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
- "dev": true,
- "bin": {
- "lz-string": "bin/bin.js"
- }
- },
- "node_modules/magic-string": {
- "version": "0.30.21",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
- "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
- "dev": true,
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.5"
- }
- },
- "node_modules/math-intrinsics": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
- "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/mime-db": {
- "version": "1.52.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
- "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/mime-types": {
- "version": "2.1.35",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
- "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
- "dependencies": {
- "mime-db": "1.52.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/min-document": {
- "version": "2.19.2",
- "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.2.tgz",
- "integrity": "sha512-8S5I8db/uZN8r9HSLFVWPdJCvYOejMcEC82VIzNUc6Zkklf/d1gg2psfE79/vyhWOj4+J8MtwmoOz3TmvaGu5A==",
- "dependencies": {
- "dom-walk": "^0.1.0"
- }
- },
- "node_modules/min-indent": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
- "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/mlly": {
- "version": "1.8.2",
- "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.2.tgz",
- "integrity": "sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==",
- "dev": true,
- "dependencies": {
- "acorn": "^8.16.0",
- "pathe": "^2.0.3",
- "pkg-types": "^1.3.1",
- "ufo": "^1.6.3"
- }
- },
- "node_modules/mlly/node_modules/pathe": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
- "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
- "dev": true
- },
- "node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true
- },
- "node_modules/nanoid": {
- "version": "3.3.15",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz",
- "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "bin": {
- "nanoid": "bin/nanoid.cjs"
- },
- "engines": {
- "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
- }
- },
- "node_modules/node-fetch": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
- "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
- "dependencies": {
- "whatwg-url": "^5.0.0"
- },
- "engines": {
- "node": "4.x || >=6.0.0"
- },
- "peerDependencies": {
- "encoding": "^0.1.0"
- },
- "peerDependenciesMeta": {
- "encoding": {
- "optional": true
- }
- }
- },
- "node_modules/node-fetch/node_modules/tr46": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
- "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
- },
- "node_modules/node-fetch/node_modules/webidl-conversions": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
- "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
- },
- "node_modules/node-fetch/node_modules/whatwg-url": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
- "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
- "dependencies": {
- "tr46": "~0.0.3",
- "webidl-conversions": "^3.0.0"
- }
- },
- "node_modules/node-forge": {
- "version": "0.10.0",
- "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
- "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==",
- "engines": {
- "node": ">= 6.0.0"
- }
- },
- "node_modules/node-gyp-build": {
- "version": "4.8.4",
- "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz",
- "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==",
- "optional": true,
- "bin": {
- "node-gyp-build": "bin.js",
- "node-gyp-build-optional": "optional.js",
- "node-gyp-build-test": "build-test.js"
- }
- },
- "node_modules/node-releases": {
- "version": "2.0.50",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.50.tgz",
- "integrity": "sha512-J6l92tKHX6w8Jy5nO1Vuc01NoIiRGi/d6qBKVxh+IQ8Cr3b6HbVNfKiF8ZpFKufTwpwxMmce2W3iQZ861ZRyTg==",
- "dev": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/normalize-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/nwsapi": {
- "version": "2.2.24",
- "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.24.tgz",
- "integrity": "sha512-7YRhZ3jS45LwmSCT4b2sVFHt/WuovaktDU07QrtOBY2PXskss5a9jfmR9jptyumwXST+rFjrmppMY1KT/yn35A==",
- "dev": true
- },
- "node_modules/oauth-sign": {
- "version": "0.9.0",
- "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
- "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
- "engines": {
- "node": "*"
- }
- },
- "node_modules/object-inspect": {
- "version": "1.13.4",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
- "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/object-is": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz",
- "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==",
- "dev": true,
- "dependencies": {
- "call-bind": "^1.0.7",
- "define-properties": "^1.2.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/object-keys": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
- "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/object.assign": {
- "version": "4.1.7",
- "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz",
- "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==",
- "dependencies": {
- "call-bind": "^1.0.8",
- "call-bound": "^1.0.3",
- "define-properties": "^1.2.1",
- "es-object-atoms": "^1.0.0",
- "has-symbols": "^1.1.0",
- "object-keys": "^1.1.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/object.fromentries": {
- "version": "2.0.8",
- "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz",
- "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==",
- "dependencies": {
- "call-bind": "^1.0.7",
- "define-properties": "^1.2.1",
- "es-abstract": "^1.23.2",
- "es-object-atoms": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/own-keys": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz",
- "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==",
- "dependencies": {
- "get-intrinsic": "^1.2.6",
- "object-keys": "^1.1.1",
- "safe-push-apply": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/p-limit": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz",
- "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==",
- "dev": true,
- "dependencies": {
- "yocto-queue": "^1.0.0"
- },
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/pako": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
- "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
- },
- "node_modules/parse5": {
- "version": "7.3.0",
- "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
- "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
- "dev": true,
- "dependencies": {
- "entities": "^6.0.0"
- },
- "funding": {
- "url": "https://github.com/inikulin/parse5?sponsor=1"
- }
- },
- "node_modules/path-browserify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
- "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g=="
- },
- "node_modules/pathe": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz",
- "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==",
- "dev": true
- },
- "node_modules/pathval": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
- "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==",
- "dev": true,
- "engines": {
- "node": "*"
- }
- },
- "node_modules/performance-now": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
- "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow=="
- },
- "node_modules/picocolors": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
- "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
- "dev": true
- },
- "node_modules/picomatch": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
- "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
- "dev": true,
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/pkg-types": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz",
- "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==",
- "dev": true,
- "dependencies": {
- "confbox": "^0.1.8",
- "mlly": "^1.7.4",
- "pathe": "^2.0.1"
- }
- },
- "node_modules/pkg-types/node_modules/pathe": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
- "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
- "dev": true
- },
- "node_modules/platform": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.3.tgz",
- "integrity": "sha512-VJK1SRmXBpjwsB4YOHYSturx48rLKMzHgCqDH2ZDa6ZbMS/N5huoNqyQdK5Fj/xayu3fqbXckn5SeCS1EbMDZg==",
- "peer": true
- },
- "node_modules/possible-typed-array-names": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
- "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/postcss": {
- "version": "8.5.16",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.16.tgz",
- "integrity": "sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/postcss"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "dependencies": {
- "nanoid": "^3.3.12",
- "picocolors": "^1.1.1",
- "source-map-js": "^1.2.1"
- },
- "engines": {
- "node": "^10 || ^12 || >=14"
- }
- },
- "node_modules/pretty-format": {
- "version": "27.5.1",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
- "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
- "dev": true,
- "dependencies": {
- "ansi-regex": "^5.0.1",
- "ansi-styles": "^5.0.0",
- "react-is": "^17.0.1"
- },
- "engines": {
- "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
- }
- },
- "node_modules/pretty-format/node_modules/ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/process": {
- "version": "0.11.10",
- "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
- "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
- "engines": {
- "node": ">= 0.6.0"
- }
- },
- "node_modules/process-nextick-args": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
- "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
- },
- "node_modules/proxy-from-env": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
- "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
- },
- "node_modules/psl": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz",
- "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==",
- "dependencies": {
- "punycode": "^2.3.1"
- },
- "funding": {
- "url": "https://github.com/sponsors/lupomontero"
- }
- },
- "node_modules/punycode": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
- "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/qs": {
- "version": "6.9.7",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz",
- "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==",
- "engines": {
- "node": ">=0.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/querystringify": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
- "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
- "dev": true
- },
- "node_modules/randombytes": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
- "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
- "dev": true,
- "dependencies": {
- "safe-buffer": "^5.1.0"
- }
- },
- "node_modules/rdf-canonize": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/rdf-canonize/-/rdf-canonize-3.4.0.tgz",
- "integrity": "sha512-fUeWjrkOO0t1rg7B2fdyDTvngj+9RlUyL92vOdiB7c0FPguWVsniIMjEtHH+meLBO9rzkUlUzBVXgWrjI8P9LA==",
- "dependencies": {
- "setimmediate": "^1.0.5"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/react": {
- "version": "18.2.0",
- "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
- "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
- "dependencies": {
- "loose-envify": "^1.1.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/react-dnd": {
- "version": "16.0.1",
- "resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-16.0.1.tgz",
- "integrity": "sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==",
- "dependencies": {
- "@react-dnd/invariant": "^4.0.1",
- "@react-dnd/shallowequal": "^4.0.1",
- "dnd-core": "^16.0.1",
- "fast-deep-equal": "^3.1.3",
- "hoist-non-react-statics": "^3.3.2"
- },
- "peerDependencies": {
- "@types/hoist-non-react-statics": ">= 3.3.1",
- "@types/node": ">= 12",
- "@types/react": ">= 16",
- "react": ">= 16.14"
- },
- "peerDependenciesMeta": {
- "@types/hoist-non-react-statics": {
- "optional": true
- },
- "@types/node": {
- "optional": true
- },
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/react-dnd-html5-backend": {
- "version": "16.0.1",
- "resolved": "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-16.0.1.tgz",
- "integrity": "sha512-Wu3dw5aDJmOGw8WjH1I1/yTH+vlXEL4vmjk5p+MHxP8HuHJS1lAGeIdG/hze1AvNeXWo/JgULV87LyQOr+r5jw==",
- "dependencies": {
- "dnd-core": "^16.0.1"
- }
- },
- "node_modules/react-dom": {
- "version": "18.2.0",
- "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
- "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
- "dependencies": {
- "loose-envify": "^1.1.0",
- "scheduler": "^0.23.0"
- },
- "peerDependencies": {
- "react": "^18.2.0"
- }
- },
- "node_modules/react-is": {
- "version": "17.0.2",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
- "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
- "dev": true
- },
- "node_modules/react-refresh": {
- "version": "0.14.2",
- "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
- "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/readable-stream": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
- "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
- "dependencies": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "node_modules/readable-stream/node_modules/safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
- },
- "node_modules/readdirp": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
- "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
- "dev": true,
- "dependencies": {
- "picomatch": "^2.2.1"
- },
- "engines": {
- "node": ">=8.10.0"
- }
- },
- "node_modules/redent": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
- "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
- "dev": true,
- "dependencies": {
- "indent-string": "^4.0.0",
- "strip-indent": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/redux": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
- "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
- "dependencies": {
- "@babel/runtime": "^7.9.2"
- }
- },
- "node_modules/reflect-metadata": {
- "version": "0.1.13",
- "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz",
- "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg=="
- },
- "node_modules/reflect.getprototypeof": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
- "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==",
- "dependencies": {
- "call-bind": "^1.0.8",
- "define-properties": "^1.2.1",
- "es-abstract": "^1.23.9",
- "es-errors": "^1.3.0",
- "es-object-atoms": "^1.0.0",
- "get-intrinsic": "^1.2.7",
- "get-proto": "^1.0.1",
- "which-builtin-type": "^1.2.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/regexp.prototype.flags": {
- "version": "1.5.4",
- "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz",
- "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==",
- "dependencies": {
- "call-bind": "^1.0.8",
- "define-properties": "^1.2.1",
- "es-errors": "^1.3.0",
- "get-proto": "^1.0.1",
- "gopd": "^1.2.0",
- "set-function-name": "^2.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/request": {
- "version": "2.88.2",
- "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
- "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
- "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142",
- "dependencies": {
- "aws-sign2": "~0.7.0",
- "aws4": "^1.8.0",
- "caseless": "~0.12.0",
- "combined-stream": "~1.0.6",
- "extend": "~3.0.2",
- "forever-agent": "~0.6.1",
- "form-data": "~2.3.2",
- "har-validator": "~5.1.3",
- "http-signature": "~1.2.0",
- "is-typedarray": "~1.0.0",
- "isstream": "~0.1.2",
- "json-stringify-safe": "~5.0.1",
- "mime-types": "~2.1.19",
- "oauth-sign": "~0.9.0",
- "performance-now": "^2.1.0",
- "qs": "~6.5.2",
- "safe-buffer": "^5.1.2",
- "tough-cookie": "~2.5.0",
- "tunnel-agent": "^0.6.0",
- "uuid": "^3.3.2"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/request/node_modules/form-data": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
- "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
- "dependencies": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.6",
- "mime-types": "^2.1.12"
- },
- "engines": {
- "node": ">= 0.12"
- }
- },
- "node_modules/request/node_modules/qs": {
- "version": "6.5.5",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.5.tgz",
- "integrity": "sha512-mzR4sElr1bfCaPJe7m8ilJ6ZXdDaGoObcYR0ZHSsktM/Lt21MVHj5De30GQH2eiZ1qGRTO7LCAzQsUeXTNexWQ==",
- "engines": {
- "node": ">=0.6"
- }
- },
- "node_modules/request/node_modules/tough-cookie": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
- "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
- "dependencies": {
- "psl": "^1.1.28",
- "punycode": "^2.1.1"
- },
- "engines": {
- "node": ">=0.8"
- }
- },
- "node_modules/request/node_modules/uuid": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
- "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
- "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).",
- "bin": {
- "uuid": "bin/uuid"
- }
- },
- "node_modules/requires-port": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
- "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
- "dev": true
- },
- "node_modules/rollup": {
- "version": "3.29.0",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.0.tgz",
- "integrity": "sha512-nszM8DINnx1vSS+TpbWKMkxem0CDWk3cSit/WWCBVs9/JZ1I/XLwOsiUglYuYReaeWWSsW9kge5zE5NZtf/a4w==",
- "dev": true,
- "bin": {
- "rollup": "dist/bin/rollup"
- },
- "engines": {
- "node": ">=14.18.0",
- "npm": ">=8.0.0"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
- }
- },
- "node_modules/rrweb-cssom": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz",
- "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==",
- "dev": true
- },
- "node_modules/rxjs": {
- "version": "7.8.2",
- "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
- "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==",
- "peer": true,
- "dependencies": {
- "tslib": "^2.1.0"
- }
- },
- "node_modules/safe-array-concat": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.4.tgz",
- "integrity": "sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==",
- "dependencies": {
- "call-bind": "^1.0.9",
- "call-bound": "^1.0.4",
- "get-intrinsic": "^1.3.0",
- "has-symbols": "^1.1.0",
- "isarray": "^2.0.5"
- },
- "engines": {
- "node": ">=0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/safe-array-concat/node_modules/isarray": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
- "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="
- },
- "node_modules/safe-buffer": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ]
- },
- "node_modules/safe-push-apply": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz",
- "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==",
- "dependencies": {
- "es-errors": "^1.3.0",
- "isarray": "^2.0.5"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/safe-push-apply/node_modules/isarray": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
- "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="
- },
- "node_modules/safe-regex-test": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
- "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
- "dependencies": {
- "call-bound": "^1.0.2",
- "es-errors": "^1.3.0",
- "is-regex": "^1.2.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
- },
- "node_modules/sass": {
- "version": "1.69.0",
- "resolved": "https://registry.npmjs.org/sass/-/sass-1.69.0.tgz",
- "integrity": "sha512-l3bbFpfTOGgQZCLU/gvm1lbsQ5mC/WnLz3djL2v4WCJBDrWm58PO+jgngcGRNnKUh6wSsdm50YaovTqskZ0xDQ==",
- "dev": true,
- "dependencies": {
- "chokidar": ">=3.0.0 <4.0.0",
- "immutable": "^4.0.0",
- "source-map-js": ">=0.6.2 <2.0.0"
- },
- "bin": {
- "sass": "sass.js"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/saxes": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
- "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==",
- "dev": true,
- "dependencies": {
- "xmlchars": "^2.2.0"
- },
- "engines": {
- "node": ">=v12.22.7"
- }
- },
- "node_modules/scheduler": {
- "version": "0.23.2",
- "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
- "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
- "dependencies": {
- "loose-envify": "^1.1.0"
- }
- },
- "node_modules/security-context": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/security-context/-/security-context-4.0.0.tgz",
- "integrity": "sha512-yiDCS7tpKQl6p4NG57BdKLTSNLFfj5HosBIzXBl4jZf/qorJzSzbEUIdLhN+vVYgyLlvjixY8DPPTgqI8zvNCA=="
- },
- "node_modules/semver": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
- "bin": {
- "semver": "bin/semver.js"
- }
- },
- "node_modules/serialize-error": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-5.0.0.tgz",
- "integrity": "sha512-/VtpuyzYf82mHYTtI4QKtwHa79vAdU5OQpNPAmE/0UDdlGT0ZxHwC+J6gXkw29wwoVI8fMPsfcVHOwXtUQYYQA==",
- "dependencies": {
- "type-fest": "^0.8.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/serialize-javascript": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
- "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
- "dev": true,
- "dependencies": {
- "randombytes": "^2.1.0"
- }
- },
- "node_modules/set-function-length": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
- "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
- "dependencies": {
- "define-data-property": "^1.1.4",
- "es-errors": "^1.3.0",
- "function-bind": "^1.1.2",
- "get-intrinsic": "^1.2.4",
- "gopd": "^1.0.1",
- "has-property-descriptors": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/set-function-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
- "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
- "dependencies": {
- "define-data-property": "^1.1.4",
- "es-errors": "^1.3.0",
- "functions-have-names": "^1.2.3",
- "has-property-descriptors": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/set-proto": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz",
- "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==",
- "dependencies": {
- "dunder-proto": "^1.0.1",
- "es-errors": "^1.3.0",
- "es-object-atoms": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/setimmediate": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
- "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="
- },
- "node_modules/side-channel": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz",
- "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==",
- "dependencies": {
- "es-errors": "^1.3.0",
- "object-inspect": "^1.13.4",
- "side-channel-list": "^1.0.1",
- "side-channel-map": "^1.0.1",
- "side-channel-weakmap": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/side-channel-list": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz",
- "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==",
- "dependencies": {
- "es-errors": "^1.3.0",
- "object-inspect": "^1.13.4"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/side-channel-map": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
- "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
- "dependencies": {
- "call-bound": "^1.0.2",
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.5",
- "object-inspect": "^1.13.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/side-channel-weakmap": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
- "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
- "dependencies": {
- "call-bound": "^1.0.2",
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.5",
- "object-inspect": "^1.13.3",
- "side-channel-map": "^1.0.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/siginfo": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
- "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
- "dev": true
- },
- "node_modules/smob": {
- "version": "1.6.2",
- "resolved": "https://registry.npmjs.org/smob/-/smob-1.6.2.tgz",
- "integrity": "sha512-RQsvleCbF8cVHEv+xuDGaA4pOizFqJ0GgjtMSRo6oP8pnN7WsigHgVGey6aILRBKv4W2YOMHLqbKdnB6hpB9fw==",
- "dev": true,
- "engines": {
- "node": ">=20.0.0"
- }
- },
- "node_modules/sodium-native": {
- "version": "3.4.1",
- "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-3.4.1.tgz",
- "integrity": "sha512-PaNN/roiFWzVVTL6OqjzYct38NSXewdl2wz8SRB51Br/MLIJPrbM3XexhVWkq7D3UWMysfrhKVf1v1phZq6MeQ==",
- "hasInstallScript": true,
- "optional": true,
- "dependencies": {
- "node-gyp-build": "^4.3.0"
- }
- },
- "node_modules/source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/source-map-js": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
- "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/source-map-support": {
- "version": "0.5.21",
- "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
- "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
- "dev": true,
- "dependencies": {
- "buffer-from": "^1.0.0",
- "source-map": "^0.6.0"
- }
- },
- "node_modules/sshpk": {
- "version": "1.18.0",
- "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz",
- "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==",
- "dependencies": {
- "asn1": "~0.2.3",
- "assert-plus": "^1.0.0",
- "bcrypt-pbkdf": "^1.0.0",
- "dashdash": "^1.12.0",
- "ecc-jsbn": "~0.1.1",
- "getpass": "^0.1.1",
- "jsbn": "~0.1.0",
- "safer-buffer": "^2.0.2",
- "tweetnacl": "~0.14.0"
- },
- "bin": {
- "sshpk-conv": "bin/sshpk-conv",
- "sshpk-sign": "bin/sshpk-sign",
- "sshpk-verify": "bin/sshpk-verify"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/stackback": {
- "version": "0.0.2",
- "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
- "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
- "dev": true
- },
- "node_modules/std-env": {
- "version": "3.10.0",
- "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz",
- "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==",
- "dev": true
- },
- "node_modules/stop-iteration-iterator": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz",
- "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==",
- "dependencies": {
- "es-errors": "^1.3.0",
- "internal-slot": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "dependencies": {
- "safe-buffer": "~5.1.0"
- }
- },
- "node_modules/string_decoder/node_modules/safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
- },
- "node_modules/string.prototype.trim": {
- "version": "1.2.11",
- "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.11.tgz",
- "integrity": "sha512-PwvK7BU+CMTJGYQCTZb5RWXIML92lftJLhQz1tBzgKiqGxJaMlBAa48POXaNAC2s4y8jr3EFqrkF9+44neS46w==",
- "dependencies": {
- "call-bind": "^1.0.9",
- "call-bound": "^1.0.4",
- "define-data-property": "^1.1.4",
- "define-properties": "^1.2.1",
- "es-abstract": "^1.24.2",
- "es-object-atoms": "^1.1.2",
- "has-property-descriptors": "^1.0.2",
- "safe-regex-test": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/string.prototype.trimend": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.10.tgz",
- "integrity": "sha512-2+3aDAOmPTmuFwjDnmJG2ctEkQKVki7vOSqaxkv42Mowj1V6PnvuwFCRrR5lChUux1TBskPjfkeTOhqczDMxTw==",
- "dependencies": {
- "call-bind": "^1.0.9",
- "call-bound": "^1.0.4",
- "define-properties": "^1.2.1",
- "es-object-atoms": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/string.prototype.trimstart": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz",
- "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==",
- "dependencies": {
- "call-bind": "^1.0.7",
- "define-properties": "^1.2.1",
- "es-object-atoms": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/strip-indent": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
- "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
- "dev": true,
- "dependencies": {
- "min-indent": "^1.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-literal": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.3.0.tgz",
- "integrity": "sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==",
- "dev": true,
- "dependencies": {
- "acorn": "^8.10.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/antfu"
- }
- },
- "node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/symbol-tree": {
- "version": "3.2.4",
- "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
- "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
- "dev": true
- },
- "node_modules/terser": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.48.0.tgz",
- "integrity": "sha512-J/9An6vs9Us6wKRriSFXBWdRZapREHqFzdNUKk0pmu804EMR6dr6winwo7e5JDxN4xahxQsuysyYFwlwj4XN/Q==",
- "dev": true,
- "dependencies": {
- "@jridgewell/source-map": "^0.3.3",
- "acorn": "^8.15.0",
- "commander": "^2.20.0",
- "source-map-support": "~0.5.20"
- },
- "bin": {
- "terser": "bin/terser"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/terser/node_modules/commander": {
- "version": "2.20.3",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
- "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
- "dev": true
- },
- "node_modules/tinybench": {
- "version": "2.9.0",
- "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
- "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
- "dev": true
- },
- "node_modules/tinypool": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.7.0.tgz",
- "integrity": "sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==",
- "dev": true,
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/tinyspy": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz",
- "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==",
- "dev": true,
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
- "node_modules/tough-cookie": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz",
- "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==",
- "dev": true,
- "dependencies": {
- "psl": "^1.1.33",
- "punycode": "^2.1.1",
- "universalify": "^0.2.0",
- "url-parse": "^1.5.3"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/tough-cookie/node_modules/universalify": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
- "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
- "dev": true,
- "engines": {
- "node": ">= 4.0.0"
- }
- },
- "node_modules/tr46": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz",
- "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==",
- "dev": true,
- "dependencies": {
- "punycode": "^2.3.0"
- },
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/tslib": {
- "version": "2.8.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
- "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
- },
- "node_modules/tunnel-agent": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
- "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
- "dependencies": {
- "safe-buffer": "^5.0.1"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/tweetnacl": {
- "version": "0.14.5",
- "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
- "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="
- },
- "node_modules/type-detect": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz",
- "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/type-fest": {
- "version": "0.8.1",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
- "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/typed-array-buffer": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
- "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
- "dependencies": {
- "call-bound": "^1.0.3",
- "es-errors": "^1.3.0",
- "is-typed-array": "^1.1.14"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/typed-array-byte-length": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz",
- "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==",
- "dependencies": {
- "call-bind": "^1.0.8",
- "for-each": "^0.3.3",
- "gopd": "^1.2.0",
- "has-proto": "^1.2.0",
- "is-typed-array": "^1.1.14"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/typed-array-byte-offset": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz",
- "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==",
- "dependencies": {
- "available-typed-arrays": "^1.0.7",
- "call-bind": "^1.0.8",
- "for-each": "^0.3.3",
- "gopd": "^1.2.0",
- "has-proto": "^1.2.0",
- "is-typed-array": "^1.1.15",
- "reflect.getprototypeof": "^1.0.9"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/typed-array-length": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.8.tgz",
- "integrity": "sha512-phPGCwqr2+Qo0fwniCE8e4pKnGu/yFb5nD5Y8bf0EEeiI5GklnACYA9GFy/DrAeRrKHXvHn+1SUsOWgJp6RO+g==",
- "dependencies": {
- "call-bind": "^1.0.9",
- "for-each": "^0.3.5",
- "gopd": "^1.2.0",
- "is-typed-array": "^1.1.15",
- "possible-typed-array-names": "^1.1.0",
- "reflect.getprototypeof": "^1.0.10"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/typescript": {
- "version": "5.9.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
- "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
- "dev": true,
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=14.17"
- }
- },
- "node_modules/ufo": {
- "version": "1.6.4",
- "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.4.tgz",
- "integrity": "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==",
- "dev": true
- },
- "node_modules/unbox-primitive": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz",
- "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==",
- "dependencies": {
- "call-bound": "^1.0.3",
- "has-bigints": "^1.0.2",
- "has-symbols": "^1.1.0",
- "which-boxed-primitive": "^1.1.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/undici-types": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
- "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
- "devOptional": true
- },
- "node_modules/universalify": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
- "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
- "dev": true,
- "engines": {
- "node": ">= 10.0.0"
- }
- },
- "node_modules/update-browserslist-db": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
- "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "dependencies": {
- "escalade": "^3.2.0",
- "picocolors": "^1.1.1"
- },
- "bin": {
- "update-browserslist-db": "cli.js"
- },
- "peerDependencies": {
- "browserslist": ">= 4.21.0"
- }
- },
- "node_modules/uri-js": {
- "version": "4.4.1",
- "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
- "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
- "dependencies": {
- "punycode": "^2.1.0"
- }
- },
- "node_modules/url-parse": {
- "version": "1.5.10",
- "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
- "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
- "dev": true,
- "dependencies": {
- "querystringify": "^2.1.1",
- "requires-port": "^1.0.0"
- }
- },
- "node_modules/util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
- },
- "node_modules/uuid": {
- "version": "9.0.1",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
- "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
- "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).",
- "funding": [
- "https://github.com/sponsors/broofa",
- "https://github.com/sponsors/ctavan"
- ],
- "bin": {
- "uuid": "dist/bin/uuid"
- }
- },
- "node_modules/verror": {
- "version": "1.10.0",
- "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
- "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==",
- "engines": [
- "node >=0.6.0"
- ],
- "dependencies": {
- "assert-plus": "^1.0.0",
- "core-util-is": "1.0.2",
- "extsprintf": "^1.2.0"
- }
- },
- "node_modules/verror/node_modules/core-util-is": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
- "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="
- },
- "node_modules/vite": {
- "version": "4.5.14",
- "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.14.tgz",
- "integrity": "sha512-+v57oAaoYNnO3hIu5Z/tJRZjq5aHM2zDve9YZ8HngVHbhk66RStobhb1sqPMIPEleV6cNKYK4eGrAbE9Ulbl2g==",
- "dev": true,
- "dependencies": {
- "esbuild": "^0.18.10",
- "postcss": "^8.4.27",
- "rollup": "^3.27.1"
- },
- "bin": {
- "vite": "bin/vite.js"
- },
- "engines": {
- "node": "^14.18.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/vitejs/vite?sponsor=1"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
- },
- "peerDependencies": {
- "@types/node": ">= 14",
- "less": "*",
- "lightningcss": "^1.21.0",
- "sass": "*",
- "stylus": "*",
- "sugarss": "*",
- "terser": "^5.4.0"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- },
- "less": {
- "optional": true
- },
- "lightningcss": {
- "optional": true
- },
- "sass": {
- "optional": true
- },
- "stylus": {
- "optional": true
- },
- "sugarss": {
- "optional": true
- },
- "terser": {
- "optional": true
- }
- }
- },
- "node_modules/vite-node": {
- "version": "0.34.0",
- "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.34.0.tgz",
- "integrity": "sha512-rGZMvpb052rjUwJA/a17xMfOibzNF7byMdRSTcN2Lw8uxX08s5EfjWW5mBkm3MSFTPctMSVtT2yC+8ShrZbT5g==",
- "dev": true,
- "dependencies": {
- "cac": "^6.7.14",
- "debug": "^4.3.4",
- "mlly": "^1.4.0",
- "pathe": "^1.1.1",
- "picocolors": "^1.0.0",
- "vite": "^3.0.0 || ^4.0.0"
- },
- "bin": {
- "vite-node": "vite-node.mjs"
- },
- "engines": {
- "node": ">=v14.18.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/vitest": {
- "version": "0.34.0",
- "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.34.0.tgz",
- "integrity": "sha512-8Pnc1fVt1P6uBncdUZ++hgiJGgxIRKuz4bmS/PQziaEcUj0D1g9cGiR1MbLrcsvFTC6fgrqDhYoTAdBG356WMA==",
- "dev": true,
- "dependencies": {
- "@types/chai": "^4.3.5",
- "@types/chai-subset": "^1.3.3",
- "@types/node": "*",
- "@vitest/expect": "0.34.0",
- "@vitest/runner": "0.34.0",
- "@vitest/snapshot": "0.34.0",
- "@vitest/spy": "0.34.0",
- "@vitest/utils": "0.34.0",
- "acorn": "^8.9.0",
- "acorn-walk": "^8.2.0",
- "cac": "^6.7.14",
- "chai": "^4.3.7",
- "debug": "^4.3.4",
- "local-pkg": "^0.4.3",
- "magic-string": "^0.30.1",
- "pathe": "^1.1.1",
- "picocolors": "^1.0.0",
- "std-env": "^3.3.3",
- "strip-literal": "^1.0.1",
- "tinybench": "^2.5.0",
- "tinypool": "^0.7.0",
- "vite": "^3.0.0 || ^4.0.0",
- "vite-node": "0.34.0",
- "why-is-node-running": "^2.2.2"
- },
- "bin": {
- "vitest": "vitest.mjs"
- },
- "engines": {
- "node": ">=v14.18.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- },
- "peerDependencies": {
- "@edge-runtime/vm": "*",
- "@vitest/browser": "*",
- "@vitest/ui": "*",
- "happy-dom": "*",
- "jsdom": "*",
- "playwright": "*",
- "safaridriver": "*",
- "webdriverio": "*"
- },
- "peerDependenciesMeta": {
- "@edge-runtime/vm": {
- "optional": true
- },
- "@vitest/browser": {
- "optional": true
- },
- "@vitest/ui": {
- "optional": true
- },
- "happy-dom": {
- "optional": true
- },
- "jsdom": {
- "optional": true
- },
- "playwright": {
- "optional": true
- },
- "safaridriver": {
- "optional": true
- },
- "webdriverio": {
- "optional": true
- }
- }
- },
- "node_modules/w3c-xmlserializer": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz",
- "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==",
- "dev": true,
- "dependencies": {
- "xml-name-validator": "^4.0.0"
- },
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/webidl-conversions": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
- "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
- "dev": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/whatwg-encoding": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
- "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==",
- "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation",
- "dev": true,
- "dependencies": {
- "iconv-lite": "0.6.3"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/whatwg-fetch": {
- "version": "3.6.19",
- "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.19.tgz",
- "integrity": "sha512-d67JP4dHSbm2TrpFj8AbO8DnL1JXL5J9u0Kq2xW6d0TFDbCA3Muhdt8orXC22utleTVj7Prqt82baN6RBvnEgw=="
- },
- "node_modules/whatwg-mimetype": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz",
- "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==",
- "dev": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/whatwg-url": {
- "version": "12.0.1",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz",
- "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==",
- "dev": true,
- "dependencies": {
- "tr46": "^4.1.1",
- "webidl-conversions": "^7.0.0"
- },
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/which-boxed-primitive": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz",
- "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==",
- "dependencies": {
- "is-bigint": "^1.1.0",
- "is-boolean-object": "^1.2.1",
- "is-number-object": "^1.1.1",
- "is-string": "^1.1.1",
- "is-symbol": "^1.1.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/which-builtin-type": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz",
- "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==",
- "dependencies": {
- "call-bound": "^1.0.2",
- "function.prototype.name": "^1.1.6",
- "has-tostringtag": "^1.0.2",
- "is-async-function": "^2.0.0",
- "is-date-object": "^1.1.0",
- "is-finalizationregistry": "^1.1.0",
- "is-generator-function": "^1.0.10",
- "is-regex": "^1.2.1",
- "is-weakref": "^1.0.2",
- "isarray": "^2.0.5",
- "which-boxed-primitive": "^1.1.0",
- "which-collection": "^1.0.2",
- "which-typed-array": "^1.1.16"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/which-builtin-type/node_modules/isarray": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
- "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="
- },
- "node_modules/which-collection": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
- "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
- "dependencies": {
- "is-map": "^2.0.3",
- "is-set": "^2.0.3",
- "is-weakmap": "^2.0.2",
- "is-weakset": "^2.0.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/which-typed-array": {
- "version": "1.1.22",
- "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.22.tgz",
- "integrity": "sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==",
- "dependencies": {
- "available-typed-arrays": "^1.0.7",
- "call-bind": "^1.0.9",
- "call-bound": "^1.0.4",
- "for-each": "^0.3.5",
- "get-proto": "^1.0.1",
- "gopd": "^1.2.0",
- "has-tostringtag": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/why-is-node-running": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
- "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==",
- "dev": true,
- "dependencies": {
- "siginfo": "^2.0.0",
- "stackback": "0.0.2"
- },
- "bin": {
- "why-is-node-running": "cli.js"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/ws": {
- "version": "8.21.0",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz",
- "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==",
- "dev": true,
- "engines": {
- "node": ">=10.0.0"
- },
- "peerDependencies": {
- "bufferutil": "^4.0.1",
- "utf-8-validate": ">=5.0.2"
- },
- "peerDependenciesMeta": {
- "bufferutil": {
- "optional": true
- },
- "utf-8-validate": {
- "optional": true
- }
- }
- },
- "node_modules/xml-name-validator": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
- "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==",
- "dev": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/xmlchars": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
- "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
- "dev": true
- },
- "node_modules/yallist": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
- "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
- },
- "node_modules/yocto-queue": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz",
- "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==",
- "dev": true,
- "engines": {
- "node": ">=12.20"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/zone.js": {
- "version": "0.13.3",
- "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.13.3.tgz",
- "integrity": "sha512-MKPbmZie6fASC/ps4dkmIhaT5eonHkEt6eAy80K42tAm0G2W+AahLJjbfi6X9NPdciOE9GRFTTM8u2IiF6O3ww==",
- "peer": true,
- "dependencies": {
- "tslib": "^2.3.0"
- }
- }
- }
-}
diff --git a/projects/sunbird-quml-player-react/package.json b/projects/sunbird-quml-player-react/package.json
deleted file mode 100644
index c741e5e7..00000000
--- a/projects/sunbird-quml-player-react/package.json
+++ /dev/null
@@ -1,53 +0,0 @@
-{
- "name": "@project-sunbird/sunbird-quml-player-web-component-react",
- "private": true,
- "version": "0.1.11",
- "type": "module",
- "scripts": {
- "dev": "vite",
- "build": "tsc -b && vite build && npm run build:wc",
- "build:wc": "node scripts/build-wc.js",
- "preview": "vite preview",
- "test": "vitest",
- "test:ui": "vitest --ui",
- "test:coverage": "vitest --coverage",
- "lint": "npm run type-check",
- "type-check": "tsc --noEmit"
- },
- "dependencies": {
- "@dnd-kit/core": "^6.3.1",
- "@dnd-kit/sortable": "^8.0.0",
- "@dnd-kit/utilities": "^3.2.2",
- "@project-sunbird/client-services": "^8.1.4",
- "@project-sunbird/sb-styles": "0.0.16",
- "@project-sunbird/sunbird-player-sdk-v9": "6.0.5",
- "@project-sunbird/telemetry-sdk": "1.3.0",
- "axios": "^1.7.2",
- "bootstrap": "5.3.3",
- "classnames": "2.3.2",
- "jquery": "3.7.1",
- "katex": "0.16.10",
- "lodash-es": "4.17.21",
- "react": "18.2.0",
- "react-dnd": "16.0.1",
- "react-dnd-html5-backend": "16.0.1",
- "react-dom": "18.2.0",
- "uuid": "9.0.1"
- },
- "devDependencies": {
- "@rollup/plugin-terser": "0.4.4",
- "@testing-library/jest-dom": "6.1.0",
- "@testing-library/react": "14.0.0",
- "@types/node": "^20.11.0",
- "@types/react": "^18.2.0",
- "@types/react-dom": "^18.2.0",
- "@vitejs/plugin-react": "4.0.0",
- "fs-extra": "11.1.1",
- "jsdom": "^22.1.0",
- "rollup": "3.29.0",
- "sass": "1.69.0",
- "typescript": "^5.3.0",
- "vite": "^4.4.0",
- "vitest": "0.34.0"
- }
-}
diff --git a/projects/sunbird-quml-player-react/public/favicon.svg b/projects/sunbird-quml-player-react/public/favicon.svg
deleted file mode 100644
index 6893eb13..00000000
--- a/projects/sunbird-quml-player-react/public/favicon.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/projects/sunbird-quml-player-react/public/icons.svg b/projects/sunbird-quml-player-react/public/icons.svg
deleted file mode 100644
index e9522193..00000000
--- a/projects/sunbird-quml-player-react/public/icons.svg
+++ /dev/null
@@ -1,24 +0,0 @@
-
diff --git a/projects/sunbird-quml-player-react/scripts/build-wc.js b/projects/sunbird-quml-player-react/scripts/build-wc.js
deleted file mode 100644
index 6f7eee62..00000000
--- a/projects/sunbird-quml-player-react/scripts/build-wc.js
+++ /dev/null
@@ -1,126 +0,0 @@
-// Post-build packaging for the web component (Phase 8, spec §6.3.5 / §6.4).
-//
-// Written as ESM (package.json has "type": "module"); the spec's CommonJS
-// `require(...)` form would fail under ESM. After `vite build` emits the IIFE
-// bundle + single CSS file, this script:
-// 1. Embeds the compiled player CSS into the bundle as a top-level
-// `BUNDLED_CSS` constant (so the web component injects it into shadow DOM
-// with no runtime fetch).
-// 2. Copies the self-contained bundle + stylesheet into the package output.
-// 3. Writes an example index.html.
-//
-// Output path: 'web-component/assets/quml-player' relative to this project (the
-// literal spec path). This does NOT touch the repo-root Angular web-component
-// package — see the deviation note in the Phase 8 report.
-
-import fs from 'fs-extra';
-import path from 'path';
-
-const DIST = 'dist';
-const PKG_ROOT = 'web-component';
-const DEST = 'web-component/assets/quml-player';
-const BUNDLE = 'sunbird-quml-player.js';
-
-// npm package name for the React web component. Deliberately DISTINCT from the
-// Angular package (@project-sunbird/sunbird-quml-player-web-component) so the two
-// coexist rather than one superseding the other. The version is taken from this
-// project's package.json (single source of truth) — do not hardcode it here.
-const WC_PACKAGE_NAME = '@project-sunbird/sunbird-quml-player-web-component-react';
-
-const build = async () => {
- try {
- const bundlePath = path.join(DIST, BUNDLE);
- if (!fs.existsSync(bundlePath)) {
- throw new Error(`Missing ${bundlePath} — did 'vite build' run first?`);
- }
-
- // 1. Locate the single compiled stylesheet (cssCodeSplit:false → one .css).
- const cssFile = fs.readdirSync(DIST).find((f) => f.endsWith('.css'));
- let bundleJs = fs.readFileSync(bundlePath, 'utf-8');
- const css = cssFile ? fs.readFileSync(path.join(DIST, cssFile), 'utf-8') : '';
-
- if (cssFile) {
- console.log(`[Build] Embedding ${cssFile} into the bundle...`);
- // Escape backticks and ${ so the CSS is a safe template-literal value.
- // BUNDLED_CSS is the FULL stylesheet — reset + component classes + fonts —
- // injected into the shadow root, where it styles the player in isolation.
- // This must stay complete; the player's own CSS depends on it.
- const safeCss = css.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\$\{/g, '\\${');
- const embedded = `var BUNDLED_CSS = \`${safeCss}\`;\n`;
- bundleJs = embedded + bundleJs;
- fs.writeFileSync(bundlePath, bundleJs);
- } else {
- console.warn('[Build] No CSS emitted; the bundle will ship without embedded styles.');
- }
-
- // 2. Copy the self-contained bundle.
- console.log('[Build] Copying built files...');
- await fs.ensureDir(DEST);
- await fs.copy(bundlePath, path.join(DEST, BUNDLE));
- if (cssFile) {
- // The `./styles` export (styles.css) is loaded into the HOST document by
- // some consumers. The player is fully styled via BUNDLED_CSS inside its
- // shadow root (above), so this file must NOT carry the global reset (`*{}`)
- // or the hashed component classes — those would leak into / mutate any host
- // page that links it (a web component must never restyle its host). Ship
- // ONLY document-level @font-face (KaTeX), which is safe to load anywhere.
- const fontFaces = (css.match(/@font-face\s*\{[^}]*\}/g) || []).join('\n');
- await fs.writeFile(path.join(DEST, 'styles.css'), fontFaces);
- console.log(
- `[Build] Wrote host-safe styles.css (@font-face only): ${(fontFaces.length / 1024).toFixed(0)}KB`,
- );
- }
-
- // 3. Example HTML.
- console.log('[Build] Creating example HTML...');
- const exampleHtml = `
-
-
-
-
- QuML Player Example
-
-
-
-
-
-
-`;
- await fs.writeFile(path.join(DEST, 'index.html'), exampleHtml);
-
- // 4. Generate the package manifest so CI can `npm pack ./web-component`
- // without a committed (and drift-prone) copy. Version is derived from the
- // project package.json so it never diverges from the source of truth.
- console.log('[Build] Writing package manifest...');
- const projectPkg = await fs.readJson('package.json');
- const manifest = {
- name: WC_PACKAGE_NAME,
- version: projectPkg.version,
- description: 'React-based QUML player web component',
- main: 'assets/quml-player/sunbird-quml-player.js',
- exports: {
- '.': './assets/quml-player/sunbird-quml-player.js',
- './styles': './assets/quml-player/styles.css',
- },
- files: ['assets/quml-player/'],
- homepage: 'https://github.com/Sunbird-inQuiry/player#readme',
- repository: {
- type: 'git',
- url: 'https://github.com/Sunbird-inQuiry/player.git',
- },
- keywords: ['sunbird', 'quml', 'question', 'player', 'web-component', 'react'],
- author: 'Sunbird',
- license: 'MIT',
- };
- await fs.writeJson(path.join(PKG_ROOT, 'package.json'), manifest, { spaces: 2 });
-
- console.log('[Build] ✅ Web component built successfully!');
- console.log(`[Build] Output: ${DEST}/`);
- console.log(`[Build] Package: ${WC_PACKAGE_NAME}@${projectPkg.version}`);
- } catch (error) {
- console.error('[Build] ❌ Error:', error);
- process.exit(1);
- }
-};
-
-build();
diff --git a/projects/sunbird-quml-player-react/src/App.css b/projects/sunbird-quml-player-react/src/App.css
deleted file mode 100644
index f90339d8..00000000
--- a/projects/sunbird-quml-player-react/src/App.css
+++ /dev/null
@@ -1,184 +0,0 @@
-.counter {
- font-size: 16px;
- padding: 5px 10px;
- border-radius: 5px;
- color: var(--accent);
- background: var(--accent-bg);
- border: 2px solid transparent;
- transition: border-color 0.3s;
- margin-bottom: 24px;
-
- &:hover {
- border-color: var(--accent-border);
- }
- &:focus-visible {
- outline: 2px solid var(--accent);
- outline-offset: 2px;
- }
-}
-
-.hero {
- position: relative;
-
- .base,
- .framework,
- .vite {
- inset-inline: 0;
- margin: 0 auto;
- }
-
- .base {
- width: 170px;
- position: relative;
- z-index: 0;
- }
-
- .framework,
- .vite {
- position: absolute;
- }
-
- .framework {
- z-index: 1;
- top: 34px;
- height: 28px;
- transform: perspective(2000px) rotateZ(300deg) rotateX(44deg) rotateY(39deg)
- scale(1.4);
- }
-
- .vite {
- z-index: 0;
- top: 107px;
- height: 26px;
- width: auto;
- transform: perspective(2000px) rotateZ(300deg) rotateX(40deg) rotateY(39deg)
- scale(0.8);
- }
-}
-
-#center {
- display: flex;
- flex-direction: column;
- gap: 25px;
- place-content: center;
- place-items: center;
- flex-grow: 1;
-
- @media (max-width: 1024px) {
- padding: 32px 20px 24px;
- gap: 18px;
- }
-}
-
-#next-steps {
- display: flex;
- border-top: 1px solid var(--border);
- text-align: left;
-
- & > div {
- flex: 1 1 0;
- padding: 32px;
- @media (max-width: 1024px) {
- padding: 24px 20px;
- }
- }
-
- .icon {
- margin-bottom: 16px;
- width: 22px;
- height: 22px;
- }
-
- @media (max-width: 1024px) {
- flex-direction: column;
- text-align: center;
- }
-}
-
-#docs {
- border-right: 1px solid var(--border);
-
- @media (max-width: 1024px) {
- border-right: none;
- border-bottom: 1px solid var(--border);
- }
-}
-
-#next-steps ul {
- list-style: none;
- padding: 0;
- display: flex;
- gap: 8px;
- margin: 32px 0 0;
-
- .logo {
- height: 18px;
- }
-
- a {
- color: var(--text-h);
- font-size: 16px;
- border-radius: 6px;
- background: var(--social-bg);
- display: flex;
- padding: 6px 12px;
- align-items: center;
- gap: 8px;
- text-decoration: none;
- transition: box-shadow 0.3s;
-
- &:hover {
- box-shadow: var(--shadow);
- }
- .button-icon {
- height: 18px;
- width: 18px;
- }
- }
-
- @media (max-width: 1024px) {
- margin-top: 20px;
- flex-wrap: wrap;
- justify-content: center;
-
- li {
- flex: 1 1 calc(50% - 8px);
- }
-
- a {
- width: 100%;
- justify-content: center;
- box-sizing: border-box;
- }
- }
-}
-
-#spacer {
- height: 88px;
- border-top: 1px solid var(--border);
- @media (max-width: 1024px) {
- height: 48px;
- }
-}
-
-.ticks {
- position: relative;
- width: 100%;
-
- &::before,
- &::after {
- content: '';
- position: absolute;
- top: -4.5px;
- border: 5px solid transparent;
- }
-
- &::before {
- left: 0;
- border-left-color: var(--border);
- }
- &::after {
- right: 0;
- border-right-color: var(--border);
- }
-}
diff --git a/projects/sunbird-quml-player-react/src/App.tsx b/projects/sunbird-quml-player-react/src/App.tsx
deleted file mode 100644
index 522bfeed..00000000
--- a/projects/sunbird-quml-player-react/src/App.tsx
+++ /dev/null
@@ -1,50 +0,0 @@
-import { QumlProvider } from './context/QumlContext';
-import { MainPlayer } from './components/MainPlayer/MainPlayer';
-import { sampleConfig } from './dev/sample-data';
-import type { PlayerConfig } from './types';
-
-/**
- * DEV harness — mounts the real player so `npm run dev` shows a runnable UI.
- *
- * Two modes, chosen by the URL:
- * - API mode: ?identifier=[&lang=en]
- * Builds a config with NO embedded data → MainPlayer fetches the hierarchy
- * + questions via the data service. `host` is left empty so requests are
- * same-origin relative and go through the Vite proxy → localhost:9000.
- * - Embedded mode (default): the bundled sample data (no network).
- */
-function resolveConfig(): PlayerConfig {
- const params = new URLSearchParams(window.location.search);
- const identifier = params.get('identifier');
-
- if (identifier) {
- return {
- // host is empty → API requests are same-origin relative and go through the
- // Vite proxy → localhost:9000.
- context: { uid: 'dev-user', sid: 'dev-session', channel: 'dev', host: '' },
- // Only set language when ?lang is present; otherwise let the language
- // precedence (localStorage['app-language'] → 'en') apply.
- config: { language: params.get('lang') ?? undefined },
- // API mode: only an identifier, no embedded sections. Online asset hosts
- // come from each media[].baseUrl in the backend response (Angular parity).
- data: { identifier },
- // maxAttempts is host/backend data (Angular parity: playerConfig.metadata),
- // not a player UI setting.
- metadata: { maxAttempts: 3 },
- };
- }
-
- return sampleConfig;
-}
-
-function App() {
- const playerConfig = resolveConfig();
-
- return (
-
-
-
- );
-}
-
-export default App;
diff --git a/projects/sunbird-quml-player-react/src/assets/hero.png b/projects/sunbird-quml-player-react/src/assets/hero.png
deleted file mode 100644
index 02251f4b956c55af2d76fd0788124d7eee2b45eb..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 13057
zcmV+cGycqpP)V|)f$;Qooc7=_G
zlYe)HToTQIc!$)^+J1M1y0*T%w!p~7%ux`!eRhO?c80XDxKQ*R^lUUMnA>6NT^?feoZ8xxvP32D&s-9ow
zqjcM}eesrC)NeDmsf)*P7wJ|K!&xP%Zy4iI8lF)Tv2!reW)tCzg_1=PmOwd1SQfxa
z8;58t!=z~Ba7CYlNWVG>he8aRPY|+-JmozNhn!#9i#77Aa_Edt$ijyCWL#=~I>~2X
zZNrQ8I0=D+NWD4pq=7~(i
zhfThMNw|G>g^y9pGzxX7ZSApl@tIxFcs{p#MX{Ax&XZT+cR#U+OWc@S)pkIuI}dzu
zH?^Q=<(y&Vq-oxSLfc0Zmq81bjZWf}RnssBaD6}2g-XJHLcN_|*IOu>m|x$nbm(?E
zyNy!Zp=RroS;?Vg*kmoJYBi!n5{_^@rA!)=t#a^;N$8GL!*DsQb}`yvEuX!G@||An
znOfUZAevPrkV_qjl|<~3QRZzG&h@C9Y5z
zqpNH4xqbF_InIPh)kX}Vn^5kyed|mOuq+2>M;v~KO37a#yrEn3XDqtOl=rc6_KZ!;
zreo)DFVB4|>1Zd(bvMI%8uM;3!)YMYu&cG?(PE!B~y@3yKBMt|R
zAf=I16tFwPsl)!jDqvYkLHaAQ+f@W1m6F5aZvwhm4JL
z{_l)@b;)mDSzle2gyFP5-r1x-5X{G}ot%VyWP@vEW80!Q=f%RTfpg>B*TA^pyWYUQ
z<=xPtz}WcZ!;rFl4m1D&FFHv?K~#9!?A%+fn=lXt;9!Fc#kQ;zk~gZFsH
z8e5iu@c_pzX&qb8&Dum*oXwB+fm6l6gFfC|o*wgEiy6tw~&co
z9Vd_4)P%wP-KwQW7|lN-znGK#?N+j24U=$982myIBM+vsiKsc*@4-rwJxuAaHKna6
zT3wi!C~a4ZKH03qU}_1bKyx0&$CaK7_%Z+Kl$)fF5^op
zZApQF2TvDav!s|krTjw-8US6ep
z%!VmX4luub+fseQz_D9ATJQ?iQQwD}TZz{-yo#l12a%+7bT@E(X-hyaVS-5vuXc#^
zx^w;L21;NphGVoj*{s3f4dme0y2LC=G1-7THd`#z?;tuC{^9k(dM{Rf2GOxg7Jzho
z7nSZHl7?M9kdalX`)YgoKEfiae5+;$(OGeN1eqxrv!ZCVKyH>xiyNqfe8xzY8*7)H
zQls8KMp)F4D>ED;idMOU^^WhVF@q>ZSmeB0y~qC~|DB648hr%Sh|*T(4q|w2l?m2+
zvBVw3@7+Mz?^Yc#+se6KM;a<=(W-I>k)$-qL2V*t}VaW`;?P4)WqI%maIDq8!oUcSYAD`}wWjkSyAVsnF65#2zQ
zZ>(K*TlS(E#4y$4Zq+e^_&}d)q20hCe3!LfLYP%nQpLJ~gM6a1hJlz3)aS<9C9me|
zAcmJ#>tOwBy{HoP0Sm1&_(E+S@6
zgBIFUoei8zJmdpiq8q5=OY7t@`)JWxn_&GvKVr=Zdb_pEL_j|=?f;WK^U9Q0efd#K
z9q7SfJTl4pmA$jsZ5oK8@O9#!I3Cv-kL)<8SalSsp#dcpvJ}Nz#G6FC0%9|7Fi#8;
zGDJXtj!&GljT3*HE@0EE>G8Se&d)*nkqe}-?`3vPl&UqK?xG
z!3XJ4M-x`EuQjhBbu?ik-)rmIt=DF_N?TVMP)8Gjn)TZ2V%H|zENbeix}kOxd@0}Q
z>)HuH6Ean!uS#~4g2Ne2WsMGel|h%j9*W_quQheG^JqmKhc*RYzp0wKlGjBq2VzY_
zgOv8WC1+%W=W)k)Yp_`8kfE=uiiwOZTXi8Uj9YGr$f@yJcJ;#&-Nq~sJ7anE(@;QN
z=~br%7%7`isKStX|7!1?L(apl^QvPKlrHV4S+6tNVQ*R1iGdC~WMNE1$a+=rpQmcB
z>wxiLIBvOnm;u*;9Y!kJdy(T4lk|8>JAm(&wEsFIF1$_*{>2ZNd$V6DS=SfrGxAv0
zzKe377JI`&o9Ljr+VnS*EwehA{f&{cKZF(6*MG5!p5MvrFA3ll{fmRG*L@6^cb;o^
z3Wm8c?Sc6$`>~VEWw(c$Y?nRO;2Q$=ulpqPtM^=1IZx;@xK0PgO7rKQ^WHVLwtgUT
z%|JF{^f(VH)wLKQ%dYiu2RmchBdxL0-M?wxxul_z*{h6ZZ`>-k(vizs((vW8Lt6Z6
zY;Dt?@JWyN`O`f;&d1Mb?e%9oyRK1ql?EE5XB2(W)|D1~Rx35$H6@6)$F?)7V|zEO
zI}fu0-0}8W5=6sg$fPnZ~7=tTudl?Ecb@pxbo)vni%gP-?hL|%*?62C;x6?@E`VRnJv
z?fTb;k4x;TS7Cu-z%J}uy}e-pwpLQ17Q@4DC+FCdAmNKklG$`I_pyw7E{fYmw~{Fj
zi?6KcVy=Wrel)EB_DWO|0CKmI|13!gBV?X`Ozp7x>?6jr`>Qz=^4ea35!$*f})
zS$i+x_k+@P2q1RFUH^ZTTk7=n?cjfR>hTq3l3SY~#w+I8SSutXGyhw;Ws~=zMQ%Vc
z>$On~47Ut?P*_!TOQ&PFmLAyJieB2X4_Fd_!WxI-AY`q1Lc-oK?+qcOTzlQ?@~x@OT}*9jTVNfl@3rGvZpWI=eKg>T
zZb@6YWz)J=IhP7CF|c?G62vMEG%#U}?#86$0jR4sG~i(jRd#jmn`7b(O#?N;3a;1t
zhXLssmUwGhp79luw#(*V8WL0|8+E
z6=YZ_O@er~$LrD_PYGc(kJgB=;yw#+Z3X6LDUZ(NcwN=B-hjdiHm!JFar%m{(5bEW
z@@_VEtG$5;`EJZ|OkJ@l&G9n((w@uNFwmU%bG|s#TbcJJos!{e+bjCjrCq_}LcN!UFgKtgg7siV*7#
z!}1whTRRi*-avJPu->C}Z8EiuK$#886+H_#_!btv+rsiBbv2jAJvJ+O0{#}y(%L3H
zfjU-kq_-L@2XrL*ae{{qYJkD{@dw%*bkh2P&YS-0!Xt!PRz7KHV0+~j(t9W8lAVWR
zt@B*DgURgEz4>WuN>o?_iKcw$?k{||Pg7{Q2o4|VmJ)mg?{VQJA<}zEr^YAAS
zgGm5RT4T3p)U;yz-tfBO^kw8?IoG!IVmc+Z3m#}AOQ?5MRa>)OcU!$N^_+yK6ayn?
zK>~WK0!#ysuj^oNLakm)Zvu+J)OSubX^kv!c*xgdIvs;kln!rgG4*uZ;w0mQQO4XD
zO9P{GNdv!=cQ(CAL{S(%KtuV^zC&Q{%g)PoXnp^gn^>c*`E>$hLYg2HjnbVGtWLa{7zHdG1jT@B{|Dm16
z7K2(jsfG+m*Zxof)iXxu+!H5Mo-0$pkyV3VV4B@Qms46M
zuBxGRV@HxU7Wwx-6CB
zaU*HO<_qn$5GH>&@?nRy1{z
zkik!sLfWQ)r#75)vVwCBU*r_)Q6mp?!j85{#Xqse)ApRdE$V0%I0*~e(_{)5H)`Mk
z#rExC>yjhZxuL@|+#v4#<Axw$+VpV
zuT;!2Vww$je$DpAW`$FX_Ab|Ip%$;&T$-lW8jS~B$>G}rd>eQG+$h9lQx4Mx0w={m
zx9?T6VU`>sR}XClkAhHEShOUe8awiq
zmizhL+}5UKs3}6~It7vBTig9dfQ2Q8coo+Miiaw7n~>4ybv2Ptt0^^=VqX(t*Yya9
zr`FxxFX8(v*H=+uJ#JJWIB2A(==HDYx~^zZ2nu?2`}|Wsa*f3h3ixc+U|FDtAG$Y!
z*lc_7se5Oso-Cgqe0){{!8H4g$3<8!R<6JOurD;((({c$1(pwb>(#TT!sge@4>r2@
zVL7>U`0`nsWAYErezk4(Z!gMI2?UTo{J3Ajo(u4)KYIRd>BRcG4BoS3G0EXyEp@tw
z%P7__?A^a>Q&AKL@ayDO9D*Qkc!NHnO9l}kpp_6hXbMppYL(X1L?njdFT|-h2<_$;
zAtDZ!1Rf%|yb!qbWKd}%0b`LzBeyNy43|QO(&h2mxQLUL)|0%agVOW)6TV!&Ip^Ls
z`PG2cygM8)IecQx=Fc+nqYRo4hS^^-nM_&-y8?EJXUczP=DIw(GkTJdpEdh<_STs{
z|A)4n1GKdE=Wu!!nYoZHcUQ4S&R;oDOKX2lrkdF(mK>hz<$Pp>igjOcvoRIjlN=W8
zu8Gx5(roqn8$>gEE5vy{GiGeW8Tq{vnf3hS-V=$tZkQuftUVuU8o6k&dn=Yg3)6MOIH>nlK^-2+C6BZITr~1@So?NvG#TwL)|~=1YXGMTLpS<)ziK_CSOabe
z=cB#5)yz|@0i9dSo?*CX)}UP=s6)B+F@~Em(u@Q(I9J9i_V{LmMu8BfXYMh~*oPP+
z!3~xTv|(>|=n6ZOtT~C@V!z!w%18*8T2t6}U2S##rC)mekBql&VsBX;$~ByGE$oA9
z`0Wzq8p?R{4)$l*on;!cLa}Dh^Xe?owiQZt9nH1fxxh$pN9K%CtOw?u3>85L7rr!d
zXs)l{TZ{xXP&U8exz?9cv~dNNibOmt*K4I$?RxqIBZ0(?Mg-9FS{*9Bc49Qc1`=sIF-rye`aNT1G@4NwXcnyc@+bw_mTsR>5<
zF<2;X0QesG_pw|TonqVBhRtfqI>ty(SIu&VOXd0CrLlfp+;WH7HYjhqnu^oAY!9cB
z=B6#R?Rfz9BP`dJ=@v_?70s3HxQPk+{6Y+lM85f2NF^00*^OcM0~?JOZfR9ZPYF+#
zYSs}(_BUYV8{n@2a1hD^SV41bwmi2uztR;PeBgF1F-`9>`zoNss-@3LaF2sjl~>OaaVmp7PNp+UT`6@}gR%uzqHDVeEZ14{Yt?n%JeQm+t(1_u
zSc}oj^{b;+rlS|ME%+LjzSI&xu0Bblxo$MJ-J$kJ?Qu_XUXh}*@*-x@ny|}wVM%Lg
z3tNB`yvr*}N?ClGL;H2cglcvErIccU3(eP7>@~4nOIcI~-`P8tSQnx=jI&{9)!1}l
z;gQ%_h>ZlPSV@o@Azq1R$C6ja5!^ZGh;YRhhxs58qJWo9@Bceac&yy(pET1hnn`~7@}2L0&dfPKYs$ih7m2}R!25!(hxqA(!UIw;
zK4+~Jowy3=RNC6nE=ncU{LH5?*9@W24lacJlvCZXB$CYtE@>c+~H
zkV=(5I&gb{xn2!~f&fs2NQgAL6`p|kyt6kpWk}iVlqIp(H;ig`{_U9yxs1jzu^ETM
z7~)Rg8C-NueqTYP&U8l{DY=Y47cR
zOR@U%$KQV{mkRF|4)z9Y^t3K`@p>duY&QLUFeh6VoV`a`$U@)(z!-N*5Cj<11$EZW&hJLX83TO{lJYP74rlDZQPkm@t<=U^I)x@|UnHHkdQlh?!ltZwl92rE;;^
zZuIappj4dhld1}kttYYV-j|KF1Kus
zWBnzttD^00%LFK(wrwNragFub6xiV8QE2rm<`&fcR4SLFcdtLxVuN!Aal-g6dE4%k
zARZ}|xeo;K{0yf7@9aua%2j5o)CPcIOc6uLHFJOcgtB5owlcNAwyAHc0QB0Dts?c@
zUemG~j_E&W7R%+x-IO4FJl8e&*2Blmp1S#RA|)geVrxvP)NHdYuxi~g&Etn?QdNK8ZDKZ?QFLU?zh30G|t9G>a_X4zk}Ygw<^$7K!GIn(Io$>(d4ODJQ2XSd%jpK
zm7>ptl$a3GyB}5-%p4>Q*p#VL^B{yQMuFCM^#l#+N!Ne
z5_PrJWB=@Iy+t)H`g1lX`{bm($KE5I?0c(JEYm#t{F}j!xtsbob0{xu@0TB_*>G7w0ICn
zr#VoBktqHZ~XxhiKD*lcG|b;H*|Ny3P^8ceV`sfBRfrhwZ!T+MFZ!F1Bt{q$8d9i6o?~
zODj^POr}&ivSa^R^YFIq7o0giLBKCycH_aU`F6)O6JX%nPTwh~Q`eq6*0iE#Srj2^
z*_hN3%*b83zfafy60@Cp3{J({RlSaEn&E?mrxRNC9GQ7#+f=s!
z0KBf-9Ny_v2VbE%aB|Di)5kNJ^t&C`4D(>t7zYUWUFtbxt+Oq=!@O7BU)}>d*R72o
zFF)3jQD_lLe4is&xzyJYC1-c{8TX$RU>&>P$%)ufpez0XSAukmh!xcekg`s$c<>-q
zI#zn^JU0zzF}V60)o$_gY}PQH>b2M9&8fRZa#OauglPb
zeQ@pMm&=!vNgos4CluQjLMV!pfkmxK+35bi^k&=k>9h02?l+u+m0agG;(h2|Jslc-llvtEwn~*w3bx7qnvZACG<8}AGeaDVvcHbKd2>3G^
zSFPULUn-?Pmo^-_`mLZr??uNH`2=I&yajlrF{DtUxMy#Nu}z=3y7qbUA;5`)hibMR
zhXL@@uKyV0-2&A@t@!xyrBnMJl&^o@Gx$&5_q6?D=ji5grd-~=?dlg;ur(_V0wjh!
zA=JV^C1m+DDkOsgr<%O9ZQFg!0}pD(#PSz4Dr_EyS5$`)VIAv);4n-SFP~YtC7sH=
z7&*MfpH;gd*FHbkmD#)hVxb6xjc9~`t?_{=JS+@ip_cTicXxG<=7m9&
zPX+Z8IC*GSAXuGCrZDHgR$r%jyk-fctis2Kx4HvZ|B~8uC@o)m^>Hy-O!&TKA?$&n
zkP2Xc54w~!=z2?^NafyL*L0V9cbYrugHBBUj`xVyZmGFR&kvk#>1J*Z~i
zNTz}?IAdJ$gkqd2!Gw(%LzE!O5s4C7q4%T~e_P{+z=DNDKrG**p=U`d5yg^vp`;Zn
zsU=8gd0a9s4s0FPJePWR9eH5=+O^Kks&kC-iblNqTh2&Pw*^(4384f+D8N|fewZu_
zg2ejQ)ov;ztz;NQl7yj;A`(!H!XQu_$sqY9h_IrH*}_%1{L&_YLDvO?%R5Z-t+ClW
z_qERbL?HKUZ!nt+!E9S`uoh^5A|DaIHe*_gf1`E_Vq+}{&T@t$EGhMnRjJ4z2w_W8
zp+qjs7as22^&S3wY1?+}^j-I=RcCE>#|39)g(lU7v_8;?=qK(9D8-*pPdiy)P3lIblG`+?%ea|
zYoD3dopYt!tKgFicfNmNi(EWE=E4hC6(r|PYtanqJlmt57YOVrr2^tfrG(eG9C##X
zu&1t@%L$RIvpj!wUA
z8i>Pqot#_+Cnp6L2XPcZy1ar|9MnY+7eNvK1E)@Tr#2KsXq1*>)uUCozT7L##ok?o
zhA6ofP4E|b*9tAfG?uf$#}>TIR&1A!yslP8}i7w-EzW(x#9VEvx18k%Tn=-$VV
zkOtUr0b2!w3t>h?#8AZl^Az*(6KCGlD;4j~yx};`#2gN1_gv=%7KVzecIRakN{f*4
zeaI>yH;-o4OGhvGTU)(quWI)-q?V*(sVesSMv|wMUQ3hLEt=lBB$KZ9TyHr>)f7o%)
zPYeU<3P)*P10*7vE)nA5#{c=6-E-_>r_u4e3i!I2+UksELwDqwMeBZ9FSP$;^Ajro
z_@M#_Ss$?ejoB@!wN|kbGKs(0zLo%0QpQXW#t;oC$B0MZYZ&Ej?8~fNhcCVvPo3vo
zFn0WWZaPliF^8_}yzb`*f@yg0uWv6HgNI)xa=pO%Ck(C<=-60l#uD3(wXP~c7!NoX
z0&^6=N`zcc90F#qt@=Rn@r!3(*1v(Tl{B!m?Mc7yIA+nEHpY{YWr$=)F7rhR1P}(v
zt{YhY#;jsW6G>#xhP*B`OCk|Pf+NN;ju1rxa*HAgoGq*rvqw&xe~;t1JA31$s?GBb
z*g7&@cbKo4n<`>)!UlIAgR6q&))B0KYU8r66GbFj?8Guw4E%&}Qi_lT003LtoIZei
zwD~=XZmeo+yZ2Pq3KYCF-R&11^p=
z@H%s+=G`}wrbJ{()Mh71#2SP3Zy3m>l1n?0N-N1Q;z6?oSxr-G(H5m4EO>~&;}VKi
zfY}3w+9z>vp#d)hVuu`)vG_aaH%3b=WKMnSu&c31;<3O;bz2iD=w+o4#oBb36
z5ZCF*Gu?zjZIR0S>_%pHY2$k8D^n7Sz_K8tCDeXM+dO<#LSg%h6`~dnVG1N@T7v&e
z%wEd1!k{^zfz_1BTW{!$!B%g)J^2b87!9Y>>100X1SgT7s0z$o>^lAA=Gp_cC1(h=*5Tmf8z&LGJJ>$|K^~s`z9*OWz5MFUr?>Bi?_PGBB)#psD5?>n+q{o_
zz7~ez&;t#h8l$jwGPCC&xq2YetXYQT+0F3j(`xmNGf8dj#an|p#I*pvI*kwW4iuB>
z+q3_7xB8y;pLzHG-S%+UHQA
zvqp;$kmGJY>lLsN4C~&TcvAS1SErTcwcw0r@wngk
zShAUA1M9b#g}^pL-zH7Q#z^&j#r9F8BTVfkR&qF<=e35goTu7c|GN)0mokj4m0%~0
zXJ8j4Hc_l;HJ&uU*Iw`8d_EscJ``s0tk9mkKo^TYXm-EoAzTQObxa@^u~g2t#T)
zJz|rE!I_?i4dCJC=B8(_pZ{YR>|V?0iCcnU;E@$239^x?SYCfNaMHN;CtHIS_zHN9
zTkQc1v@O35okiFtq5_u+5FkY55ap@pi)O?}x0D1c*qB0KpYR}>Ul+B0Vmr}Z@+%mJ|As}sis_=ROPbov@*2thpE&?!V#Qgu$snYvCZ
zrkhmkMU+fSf-s8(L37fPr&M*jRs{{THb!aXQu|P9l_-vJhHvLzMGH
zE?1U0H_+PmNABp9`|KzkGfrrZ%XvdGo6*<{d5m9~L7
z_^`M;X6xDo=m6LY6RfvJEvsTK1!u8d2HPx|$S}p;sRy!I
zWL55Yxu~_B`OP@~(q6&W3#)~I&+MGL%GWR$#udC151^wsswhqlii;rP9jJpiI7o&Z
zAb})=HY7?4HA|re3ns`%$)FuvKCFWjhb~?IE)F6dF2K5}poj-NK6Gf;hw$t3=1txY
zoxQxZWrQU6K!%|~!m?~Bnw-6Rr!F3BZ{u5!LqnZTDON}Coj9^@&le)V!NYrVwS~B%
zEL+>Sr@}qGwGvu|HrOo|gSt__ezN^&%~{*)a=rf7y1HujUcr`zZB<4#l@T#eN)si}
z)lZA<{=tKx8E%c9>A(##6}_p+~EZpKsl5a4pj`E*;_-6`ysiv
zffA!7=MT1vCz}-m4~tjVey1b2KSR4OEtLd-(_DdUqYZ74LaDkhH?KFh?%WAOP2WbX
zp@zT+Dx|5_f%JQiAGvVw!oh+g3e50u!aPfMxdC=E)XB{F5IcEZhePIM-
zph6Y`$Oy?JBL<8Ex(SqEhLeQ@XcrdA>a?rx+_~HLA;l14)WmmpH}_w?Pg#HBZs0eS
zwypwAW?M-x+3AU-(GGWSJ=ngxUEcEZ5OsX(Qlt!MQ
zn^(`S{GHkAv(8@D`EAfSYig%Cxv?z!{=w^F#y)5_d7FuKZH7qlR-#5B0bt806%D0I
zT7VdVP_?q*%Rq8UR;JkD4i^RXowt+E%#V2U>TfDqzZSDZ+dR!a#T3I>-z_$q9@k|m
zy5~A*m~&JWP@E7a=pc}4kVHTc4h&R;Li7d@f`|hKMLkbb^uhOakNr3&FLjlm~i5NBM<
zFaYI{;cpiHCNRdE0dg*>qIm(_t?#$h=(SCw?h3rJV2*ER8{O4^3#=dO)KwklZkoqU
zS8i5c%YL*y*4;FY#D=XmkQnYj%LH)?02~gSJH`Qp1XY64g>%c_K$xseI&|e)7vRoL
zAqRba$G@%fSGA7X7hQk%_3NVOYVS+$leU_!&6*5uN)8#5ZBz_6ASCA;azYS-Rt@ki
zg2NWz(=;t}SC(~Ibl63$5C8FPmhXqb^)5#jaJ~I{Ex3xZ!+2h8$}}h_g@Be>HZ;72
z6#y#>AY3^skuVKF#0WxFBQ()5d5_nWb?c6c>EeMM|Mh+*&wEpPyxHCq{R-Gdr-`hN
zF=1sxl&mBoK+#qRLl9#CEN|Fg8>nbmsTg3a1;#M9enQ$RgWk}kp#-5wh=EF&1tl%mJln2V^8o%Qv(*=zEuO7y
z=m*8?xpUn-*@h5Cl_3BK3joiGkyaScK+>|MWdMRWm@RT!Q1piAlv5hL@B6>3&GI8)
zP!xBc6}ZNIpJLL%2a8Y!+(<=f%WX>_uWVxlga9!D*oYt$l0cxRDMvqfU;Kq_mLK5k
z)dvqYcgLa_Lz?3HyeF)@$%$&6lI?r4I>6W#M*<)vq{?&Oqrx``d`mhpVPr>
z#q078F6gw_X<=?KR>8%^t%@wbITvNMu!hKiTSkCTJkw>1!e*Y{%31#_yMf=LW7{RJ
zYoC^w$6%3cBtVG5)x#{Hg6IVTh9XEcM{gQwXk!R^y95^f-hZ`d{aVa+xW1EO4wDV4
zB?JgD7*?qkvc|$nIykTvNl2x0j3Q!MXoLL^)~}d7jcYf(H8D~c+?$pKL(px>Z3`eb
z04RzS6_AgFT6Pn#iZAg$Sl_j8#;6ShF%&(Fag#E2asU@@LaN;=b=Wf7sgPKhfzhBM
zC@eFL8^MrnA*9&Khe*Ab@CC9*uyJGXyi(;y2>lQLJZt;ShtJi?3Yf_t`F+$hY!+Q2Ndsx=U+bjTiAy7djLji>7k%k`$9&--f<*BNA3Hy&ZrHH|4
zG5H&9cB?O#zI1_OOf0Ce%mDfQxdtp3vU%(iY6yji3iISS61XLv#z|!zI_sZqza@B+
zyu9st5-h+`H7QUKx9}3w@oU@EO}&cEzG?fu!!bLO->%zkcg;i9^j`S~=WKMnDi1f=
P00000NkvXXu0mjft=yBf
diff --git a/projects/sunbird-quml-player-react/src/assets/react.svg b/projects/sunbird-quml-player-react/src/assets/react.svg
deleted file mode 100644
index 6c87de9b..00000000
--- a/projects/sunbird-quml-player-react/src/assets/react.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/projects/sunbird-quml-player-react/src/assets/vite.svg b/projects/sunbird-quml-player-react/src/assets/vite.svg
deleted file mode 100644
index 5101b674..00000000
--- a/projects/sunbird-quml-player-react/src/assets/vite.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/projects/sunbird-quml-player-react/src/components/Alert/Alert.module.scss b/projects/sunbird-quml-player-react/src/components/Alert/Alert.module.scss
deleted file mode 100644
index e9d33659..00000000
--- a/projects/sunbird-quml-player-react/src/components/Alert/Alert.module.scss
+++ /dev/null
@@ -1,94 +0,0 @@
-@use '../../styles/variables' as v;
-@use '../../styles/mixins' as m;
-
-.alert {
- padding: v.$space-4;
- margin-bottom: v.$space-4;
- border-left: 4px solid v.$gray-300;
- background: v.$g100;
- border-radius: v.$r-sm;
- font-family: v.$ff-base;
-}
-
-.correct {
- border-color: v.$success;
- background: v.$success-bg;
-}
-
-.incorrect {
- border-color: v.$danger;
- background: v.$danger-bg;
-}
-
-.partial {
- border-color: v.$warning;
- background: v.$warning-bg;
-}
-
-.info {
- border-color: v.$info;
- background: v.$info-bg;
-}
-
-.header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: v.$space-3;
-}
-
-.title {
- font-weight: v.$fw-semibold;
- color: v.$g700;
-}
-
-.closeBtn {
- @include m.focus-ring;
-
- display: inline-flex;
- align-items: center;
- justify-content: center;
- padding: v.$space-1;
- background: none;
- border: none;
- border-radius: v.$r-sm;
- color: v.$g400;
- cursor: pointer;
- transition: color v.$dur-fast v.$ease-out;
-
- &:hover {
- color: v.$g700;
- }
-}
-
-.message {
- margin: 0 0 v.$space-3;
- color: v.$g700;
- line-height: v.$lh-snug;
-}
-
-.details {
- padding: v.$space-3;
- background: rgba(0, 0, 0, 0.03);
- border-radius: v.$r-sm;
- margin-bottom: v.$space-3;
- font-size: v.$text-sm;
- color: v.$g600;
-}
-
-.actions {
- display: flex;
- gap: v.$space-3;
-}
-
-.actionBtn {
- @include m.button-base;
- @include m.focus-ring;
-
- background: v.$dark;
- color: v.$white;
-
- &:hover:not(:disabled) {
- background: v.$g800;
- }
-}
diff --git a/projects/sunbird-quml-player-react/src/components/Alert/Alert.test.tsx b/projects/sunbird-quml-player-react/src/components/Alert/Alert.test.tsx
deleted file mode 100644
index a5196306..00000000
--- a/projects/sunbird-quml-player-react/src/components/Alert/Alert.test.tsx
+++ /dev/null
@@ -1,59 +0,0 @@
-import { describe, it, expect, vi } from 'vitest';
-import { render, screen, fireEvent } from '@testing-library/react';
-import type { ReactNode } from 'react';
-import { QumlProvider } from '../../context/QumlContext';
-import { Alert } from './Alert';
-import type { PlayerConfig } from '../../types';
-
-const mockConfig: PlayerConfig = { context: {}, config: { language: 'en' } };
-const wrap = (ui: ReactNode) =>
- render({ui});
-
-describe('Alert', () => {
- it('renders the message with role="alert"', () => {
- wrap();
- const alert = screen.getByRole('alert');
- expect(alert).toBeInTheDocument();
- expect(alert).toHaveTextContent('Well done');
- });
-
- it('shows the correct title per type', () => {
- wrap();
- expect(screen.getByText(/correct answer/i)).toBeInTheDocument();
- });
-
- it.each(['correct', 'incorrect', 'partial', 'info'] as const)(
- 'renders the %s variant',
- (type) => {
- wrap();
- expect(screen.getByRole('alert')).toBeInTheDocument();
- },
- );
-
- it('fires onClose when the close button is clicked', () => {
- const onClose = vi.fn();
- wrap();
- fireEvent.click(screen.getByRole('button', { name: /close/i }));
- expect(onClose).toHaveBeenCalledTimes(1);
- });
-
- it('shows expected-answer details when provided', () => {
- wrap();
- expect(screen.getByText(/expected answer/i)).toBeInTheDocument();
- expect(screen.getByText(/Paris/)).toBeInTheDocument();
- });
-
- it('shows "View Solution" only when showSolution is true and fires its callback', () => {
- const onShowSolution = vi.fn();
- const { rerender } = wrap();
- expect(screen.queryByRole('button', { name: /view solution/i })).not.toBeInTheDocument();
-
- rerender(
-
-
- ,
- );
- fireEvent.click(screen.getByRole('button', { name: /view solution/i }));
- expect(onShowSolution).toHaveBeenCalledTimes(1);
- });
-});
diff --git a/projects/sunbird-quml-player-react/src/components/Alert/Alert.tsx b/projects/sunbird-quml-player-react/src/components/Alert/Alert.tsx
deleted file mode 100644
index 8941674d..00000000
--- a/projects/sunbird-quml-player-react/src/components/Alert/Alert.tsx
+++ /dev/null
@@ -1,76 +0,0 @@
-import { useQuml } from '../../context/useQuml';
-import { t } from '../../i18n/translations';
-import { CloseIcon } from '../icons';
-import styles from './Alert.module.scss';
-
-/**
- * Alert — inline dismissible feedback banner (per spec §3.3).
- *
- * Presentational: reads ONLY `state.language` from Context for translations;
- * everything else is props + callbacks. No toast behavior (per design decision),
- * no business logic, no scoring.
- */
-type AlertType = 'correct' | 'incorrect' | 'partial' | 'info';
-
-interface AlertProps {
- type?: AlertType;
- message?: string;
- /** Extra detail line (e.g. the expected answer). */
- details?: string | null;
- onClose?: () => void;
- showSolution?: boolean;
- onShowSolution?: () => void;
-}
-
-export function Alert({
- type = 'info',
- message = '',
- details = null,
- onClose,
- showSolution = false,
- onShowSolution,
-}: AlertProps) {
- const { state } = useQuml();
- const language = state.language;
-
- const typeLabel: Record = {
- correct: t(language, 'CORRECT_ANSWER'),
- incorrect: t(language, 'INCORRECT_ANSWER'),
- partial: t(language, 'PARTIAL_SCORE'),
- info: 'Info',
- };
-
- return (
-
-
- {typeLabel[type]}
-
-
-
- {message &&
{message}
}
-
- {details && (
-
-
- {t(language, 'EXPECTED_ANSWER')}: {details}
-
-
- )}
-
- {showSolution && (
-
-
-
- )}
-
- );
-}
diff --git a/projects/sunbird-quml-player-react/src/components/Header/Header.module.scss b/projects/sunbird-quml-player-react/src/components/Header/Header.module.scss
deleted file mode 100644
index 2f931fc1..00000000
--- a/projects/sunbird-quml-player-react/src/components/Header/Header.module.scss
+++ /dev/null
@@ -1,116 +0,0 @@
-@use '../../styles/variables' as v;
-@use '../../styles/mixins' as m;
-
-.header {
- position: sticky;
- top: 0;
- z-index: 100;
- display: flex;
- justify-content: space-between;
- align-items: center;
- gap: v.$space-4;
- min-height: 54px;
- padding: v.$space-2 v.$space-4;
- background: v.$ivory;
- border-bottom: 1px solid v.$gray-200;
-}
-
-.left,
-.center,
-.right {
- display: flex;
- align-items: center;
- gap: v.$space-3;
-}
-
-// Mobile-only navigation menu toggle (spec §6.6); hidden ≥ 768px where the
-// persistent sidebar is visible.
-.menuBtn {
- @include m.focus-ring;
-
- display: none;
- align-items: center;
- justify-content: center;
- padding: v.$space-1;
- border: none;
- border-radius: v.$r-sm;
- background: transparent;
- color: v.$g600;
- cursor: pointer;
-
- &:hover {
- background: v.$g100;
- color: v.$g900;
- }
-
- @include m.mobile {
- display: inline-flex;
- }
-}
-
-.counter {
- font-family: v.$ff-base;
- font-size: v.$text-sm;
- font-weight: v.$fw-medium;
- color: v.$g600;
- font-variant-numeric: tabular-nums;
- white-space: nowrap;
-}
-
-.timer {
- display: inline-flex;
- align-items: center;
- gap: v.$space-2;
- padding: v.$space-1 v.$space-3;
- border-radius: v.$r-sm;
- background: v.$g100;
- color: v.$g600;
- font-family: v.$ff-base;
- font-size: v.$text-xs;
- font-weight: v.$fw-semibold;
- font-variant-numeric: tabular-nums;
- white-space: nowrap;
- transition: background v.$dur-fast v.$ease-out, color v.$dur-fast v.$ease-out;
-}
-
-.timerIcon {
- display: block;
-}
-
-// Low-time warning (≤ 60s): red + gentle pulse — visual fidelity to the design.
-.timerLow {
- background: v.$danger-bg;
- color: v.$danger;
- animation: header-timer-pulse 1s ease-in-out infinite;
-}
-
-@keyframes header-timer-pulse {
- 0%,
- 100% {
- opacity: 1;
- }
- 50% {
- opacity: 0.7;
- }
-}
-
-.navBtn {
- @include m.button-base;
- @include m.focus-ring;
-
- background: transparent;
- color: v.$g600;
- border: 1.5px solid v.$gray-200;
-
- &:hover:not(:disabled) {
- border-color: v.$g400;
- color: v.$g900;
- background: v.$cream-bg;
- }
-}
-
-.navLabel {
- @include m.mobile {
- display: none;
- }
-}
diff --git a/projects/sunbird-quml-player-react/src/components/Header/Header.test.tsx b/projects/sunbird-quml-player-react/src/components/Header/Header.test.tsx
deleted file mode 100644
index c9ad1d4e..00000000
--- a/projects/sunbird-quml-player-react/src/components/Header/Header.test.tsx
+++ /dev/null
@@ -1,53 +0,0 @@
-import { describe, it, expect, vi } from 'vitest';
-import { render, screen, fireEvent } from '@testing-library/react';
-import type { ReactNode } from 'react';
-import { QumlProvider } from '../../context/QumlContext';
-import { Header } from './Header';
-import type { PlayerConfig } from '../../types';
-
-const mockConfig: PlayerConfig = { context: {}, config: { language: 'en' } };
-
-const wrap = (ui: ReactNode) =>
- render({ui});
-
-describe('Header', () => {
- it('renders the question counter', () => {
- wrap();
- expect(screen.getByText(/Question 3 of 10/i)).toBeInTheDocument();
- });
-
- it('shows the timer (mm:ss) when timeRemaining is provided', () => {
- wrap();
- expect(screen.getByText('1:05')).toBeInTheDocument();
- });
-
- it('hides the timer when timeRemaining is null', () => {
- wrap();
- expect(screen.queryByRole('timer')).not.toBeInTheDocument();
- });
-
- it('disables Previous on the first question', () => {
- wrap();
- expect(screen.getByRole('button', { name: /previous/i })).toBeDisabled();
- });
-
- it('disables Next on the last question', () => {
- wrap();
- expect(screen.getByRole('button', { name: /next/i })).toBeDisabled();
- });
-
- it('emits onPrevious / onNext via callbacks', () => {
- const onPrevious = vi.fn();
- const onNext = vi.fn();
- wrap();
- fireEvent.click(screen.getByRole('button', { name: /previous/i }));
- fireEvent.click(screen.getByRole('button', { name: /next/i }));
- expect(onPrevious).toHaveBeenCalledTimes(1);
- expect(onNext).toHaveBeenCalledTimes(1);
- });
-
- it('does not render a bookmark control', () => {
- wrap();
- expect(screen.queryByRole('button', { name: /bookmark/i })).not.toBeInTheDocument();
- });
-});
diff --git a/projects/sunbird-quml-player-react/src/components/Header/Header.tsx b/projects/sunbird-quml-player-react/src/components/Header/Header.tsx
deleted file mode 100644
index ca077aa9..00000000
--- a/projects/sunbird-quml-player-react/src/components/Header/Header.tsx
+++ /dev/null
@@ -1,106 +0,0 @@
-import { useQuml } from '../../context/useQuml';
-import { t } from '../../i18n/translations';
-import { PreviousIcon, NextIcon, TimerIcon, MenuIcon } from '../icons';
-import styles from './Header.module.scss';
-
-/**
- * Header — presentational top bar: question counter, optional timer, and
- * previous/next navigation.
- *
- * Per spec §3.2 it reads ONLY `state.language` from Context (for translations);
- * everything else arrives as typed props and intent is emitted via callbacks.
- * No bookmark (sidebar is the navigation pattern), no NavBar, no business logic.
- */
-interface HeaderProps {
- questionNumber?: number;
- totalQuestions?: number;
- /** Seconds remaining; `null`/omitted hides the timer. */
- timeRemaining?: number | null;
- onPrevious?: () => void;
- onNext?: () => void;
- isFirstQuestion?: boolean;
- isLastQuestion?: boolean;
- /** When provided, renders a mobile-only menu button (toggles the sections drawer, spec §6.6). */
- onMenuClick?: () => void;
-}
-
-/** Local mm:ss formatter (per spec §3.2 — distinct from utils/time HH:MM:SS). */
-function formatTime(seconds: number): string {
- const mins = Math.floor(seconds / 60);
- const secs = seconds % 60;
- return `${mins}:${String(secs).padStart(2, '0')}`;
-}
-
-export function Header({
- questionNumber = 1,
- totalQuestions = 10,
- timeRemaining = null,
- onPrevious,
- onNext,
- isFirstQuestion = false,
- isLastQuestion = false,
- onMenuClick,
-}: HeaderProps) {
- const { state } = useQuml();
- const language = state.language;
-
- const showTimer = timeRemaining != null;
- const isTimeLow = showTimer && timeRemaining <= 60;
-
- return (
-
-
- {onMenuClick && (
-
- )}
-
- {t(language, 'QUESTION')} {questionNumber} {t(language, 'OF')} {totalQuestions}
-
-
-
-
- {showTimer && (
-
-
- {formatTime(timeRemaining)}
-
- )}
-
-
-
-
-
-
-
-
- );
-}
diff --git a/projects/sunbird-quml-player-react/src/components/Hint/Hint.module.scss b/projects/sunbird-quml-player-react/src/components/Hint/Hint.module.scss
deleted file mode 100644
index d2a5b168..00000000
--- a/projects/sunbird-quml-player-react/src/components/Hint/Hint.module.scss
+++ /dev/null
@@ -1,56 +0,0 @@
-@use '../../styles/variables' as v;
-@use '../../styles/mixins' as m;
-
-.hint {
- display: flex;
- flex-direction: column;
- gap: v.$space-4;
- margin-top: v.$space-8;
-
- @include m.short {
- margin-top: v.$space-3;
- }
-}
-
-.actions {
- display: flex;
- flex-wrap: wrap;
- gap: v.$space-3;
-}
-
-.toggleBtn {
- @include m.button-base;
- @include m.focus-ring;
-
- background: transparent;
- color: v.$brick-shade;
- border: 1.5px solid v.$brick;
-
- &:hover:not(:disabled) {
- background: v.$brick-lt;
- }
-}
-
-.panel {
- padding: v.$space-5;
- border-radius: v.$r-sm;
- font-family: v.$ff-base;
-}
-
-.hintPanel {
- background: v.$sunflower;
- color: v.$g800;
-}
-
-.solutionPanel {
- background: v.$success-bg;
- color: v.$g800;
-}
-
-.panelHeading {
- margin: 0 0 v.$space-3;
- font-size: v.$text-sm;
- font-weight: v.$fw-semibold;
- text-transform: uppercase;
- letter-spacing: 0.04em;
-}
diff --git a/projects/sunbird-quml-player-react/src/components/Hint/Hint.test.tsx b/projects/sunbird-quml-player-react/src/components/Hint/Hint.test.tsx
deleted file mode 100644
index 91e5436d..00000000
--- a/projects/sunbird-quml-player-react/src/components/Hint/Hint.test.tsx
+++ /dev/null
@@ -1,52 +0,0 @@
-import { describe, it, expect } from 'vitest';
-import { render, screen, fireEvent } from '@testing-library/react';
-import { Hint } from './Hint';
-
-describe('Hint', () => {
- it('renders nothing when there is no content', () => {
- const { container } = render();
- expect(container).toBeEmptyDOMElement();
- });
-
- it('shows the hint button when showHints is set and hints are supplied', () => {
- render(Think about Mars.
' }]} showHints />);
- const toggle = screen.getByRole('button', { name: /show hint/i });
- expect(toggle).toHaveAttribute('aria-expanded', 'false');
- fireEvent.click(toggle);
- expect(screen.getByRole('button', { name: /hide hint/i })).toHaveAttribute(
- 'aria-expanded',
- 'true',
- );
- });
-
- it('hides the hint button when showHints is false, even with hint content', () => {
- render(Think about Mars.' }]} />);
- expect(screen.queryByRole('button', { name: /show hint/i })).not.toBeInTheDocument();
- });
-
- it('hides the View Solution button until the learner has interacted', () => {
- render(Because iron oxide.' }]} showSolutions />);
- // canViewSolution defaults to false → no solution button yet.
- expect(screen.queryByRole('button', { name: /view solution/i })).not.toBeInTheDocument();
- });
-
- it('hides the View Solution button when showSolutions is false, even after interaction', () => {
- render(Because iron oxide.' }]} canViewSolution />);
- // showSolutions defaults to false → button stays hidden despite interaction + content.
- expect(screen.queryByRole('button', { name: /view solution/i })).not.toBeInTheDocument();
- });
-
- it('shows the View Solution button once opted in and unlocked, and reveals the solution', () => {
- render(
- Because iron oxide.' }]} canViewSolution showSolutions />,
- );
- fireEvent.click(screen.getByRole('button', { name: /view solution/i }));
- expect(screen.getByText(/^solution$/i)).toBeInTheDocument();
- });
-
- it('falls back to the SA answer as the solution body when opted in and unlocked', () => {
- render();
- fireEvent.click(screen.getByRole('button', { name: /view solution/i }));
- expect(screen.getByText(/^solution$/i)).toBeInTheDocument();
- });
-});
diff --git a/projects/sunbird-quml-player-react/src/components/Hint/Hint.tsx b/projects/sunbird-quml-player-react/src/components/Hint/Hint.tsx
deleted file mode 100644
index c6c70a3e..00000000
--- a/projects/sunbird-quml-player-react/src/components/Hint/Hint.tsx
+++ /dev/null
@@ -1,129 +0,0 @@
-import { useState } from 'react';
-import { t, readI18n } from '../../i18n/translations';
-import { QuestionBody } from '../QuestionBody/QuestionBody';
-import { HintIcon } from '../icons';
-import type { I18nValue } from '../../types';
-import type { MediaResolveContext } from '../../utils/media';
-import styles from './Hint.module.scss';
-
-/**
- * Hint + Solution reveal UI (spec §6.8).
- *
- * Pure UI over already-normalized question content. Visibility is gated by the
- * section's showHints/showSolutions flags AND content presence (Angular parity —
- * section-player.component.ts:241,244; alert...html:126-127):
- * - "Show Hint" appears when `showHints` is true AND the backend supplied hints.
- * - "View Solution" appears when `showSolutions` is true AND solution/answer
- * content exists AND `canViewSolution` is true (learner has interacted).
- * Absent flags are falsy, so the buttons stay hidden unless the creator opts in.
- * No scoring, no Context mutation. HTML/KaTeX is rendered via QuestionBody.
- */
-export interface HintProps {
- hints?: unknown[];
- solutions?: unknown[];
- /** SA model answer (used as the solution body when no `solutions` are sent). */
- answer?: string | I18nValue;
- /** Unlock the View Solution button — set once the learner has interacted. */
- canViewSolution?: boolean;
- /** Section flag: creator opted in to showing hints. Absent → hidden. */
- showHints?: boolean;
- /** Section flag: creator opted in to showing solutions. Absent → hidden. */
- showSolutions?: boolean;
- language?: string;
- /** Media + offline resolution inputs so solution/hint assets resolve like the stem. */
- mediaCtx?: MediaResolveContext;
-}
-
-/**
- * Extract renderable HTML from a QuML hint/solution array entry.
- * The candidate may be a plain string or an I18nValue map (API form) — localize
- * via readI18n so both offline and fetched content render.
- */
-function extractHtml(entry: unknown, language: string): string {
- if (typeof entry === 'string') return entry;
- if (entry && typeof entry === 'object') {
- const obj = entry as Record;
- const candidate = obj.value ?? obj.body ?? obj.solution ?? obj.hint;
- if (typeof candidate === 'string') return candidate;
- if (candidate && typeof candidate === 'object') {
- return readI18n(candidate as I18nValue, language);
- }
- }
- return '';
-}
-
-export function Hint({
- hints = [],
- solutions = [],
- answer,
- canViewSolution = false,
- showHints: showHintsFlag = false,
- showSolutions: showSolutionsFlag = false,
- language = 'en',
- mediaCtx,
-}: HintProps) {
- const [showHint, setShowHint] = useState(false);
- const [showSolution, setShowSolution] = useState(false);
-
- const hintHtml = hints.map((h) => extractHtml(h, language)).filter(Boolean);
- const solutionHtml = solutions.map((s) => extractHtml(s, language)).filter(Boolean);
- const answerText = readI18n(answer, language);
-
- // Hint button: section opted in (showHints) AND the backend sent hint content.
- const hasHints = showHintsFlag && hintHtml.length > 0;
- // Solution button: section opted in (showSolutions) AND the learner has
- // interacted (canViewSolution) AND there is solution/answer content to reveal.
- const hasSolution =
- showSolutionsFlag && canViewSolution && (solutionHtml.length > 0 || Boolean(answerText));
-
- if (!hasHints && !hasSolution) return null;
-
- return (
-
-
- {hasHints && (
-
- )}
- {hasSolution && (
-
- )}
-
-
- {showHint && hasHints && (
-
-
{t(language, 'HINT')}
- {hintHtml.map((html, i) => (
-
- ))}
-
- )}
-
- {showSolution && hasSolution && (
-
-
{t(language, 'SOLUTION')}
- {solutionHtml.map((html, i) => (
-
- ))}
- {solutionHtml.length === 0 && answerText && (
-
- )}
-
- )}
-
- );
-}
diff --git a/projects/sunbird-quml-player-react/src/components/ImageViewer/ImageViewer.tsx b/projects/sunbird-quml-player-react/src/components/ImageViewer/ImageViewer.tsx
deleted file mode 100644
index 1b386922..00000000
--- a/projects/sunbird-quml-player-react/src/components/ImageViewer/ImageViewer.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import './image-viewer.css';
-import type { ImageZoomState } from './useImageZoom';
-
-/**
- * Full-screen image viewer overlay.
- * Mirrors Angular section-player.component.html:143-153 (image-viewer overlay,
- * close button, zoom-in/out) and applies the portrait/landscape/neutral class to
- * the enlarged image, matching setImageZoom()'s #imageModal handling.
- */
-interface ImageViewerProps {
- state: ImageZoomState;
- onClose: () => void;
- onZoomIn: () => void;
- onZoomOut: () => void;
-}
-
-export function ImageViewer({ state, onClose, onZoomIn, onZoomOut }: ImageViewerProps) {
- if (!state.open) return null;
-
- return (
-
-
-
-

-
-
-
-
-
-
- );
-}
diff --git a/projects/sunbird-quml-player-react/src/components/ImageViewer/image-viewer.css b/projects/sunbird-quml-player-react/src/components/ImageViewer/image-viewer.css
deleted file mode 100644
index 197fb929..00000000
--- a/projects/sunbird-quml-player-react/src/components/ImageViewer/image-viewer.css
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Image viewer + magnify styles.
- * Mirrors Angular section-player.component.scss (.image-viewer__*, .magnify-icon,
- * .portrait/.landscape/.neutral). Global (not CSS-modules) because the magnify
- * icon and its orientation classes are attached to DOM injected via
- * dangerouslySetInnerHTML, which module-scoped class names cannot reach.
- */
-
-.image-viewer__overlay,
-.image-viewer__container,
-.image-viewer__close,
-.image-viewer__zoom {
- position: absolute;
-}
-
-.image-viewer__overlay {
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background: #fff;
- z-index: 11111;
-}
-
-.image-viewer__container {
- background-color: #fff;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- z-index: 11111;
- width: 80%;
- height: 80%;
- display: flex;
- align-items: center;
- justify-content: center;
-}
-
-.image-viewer__img {
- width: 100%;
- height: 100%;
- object-fit: contain;
-}
-
-.image-viewer__container .portrait {
- width: auto;
- height: 100%;
-}
-
-.image-viewer__container .neutral {
- width: auto;
- height: auto;
-}
-
-.image-viewer__container .landscape {
- width: 100%;
- height: auto;
-}
-
-.image-viewer__close {
- top: 1rem;
- right: 1rem;
- text-align: center;
- cursor: pointer;
- z-index: 999999;
- background: rgba(0, 0, 0, 0.5);
- border-radius: 100%;
- width: 3rem;
- height: 3rem;
- border: none;
-}
-
-.image-viewer__close::after {
- content: "\2715";
- color: #fff;
- font-size: 2rem;
-}
-
-.image-viewer__close:hover {
- background: rgba(0, 0, 0, 1);
-}
-
-.image-viewer__zoom {
- bottom: 1rem;
- right: 1rem;
- width: 2.5rem;
- border-radius: 0.5rem;
- background: #fff;
- display: flex;
- flex-direction: column;
- align-items: center;
- overflow: hidden;
- z-index: 99999;
- border: 0.0625rem solid #ccc;
-}
-
-.image-viewer__zoomin,
-.image-viewer__zoomout {
- text-align: center;
- height: 2.5rem;
- width: 2.5rem;
- cursor: pointer;
- font-size: 1.5rem;
- line-height: 2.5rem;
- background: none;
- border: none;
-}
-
-.image-viewer__zoomin:hover,
-.image-viewer__zoomout:hover {
- background-color: #f0f0f0;
-}
-
-.image-viewer__zoomin {
- border-bottom: 0.0625rem solid #e0e0e0;
-}
-
-/* Magnify icon injected next to each data-asset-variable image. */
-.magnify-icon {
- position: absolute;
- right: 0;
- bottom: 0;
- width: 1.5rem;
- height: 1.5rem;
- border-top-left-radius: 0.5rem;
- cursor: pointer;
- background-color: #fff;
-}
-
-.magnify-icon::after {
- content: "";
- position: absolute;
- bottom: 0.125rem;
- right: 0.125rem;
- z-index: 1;
- width: 1rem;
- height: 1rem;
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 37.166 37.166'%3E%3Cpath d='M35.829,32.045l-6.833-6.833c-0.513-0.513-1.167-0.788-1.836-0.853c2.06-2.567,3.298-5.819,3.298-9.359 c0-8.271-6.729-15-15-15c-8.271,0-15,6.729-15,15c0,8.271,6.729,15,15,15c3.121,0,6.021-0.96,8.424-2.598 c0.018,0.744,0.305,1.482,0.872,2.052l6.833,6.833c0.585,0.586,1.354,0.879,2.121,0.879s1.536-0.293,2.121-0.879 C37.001,35.116,37.001,33.217,35.829,32.045z M15.458,25c-5.514,0-10-4.484-10-10c0-5.514,4.486-10,10-10c5.514,0,10,4.486,10,10 C25.458,20.516,20.972,25,15.458,25z M22.334,15c0,1.104-0.896,2-2,2h-2.75v2.75c0,1.104-0.896,2-2,2s-2-0.896-2-2V17h-2.75 c-1.104,0-2-0.896-2-2s0.896-2,2-2h2.75v-2.75c0-1.104,0.896-2,2-2s2,0.896,2,2V13h2.75C21.438,13,22.334,13.895,22.334,15z' fill='%23333'/%3E%3C/svg%3E");
- background-size: cover;
- background-repeat: no-repeat;
- background-position: center;
-}
diff --git a/projects/sunbird-quml-player-react/src/components/ImageViewer/useImageZoom.ts b/projects/sunbird-quml-player-react/src/components/ImageViewer/useImageZoom.ts
deleted file mode 100644
index 9cc4d46e..00000000
--- a/projects/sunbird-quml-player-react/src/components/ImageViewer/useImageZoom.ts
+++ /dev/null
@@ -1,103 +0,0 @@
-import { useEffect, useState, useCallback } from 'react';
-import type { RefObject } from 'react';
-import './image-viewer.css';
-
-/**
- * Image zoom / click-to-enlarge, ported from the Angular web-component.
- *
- * Mirrors:
- * - section-player.component.ts:setImageZoom() (magnify icon + open)
- * - section-player.component.ts:setImageHeightWidthClass() (portrait/landscape)
- * - section-player.component.ts:zoomIn/zoomOut/closeZoom()
- *
- * Angular queries the whole document after each slide change; here we scope the
- * pass to a container ref and re-run on DOM mutations (covering late-rendered
- * solution content), which reproduces the same runtime result.
- */
-
-export type Orientation = 'portrait' | 'landscape' | 'neutral';
-
-export interface ImageZoomState {
- open: boolean;
- src: string;
- orientation: Orientation;
- /** Zoom percentage; starts at 100, +/-10 per step, min 100 (Angular parity). */
- zoom: number;
-}
-
-const INITIAL: ImageZoomState = { open: false, src: '', orientation: 'neutral', zoom: 100 };
-
-/** Portrait if taller than wide, landscape if wider, else neutral (Angular rule). */
-function orientationOf(img: HTMLImageElement): Orientation {
- const h = img.naturalHeight || img.clientHeight;
- const w = img.naturalWidth || img.clientWidth;
- if (h > w) return 'portrait';
- if (h < w) return 'landscape';
- return 'neutral';
-}
-
-export function useImageZoom(
- containerRef: RefObject,
- deps: unknown[] = [],
-) {
- const [state, setState] = useState(INITIAL);
-
- const openViewer = useCallback((img: HTMLImageElement) => {
- setState({ open: true, src: img.src, orientation: orientationOf(img), zoom: 100 });
- }, []);
-
- const close = useCallback(() => setState((s) => ({ ...s, open: false, zoom: 100 })), []);
- const zoomIn = useCallback(() => setState((s) => ({ ...s, zoom: s.zoom + 10 })), []);
- // Mirrors Angular zoomOut(): only steps down while above 100%.
- const zoomOut = useCallback(
- () => setState((s) => (s.zoom > 100 ? { ...s, zoom: s.zoom - 10 } : s)),
- [],
- );
-
- useEffect(() => {
- const root = containerRef.current;
- if (!root) return;
-
- // Mirrors setImageZoom() + setImageHeightWidthClass(): decorate every
- // data-asset-variable
with an orientation class + a magnify icon.
- const decorate = () => {
- const images = root.querySelectorAll('img[data-asset-variable]');
- images.forEach((image) => {
- if (image.dataset.zoomBound === 'true') return;
- image.dataset.zoomBound = 'true';
- image.classList.add('option-image');
-
- const applyOrientation = () => {
- image.classList.remove('portrait', 'landscape', 'neutral');
- image.classList.add(orientationOf(image));
- };
- if (image.complete) applyOrientation();
- else image.addEventListener('load', applyOrientation, { once: true });
-
- const icon = document.createElement('div');
- icon.className = 'magnify-icon';
- icon.onclick = (event) => {
- event.stopPropagation();
- openViewer(image);
- };
- if (image.parentNode) {
- // Ensure the icon anchors to a positioned parent.
- const parent = image.parentElement;
- if (parent && getComputedStyle(parent).position === 'static') {
- parent.style.position = 'relative';
- }
- image.parentNode.insertBefore(icon, image.nextSibling);
- }
- });
- };
-
- decorate();
- // Re-decorate when solution/hint content mounts later.
- const observer = new MutationObserver(() => decorate());
- observer.observe(root, { childList: true, subtree: true });
- return () => observer.disconnect();
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, deps);
-
- return { state, close, zoomIn, zoomOut };
-}
diff --git a/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.embedded-render.test.tsx b/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.embedded-render.test.tsx
deleted file mode 100644
index fd9c1082..00000000
--- a/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.embedded-render.test.tsx
+++ /dev/null
@@ -1,117 +0,0 @@
-import { describe, it, expect } from 'vitest';
-import { render, screen, fireEvent } from '@testing-library/react';
-import { QumlProvider } from '../../context/QumlContext';
-import { MainPlayer } from './MainPlayer';
-import type { PlayerConfig } from '../../types';
-
-// The real editor/portal contract: the WHOLE questionset with question content
-// embedded in metadata.children (Section A: MCQ + SA; Section B: FTB + REO).
-// This drives the full render path (no network) to prove questions actually paint.
-const metadata = {
- identifier: 'do_214609811633471488164',
- name: 'Sample question set',
- objectType: 'QuestionSetImage',
- timeLimits: { questionSet: { max: 0, min: 0 } },
- children: [
- {
- identifier: 'do_secA',
- name: 'Section A',
- objectType: 'QuestionSet',
- index: 1,
- children: [
- {
- identifier: 'do_q1',
- name: 'Q1',
- objectType: 'Question',
- primaryCategory: 'Multiple Choice Question',
- qType: 'MCQ',
- index: 1,
- maxScore: 5,
- body: 'Which is the capital of France?
',
- interactions: {
- response1: {
- type: 'choice',
- options: [
- { label: { en: 'New York' }, value: 0 },
- { label: { en: 'Paris' }, value: 1 },
- ],
- },
- },
- responseDeclaration: {
- response1: { cardinality: 'single', type: 'integer', correctResponse: { value: 1 } },
- },
- },
- {
- identifier: 'do_q2',
- name: 'Q2',
- objectType: 'Question',
- primaryCategory: 'Subjective Question',
- qType: 'SA',
- index: 2,
- maxScore: 5,
- body: 'When is Independence Day observed in India',
- interactions: {},
- answer: '15th August
',
- },
- ],
- },
- {
- identifier: 'do_secB',
- name: 'Section B',
- objectType: 'QuestionSet',
- index: 2,
- children: [
- {
- identifier: 'do_q3',
- name: 'Q3',
- objectType: 'Question',
- primaryCategory: 'FTB Question',
- qType: 'FTB',
- index: 1,
- maxScore: 1,
- body: 'The tree is [[response1]]',
- interactions: { response1: { type: 'text' } },
- responseProcessing: { template: 'MAP_RESPONSE' },
- responseDeclaration: {
- response1: {
- cardinality: 'single',
- type: 'string',
- correctResponse: { value: 'tall' },
- mapping: [{ value: 'tall', score: 1, caseSensitive: false }],
- },
- },
- },
- ],
- },
- ],
-};
-
-const cfg: PlayerConfig = { context: {}, config: { language: 'en' }, metadata, data: {} };
-
-const renderPlayer = () =>
- render(
-
-
- ,
- );
-
-describe('MainPlayer — renders from embedded metadata (portal/editor contract)', () => {
- it('shows the real assessment name on the overview (not the fallback)', () => {
- renderPlayer();
- expect(screen.queryByText(/loading/i)).not.toBeInTheDocument();
- // Real name proves metadata was consumed (fallback would be "Assessment Overview").
- expect(screen.getByText('Sample question set')).toBeInTheDocument();
- expect(screen.getByRole('button', { name: /start assessment/i })).toBeInTheDocument();
- });
-
- it('paints the first question stem + options after entering the assessment', () => {
- renderPlayer();
- fireEvent.click(screen.getByRole('button', { name: /start assessment/i }));
- fireEvent.click(screen.getByRole('button', { name: /start section/i }));
- // The MCQ stem and both option labels actually reach the DOM.
- expect(screen.getByText(/capital of France/i)).toBeInTheDocument();
- expect(screen.getByText('Paris')).toBeInTheDocument();
- expect(screen.getByText('New York')).toBeInTheDocument();
- expect(screen.getAllByRole('radio')).toHaveLength(2);
- });
-});
diff --git a/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.max-attempts.test.tsx b/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.max-attempts.test.tsx
deleted file mode 100644
index 5f292fe8..00000000
--- a/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.max-attempts.test.tsx
+++ /dev/null
@@ -1,147 +0,0 @@
-import { describe, it, expect, vi } from 'vitest';
-import { render, screen, fireEvent, within } from '@testing-library/react';
-import { QumlProvider } from '../../context/QumlContext';
-import { MainPlayer } from './MainPlayer';
-import type { PlayerConfig } from '../../types';
-
-// Angular parity (main-player.component.ts:249,253,483-485) — maxAttempts is
-// host/backend data under `playerConfig.metadata`, not `config`.
-const baseData = {
- showTimer: false,
- sections: [
- {
- identifier: 's1',
- name: 'Section 1',
- timeLimits: { questionSet: { max: 0, min: 0 } },
- children: [
- {
- identifier: 'q1',
- body: 'Q1
',
- primaryCategory: 'Multiple Choice Question',
- interactions: { response1: { options: [{ value: 0, label: 'Apple' }, { value: 1, label: 'Banana' }] } },
- responseDeclaration: {
- response1: { cardinality: 'single', type: 'integer', correctResponse: { value: 0 } },
- },
- },
- ],
- },
- ],
-};
-
-const enterAssessment = () => {
- fireEvent.click(screen.getByRole('button', { name: /start assessment/i }));
- fireEvent.click(screen.getByRole('button', { name: /start section/i }));
-};
-
-const submitAssessment = () => {
- fireEvent.click(screen.getAllByRole('radio')[0]); // answer correctly
- fireEvent.click(screen.getAllByRole('button', { name: /^submit$/i })[0]);
- const dialog = screen.getByRole('dialog');
- fireEvent.click(within(dialog).getByRole('button', { name: /^submit$/i }));
-};
-
-describe('MainPlayer — max attempts (Angular parity)', () => {
- it('hides Retake on Results once this attempt is the last one allowed', () => {
- const cfg: PlayerConfig = {
- context: {},
- config: { language: 'en' },
- metadata: { maxAttempts: 1 },
- data: baseData,
- };
- render(
-
-
- ,
- );
- enterAssessment();
- submitAssessment();
- expect(screen.getByRole('heading', { name: /your results/i })).toBeInTheDocument();
- expect(screen.queryByRole('button', { name: /retake/i })).not.toBeInTheDocument();
- });
-
- it('keeps Retake when attempts remain', () => {
- const cfg: PlayerConfig = {
- context: {},
- config: { language: 'en' },
- metadata: { maxAttempts: 3 },
- data: baseData,
- };
- render(
-
-
- ,
- );
- enterAssessment();
- submitAssessment();
- expect(screen.getByRole('button', { name: /retake/i })).toBeInTheDocument();
- });
-
- it('emits an exdata isLastAttempt event when the final attempt starts', () => {
- const onPlayerEvent = vi.fn();
- const cfg: PlayerConfig = {
- context: {},
- config: { language: 'en' },
- metadata: { maxAttempts: 1 },
- data: baseData,
- };
- render(
-
-
- ,
- );
- expect(onPlayerEvent).toHaveBeenCalledWith(
- expect.objectContaining({
- eid: 'exdata',
- edata: expect.objectContaining({
- currentattempt: 1,
- isLastAttempt: true,
- maxLimitExceeded: false,
- }),
- }),
- );
- });
-
- it('emits an exdata maxLimitExceeded event when the last attempt is submitted', () => {
- const onPlayerEvent = vi.fn();
- const cfg: PlayerConfig = {
- context: {},
- config: { language: 'en' },
- metadata: { maxAttempts: 1 },
- data: baseData,
- };
- render(
-
-
- ,
- );
- onPlayerEvent.mockClear();
- enterAssessment();
- submitAssessment();
- expect(onPlayerEvent).toHaveBeenCalledWith(
- expect.objectContaining({
- eid: 'exdata',
- edata: expect.objectContaining({
- currentattempt: 1,
- isLastAttempt: false,
- maxLimitExceeded: true,
- }),
- }),
- );
- });
-
- it('does not restrict Retake when maxAttempts is not sent (unlimited)', () => {
- const cfg: PlayerConfig = {
- context: {},
- config: { language: 'en' },
- data: baseData,
- };
- render(
-
-
- ,
- );
- enterAssessment();
- submitAssessment();
- expect(screen.getByRole('button', { name: /retake/i })).toBeInTheDocument();
- });
-});
diff --git a/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.metadata-config.test.tsx b/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.metadata-config.test.tsx
deleted file mode 100644
index fc9375d8..00000000
--- a/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.metadata-config.test.tsx
+++ /dev/null
@@ -1,79 +0,0 @@
-import { describe, it, expect, vi } from 'vitest';
-import { render, screen, waitFor, act } from '@testing-library/react';
-import { QumlProvider } from '../../context/QumlContext';
-import { MainPlayer } from './MainPlayer';
-import type { PlayerConfig } from '../../types';
-
-// The Sunbird editor/portal pass the questionset under `playerConfig.metadata`
-// (Angular contract) with `data` empty. Mock the data service to assert the
-// player fetches using the identifier taken from metadata.
-const { loadQuestionSet } = vi.hoisted(() => ({ loadQuestionSet: vi.fn() }));
-// These configs carry no embedded question content, so force the fetch path.
-vi.mock('../../services/data-service', () => ({
- loadQuestionSet,
- hasEmbeddedQuestions: () => false,
- transformEmbeddedQuestionSet: () => [],
-}));
-
-describe('MainPlayer — metadata config contract (editor/portal)', () => {
- it('fetches by identifier from playerConfig.metadata when data is empty', async () => {
- loadQuestionSet.mockResolvedValue({
- metadata: { name: 'questionset-t1' },
- sections: [],
- });
- const cfg: PlayerConfig = {
- context: {},
- config: { language: 'en' },
- metadata: { identifier: 'do_qs1', name: 'questionset-t1' },
- data: {},
- };
-
- render(
-
-
- ,
- );
-
- await waitFor(() =>
- expect(loadQuestionSet).toHaveBeenCalledWith('do_qs1', expect.anything()),
- );
- // The overview title reflects the fetched metadata name, not the fallback.
- await waitFor(() => expect(screen.getByText('questionset-t1')).toBeInTheDocument());
- });
-
- it('does not fetch when neither data nor metadata carries an identifier', async () => {
- loadQuestionSet.mockClear();
- const cfg: PlayerConfig = {
- context: {},
- config: { language: 'en' },
- metadata: {},
- data: {},
- };
- render(
-
-
- ,
- );
- // Flush effects with a single microtask tick; the no-identifier path returns
- // synchronously, so loadQuestionSet must not be called.
- await act(async () => {});
- expect(loadQuestionSet).not.toHaveBeenCalled();
- });
-
- it('does not fetch when the identifier is a non-string (guards against .../[object Object])', async () => {
- loadQuestionSet.mockClear();
- const cfg: PlayerConfig = {
- context: {},
- config: { language: 'en' },
- metadata: { identifier: { bad: true } as unknown as string },
- data: {},
- };
- render(
-
-
- ,
- );
- await act(async () => {});
- expect(loadQuestionSet).not.toHaveBeenCalled();
- });
-});
diff --git a/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.module.scss b/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.module.scss
deleted file mode 100644
index 69915483..00000000
--- a/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.module.scss
+++ /dev/null
@@ -1,108 +0,0 @@
-@use '../../styles/variables' as v;
-@use '../../styles/mixins' as m;
-
-// app-shell (column) → app-body (row: sidebar + main), collapsing to a single
-// column with a drawer < 768px (spec §6.6 / §6.11).
-.appShell {
- display: flex;
- flex-direction: column;
- height: 100%;
- width: 100%;
- max-width: 100%;
- // Query container for the player's responsive rules (m.mobile / m.tablet).
- // `inline-size` contains ONLY the inline (width) axis, so the height:100%
- // chain — and the :host height:100% freeze fix — is untouched. Every
- // responsive component is a descendant of this element, so they respond to
- // the player's own available width instead of the browser viewport (needed
- // for the editor's narrow mobile preview).
- container-type: inline-size;
- container-name: quml;
- // Positioning context for the player's overlays. The overlays (submit modal,
- // mobile sections drawer, feedback toast) are `position: absolute` and anchor
- // to THIS box, so they stay within the player instead of covering the whole
- // browser window when the player is embedded in a small frame (editor mobile
- // preview). When the player fills the viewport (portal, real mobile,
- // standalone) this box == the viewport, so it is visually identical to the
- // previous `position: fixed` behavior. (container-type does not reliably
- // establish a fixed-positioning containing block across browsers, so we rely
- // on absolute positioning + this explicit relative anchor instead.)
- position: relative;
- overflow-x: hidden; // hard guard: nothing scrolls the shell sideways
- // Overview / results / review render their screen directly in the shell (the
- // assessment stage scrolls via its inner .main). When the host constrains the
- // player height, those screens overflow and their bottom CTA (e.g. "Start
- // Assessment") gets clipped — so allow the shell itself to scroll vertically.
- // Harmless for the assessment stage: its content fills exactly 100% and scrolls
- // internally, so the shell never overflows.
- overflow-y: auto;
- background: v.$cream-bg;
- font-family: v.$ff-base;
-}
-
-.appBody {
- display: flex;
- flex: 1;
- min-height: 0;
- overflow: hidden; // sidebar + main scroll independently (design .app-body)
-}
-
-.sidebarSlot {
- flex-shrink: 0;
-
- @include m.mobile {
- display: none;
- }
-}
-
-.main {
- display: flex;
- flex-direction: column;
- flex: 1;
- min-width: 0;
- min-height: 0;
- overflow-x: hidden;
- overflow-y: auto;
-}
-
-.sectionStepsBar {
- display: flex;
- justify-content: center;
- padding: v.$space-4 v.$space-6;
- background: v.$ivory;
- border-bottom: 1px solid v.$gray-200;
-
- @include m.mobile {
- padding: v.$space-3 v.$space-4;
- }
-}
-
-.endPage {
- max-width: 640px;
- margin: 0 auto;
- padding: v.$space-12 v.$space-6;
- text-align: center;
-}
-
-.title {
- margin: 0 0 v.$space-2;
- font-size: v.$text-2xl;
- font-weight: v.$fw-bold;
- color: v.$dark;
-}
-
-.subtitle {
- margin: 0 0 v.$space-8;
- color: v.$g500;
-}
-
-.status,
-.error {
- padding: v.$space-12;
- text-align: center;
- font-family: v.$ff-base;
- color: v.$g600;
-}
-
-.error {
- color: v.$danger;
-}
diff --git a/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.portal-fetch.test.tsx b/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.portal-fetch.test.tsx
deleted file mode 100644
index 6b87b25b..00000000
--- a/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.portal-fetch.test.tsx
+++ /dev/null
@@ -1,104 +0,0 @@
-import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
-import { render, screen, fireEvent, waitFor } from '@testing-library/react';
-import { QumlProvider } from '../../context/QumlContext';
-import { MainPlayer } from './MainPlayer';
-import type { PlayerConfig } from '../../types';
-
-// Simulate the PORTAL end-to-end: it passes SHALLOW metadata (identifier only,
-// from /content/v1/read) and sets the /portal gateway URLs. The player must
-// fetch hierarchy (stubs) + list (bodies) from those URLs, merge, and render.
-vi.mock('../../services/http-client', () => ({ httpGet: vi.fn(), httpPost: vi.fn() }));
-import { httpGet, httpPost } from '../../services/http-client';
-const mockGet = httpGet as unknown as ReturnType;
-const mockPost = httpPost as unknown as ReturnType;
-
-// /portal/questionset/v2/hierarchy → sections with STUB questions (no body).
-const hierarchy = {
- questionset: {
- identifier: 'do_qs',
- name: 'Sample question set',
- objectType: 'QuestionSetImage',
- children: [
- {
- identifier: 'do_secA',
- name: 'Section A',
- objectType: 'QuestionSet',
- index: 1,
- children: [
- { identifier: 'do_q1', objectType: 'Question', qType: 'MCQ', primaryCategory: 'Multiple Choice Question', index: 1 },
- ],
- },
- ],
- },
-};
-
-// /portal/question/v2/list → full question content (bodies + interactions).
-const questions = [
- {
- identifier: 'do_q1',
- qType: 'MCQ',
- primaryCategory: 'Multiple Choice Question',
- maxScore: 5,
- body: 'Which is the capital of France?
',
- interactions: {
- response1: {
- type: 'choice',
- options: [
- { label: { en: 'New York' }, value: 0 },
- { label: { en: 'Paris' }, value: 1 },
- ],
- },
- },
- responseDeclaration: {
- response1: { cardinality: 'single', type: 'integer', correctResponse: { value: 1 } },
- },
- },
-];
-
-// Shallow metadata, exactly like the portal's content-read result.
-const cfg: PlayerConfig = {
- context: {},
- config: { language: 'en' },
- metadata: { identifier: 'do_qs', name: 'Sample question set' },
- data: {},
-};
-
-describe('MainPlayer — full portal path (shallow metadata → /portal fetch → render)', () => {
- beforeEach(() => {
- mockGet.mockReset();
- mockPost.mockReset();
- (window as any).questionSetHierarchyUrl = '/portal/questionset/v2/hierarchy/';
- (window as any).questionListUrl = '/portal/question/v2/list';
- });
- afterEach(() => {
- delete (window as any).questionSetHierarchyUrl;
- delete (window as any).questionListUrl;
- });
-
- it('fetches from the /portal gateway URLs, merges, and renders the question', async () => {
- mockGet.mockResolvedValue(hierarchy);
- mockPost.mockResolvedValue({ questions });
-
- render(
-
-
- ,
- );
-
- // Hierarchy fetched from the portal gateway route (not /learner).
- await waitFor(() =>
- expect(mockGet).toHaveBeenCalledWith('/portal/questionset/v2/hierarchy/do_qs?mode=edit', expect.anything()),
- );
- // Question list fetched from the portal gateway route (not /api or /action);
- // a ?lang= suffix is appended from config.language.
- expect(mockPost.mock.calls[0][0]).toContain('/portal/question/v2/list');
-
- // Overview shows, then enter the assessment and confirm the question paints.
- await waitFor(() => expect(screen.getByText('Sample question set')).toBeInTheDocument());
- fireEvent.click(screen.getByRole('button', { name: /start assessment/i }));
- fireEvent.click(screen.getByRole('button', { name: /start section/i }));
- expect(screen.getByText(/capital of France/i)).toBeInTheDocument();
- expect(screen.getByText('Paris')).toBeInTheDocument();
- expect(screen.getAllByRole('radio')).toHaveLength(2);
- });
-});
diff --git a/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.preview-config.test.tsx b/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.preview-config.test.tsx
deleted file mode 100644
index 37a27248..00000000
--- a/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.preview-config.test.tsx
+++ /dev/null
@@ -1,119 +0,0 @@
-import { describe, it, expect, vi } from 'vitest';
-import { render, screen, fireEvent, act } from '@testing-library/react';
-import { QumlProvider } from '../../context/QumlContext';
-import { MainPlayer } from './MainPlayer';
-import type { PlayerConfig } from '../../types';
-
-// Embedded single-question config, mirroring what the editor's single-question
-// preview sends. `showStartPage` / `requiresSubmit` live on the questionset
-// metadata (here, alongside the embedded sections → metadata === data).
-const buildConfig = (overrides: {
- showStartPage?: string;
- requiresSubmit?: string;
- showSectionIntro?: boolean;
-}): PlayerConfig => ({
- context: {},
- config: {
- language: 'en',
- showFeedback: true,
- ...(overrides.showSectionIntro !== undefined
- ? { showSectionIntro: overrides.showSectionIntro }
- : {}),
- },
- data: {
- ...(overrides.showStartPage !== undefined ? { showStartPage: overrides.showStartPage } : {}),
- ...(overrides.requiresSubmit !== undefined ? { requiresSubmit: overrides.requiresSubmit } : {}),
- sections: [
- {
- identifier: 's1',
- name: 'Section 1',
- timeLimits: { questionSet: { max: 0, min: 0 } },
- children: [
- {
- identifier: 'q1',
- body: 'Q1
',
- primaryCategory: 'Multiple Choice Question',
- interactions: {
- response1: { options: [{ value: 0, label: 'Apple' }, { value: 1, label: 'Banana' }] },
- },
- responseDeclaration: {
- response1: { cardinality: 'single', type: 'integer', correctResponse: { value: 0 } },
- },
- },
- ],
- },
- ],
- },
-});
-
-const renderPlayer = (cfg: PlayerConfig) =>
- render(
-
-
- ,
- );
-
-describe('MainPlayer — preview parity (showStartPage / requiresSubmit)', () => {
- it('showStartPage:"No" lands directly on the question (skips overview AND section intro — Angular parity)', () => {
- // Section intros are enabled by default (no showSectionIntro), yet the entry
- // still bypasses both the overview and the intro screen.
- renderPlayer(buildConfig({ showStartPage: 'No' }));
- expect(screen.queryByRole('button', { name: /start assessment/i })).not.toBeInTheDocument();
- expect(screen.queryByRole('button', { name: /start section/i })).not.toBeInTheDocument();
- // Straight into the first question.
- expect(screen.getByText('Apple')).toBeInTheDocument();
- expect(screen.getByText(/Question 1 of 1/i)).toBeInTheDocument();
- });
-
- it('normal content still shows the overview then the section intro (feature intact)', () => {
- renderPlayer(buildConfig({})); // no showStartPage → default flow
- // 1. Overview first.
- const start = screen.getByRole('button', { name: /start assessment/i });
- expect(screen.queryByText('Apple')).not.toBeInTheDocument();
- // 2. Start → section intro (intros default on, NOT skipped for normal content).
- fireEvent.click(start);
- const begin = screen.getByRole('button', { name: /start section/i });
- // 3. Begin → the question.
- fireEvent.click(begin);
- expect(screen.getByText('Apple')).toBeInTheDocument();
- });
-
- it('with showStartPage:"No", an explicit return to overview (Retake) shows it, not a stuck loader', () => {
- vi.useFakeTimers();
- try {
- renderPlayer(buildConfig({ showStartPage: 'No', requiresSubmit: 'No' }));
- // Initial: skipped overview, landed on the question.
- expect(screen.getByText('Apple')).toBeInTheDocument();
- // Submit (no confirmation) → results.
- const submits = screen.getAllByRole('button', { name: /^submit$/i });
- fireEvent.click(submits[submits.length - 1]);
- act(() => vi.advanceTimersByTime(1000));
- // Retake → returns to overview. The one-shot auto-start does NOT re-fire,
- // so the overview must actually render (regression: was a stuck loader).
- fireEvent.click(screen.getByRole('button', { name: /retake/i }));
- expect(screen.getByRole('button', { name: /start assessment/i })).toBeInTheDocument();
- } finally {
- vi.useRealTimers();
- }
- });
-
- it('requiresSubmit:"No" submits straight to results with no confirmation dialog', () => {
- vi.useFakeTimers();
- try {
- // Land directly on the question (showStartPage/showSectionIntro skipped)
- // so we can exercise the submit path in isolation.
- renderPlayer(
- buildConfig({ requiresSubmit: 'No', showStartPage: 'No', showSectionIntro: false }),
- );
- // On the only question; the bottom action is the final Submit.
- const submits = screen.getAllByRole('button', { name: /^submit$/i });
- fireEvent.click(submits[submits.length - 1]);
- act(() => vi.advanceTimersByTime(1000)); // feedback dwell then proceed
- // No confirmation dialog — straight to the results screen.
- expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
- expect(screen.getByRole('button', { name: /review all answers/i })).toBeInTheDocument();
- } finally {
- vi.useRealTimers();
- }
- });
-});
diff --git a/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.reorder-telemetry.test.tsx b/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.reorder-telemetry.test.tsx
deleted file mode 100644
index e6b5ec1b..00000000
--- a/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.reorder-telemetry.test.tsx
+++ /dev/null
@@ -1,83 +0,0 @@
-import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
-import { render, screen, fireEvent } from '@testing-library/react';
-import { QumlProvider } from '../../context/QumlContext';
-import { MainPlayer } from './MainPlayer';
-import { initializeTelemetry } from '../../services/telemetry-service';
-import type { PlayerConfig, TelemetryContext } from '../../types';
-
-// Reproduces the real crash condition: a host telemetry SDK that has NO logEvent
-// (portal/editor) — set BEFORE interacting. Then answer a reorder question (whose
-// drag/tap/nudge fire onOptionSelected → telemetry) and assert nothing throws.
-const metadata = {
- identifier: 'do_qs',
- name: 'QS',
- objectType: 'QuestionSetImage',
- children: [
- {
- identifier: 'do_sec',
- name: 'Section',
- objectType: 'QuestionSet',
- index: 1,
- children: [
- {
- identifier: 'do_reo',
- name: 'Q',
- objectType: 'Question',
- primaryCategory: 'Reorder Question',
- qType: 'REO',
- index: 1,
- maxScore: 1,
- body: 'Reorder the sentence
',
- interactions: {
- response1: {
- type: 'order',
- options: [
- { value: 'A', label: 'Book' },
- { value: 'B', label: 'is' },
- { value: 'C', label: 'on' },
- ],
- },
- },
- responseDeclaration: {
- response1: {
- cardinality: 'ordered',
- type: 'string',
- correctResponse: { value: ['A', 'B', 'C'] },
- },
- },
- },
- ],
- },
- ],
-};
-
-const cfg: PlayerConfig = { context: {}, config: { language: 'en' }, metadata, data: {} };
-
-describe('MainPlayer — reorder interaction with a logEvent-less telemetry SDK', () => {
- beforeEach(() => {
- // Host SDK exposes initialize but NOT logEvent — exactly the failing case.
- (window as any).EkTelemetry = { initialize: vi.fn() };
- initializeTelemetry({} as TelemetryContext);
- });
- afterEach(() => {
- delete (window as any).EkTelemetry;
- vi.restoreAllMocks();
- });
-
- it('answering a reorder question does NOT throw (regression: Mp.logEvent is not a function)', () => {
- render(
-
-
- ,
- );
- fireEvent.click(screen.getByRole('button', { name: /start assessment/i }));
- fireEvent.click(screen.getByRole('button', { name: /start section/i }));
-
- // The reorder question renders; tapping a bank word changes the answer, which
- // fires onOptionSelected → handleQuestionAnswer → logOptionSelected/
- // logAnswerSubmitted → raiseInteractEvent/raiseAssessEvent → the SDK path.
- // Before the fix this threw synchronously inside the click; now it must not.
- expect(() => fireEvent.click(screen.getByText('Book'))).not.toThrow();
- expect(() => fireEvent.click(screen.getByText('is'))).not.toThrow();
- });
-});
diff --git a/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.test.tsx b/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.test.tsx
deleted file mode 100644
index b0bfd09c..00000000
--- a/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.test.tsx
+++ /dev/null
@@ -1,176 +0,0 @@
-import { describe, it, expect, vi } from 'vitest';
-import { render, screen, fireEvent, within, act } from '@testing-library/react';
-import { QumlProvider } from '../../context/QumlContext';
-import { MainPlayer } from './MainPlayer';
-import type { PlayerConfig } from '../../types';
-
-// Raw-ish embedded config (MainPlayer normalizes via the transformation service).
-const cfg: PlayerConfig = {
- context: {},
- config: { language: 'en', showFeedback: true },
- data: {
- // Timer is opt-in (Angular parity): content must set showTimer for it to show.
- showTimer: true,
- sections: [
- {
- identifier: 's1',
- name: 'Section 1',
- timeLimits: { questionSet: { max: 0, min: 0 } },
- children: [
- {
- identifier: 'q1',
- body: 'Q1
',
- primaryCategory: 'Multiple Choice Question',
- interactions: { response1: { options: [{ value: 0, label: 'Apple' }, { value: 1, label: 'Banana' }] } },
- responseDeclaration: {
- response1: { cardinality: 'single', type: 'integer', correctResponse: { value: 0 } },
- },
- },
- ],
- },
- ],
- },
-};
-
-const renderPlayer = () =>
- render(
-
-
- ,
- );
-
-/** Advance the Phase 6 flow: overview → sectionIntro → assessment. */
-const enterAssessment = () => {
- fireEvent.click(screen.getByRole('button', { name: /start assessment/i }));
- fireEvent.click(screen.getByRole('button', { name: /start section/i }));
-};
-
-describe('MainPlayer', () => {
- it('shows the Assessment Overview first with a Start CTA', () => {
- renderPlayer();
- expect(screen.queryByText(/loading/i)).not.toBeInTheDocument();
- expect(screen.getByRole('button', { name: /start assessment/i })).toBeInTheDocument();
- // Question chrome is not rendered until the assessment stage.
- expect(screen.queryByText('Apple')).not.toBeInTheDocument();
- });
-
- it('renders the section intro then the first question after Start/Begin', () => {
- renderPlayer();
- enterAssessment();
- expect(screen.getByText('Apple')).toBeInTheDocument();
- expect(screen.getByText(/Question 1 of 1/i)).toBeInTheDocument();
- });
-
- it('does not flash feedback on selection; proceeds (non-blocking) on Submit', () => {
- vi.useFakeTimers();
- try {
- renderPlayer();
- enterAssessment();
- // Selecting an option must NOT flash feedback mid-answer.
- fireEvent.click(screen.getAllByRole('radio')[1]); // wrong option (value 1)
- expect(screen.queryByRole('status')).not.toBeInTheDocument();
- // Section Submit shows feedback briefly, then proceeds even on a wrong
- // answer (non-blocking) → the end-of-assessment confirm dialog opens.
- const submits = screen.getAllByRole('button', { name: /^submit$/i });
- fireEvent.click(submits[submits.length - 1]); // section-level submit
- act(() => vi.advanceTimersByTime(1000));
- expect(screen.getByRole('dialog')).toBeInTheDocument();
- } finally {
- vi.useRealTimers();
- }
- });
-
- it('opens the submit dialog, then shows results on confirm', () => {
- renderPlayer();
- enterAssessment();
- fireEvent.click(screen.getAllByRole('radio')[0]); // answer correctly
- // Header "Submit" opens the confirmation dialog (Phase 7).
- fireEvent.click(screen.getAllByRole('button', { name: /^submit$/i })[0]);
- const dialog = screen.getByRole('dialog');
- expect(dialog).toBeInTheDocument();
- // Confirm inside the dialog → Results screen with the reused Scoreboard.
- fireEvent.click(within(dialog).getByRole('button', { name: /^submit$/i }));
- expect(screen.getByRole('region', { name: /quiz summary/i })).toBeInTheDocument();
- expect(screen.getByRole('heading', { name: /your results/i })).toBeInTheDocument();
- });
-
- it('returns to overview on retake', () => {
- renderPlayer();
- enterAssessment();
- fireEvent.click(screen.getAllByRole('button', { name: /^submit$/i })[0]);
- const dialog = screen.getByRole('dialog');
- fireEvent.click(within(dialog).getByRole('button', { name: /^submit$/i }));
- fireEvent.click(screen.getByRole('button', { name: /retake/i }));
- expect(screen.getByRole('button', { name: /start assessment/i })).toBeInTheDocument();
- });
-
- it('count-up timer runs from Start (including section intros) when there is no limit', () => {
- vi.useFakeTimers();
- try {
- renderPlayer(); // cfg has timeLimits max 0 → count-up mode
- fireEvent.click(screen.getByRole('button', { name: /start assessment/i }));
- // The clock runs through the section intro (switching sections doesn't pause it).
- act(() => vi.advanceTimersByTime(3000));
- expect(screen.getByRole('timer')).toHaveTextContent('0:03');
- // …and keeps ticking inside the assessment.
- fireEvent.click(screen.getByRole('button', { name: /start section/i }));
- act(() => vi.advanceTimersByTime(2000));
- expect(screen.getByRole('timer')).toHaveTextContent('0:05');
- } finally {
- vi.useRealTimers();
- }
- });
-
- it('countdown runs from Start (including section intros)', () => {
- vi.useFakeTimers();
- try {
- // 5:00 assessment limit (read from data.timeLimits.questionSet.max).
- const timedCfg = {
- ...cfg,
- data: { ...(cfg.data as object), timeLimits: { questionSet: { max: 300, min: 0 } } },
- } as PlayerConfig;
- render(
-
-
- ,
- );
- fireEvent.click(screen.getByRole('button', { name: /start assessment/i }));
- // The countdown ticks during the section intro too.
- act(() => vi.advanceTimersByTime(3000));
- expect(screen.getByText('4:57')).toBeInTheDocument();
- fireEvent.click(screen.getByRole('button', { name: /start section/i }));
- act(() => vi.advanceTimersByTime(2000));
- expect(screen.getByText('4:55')).toBeInTheDocument();
- } finally {
- vi.useRealTimers();
- }
- });
-
- // Both the omitted case and an explicit `showTimer: false` must suppress the
- // timer (Angular parity: header *ngIf="showTimer"), even with a time limit.
- it.each([
- ['omitted', (() => { const { showTimer: _o, ...rest } = cfg.data as Record; return rest; })()],
- ['explicit false', { ...(cfg.data as Record), showTimer: false }],
- ])('shows NO timer when showTimer is %s, even with a time limit', (_label, data) => {
- vi.useFakeTimers();
- try {
- const noTimerCfg = {
- ...cfg,
- data: { ...data, timeLimits: { questionSet: { max: 300, min: 0 } } },
- } as PlayerConfig;
- render(
-
-
- ,
- );
- fireEvent.click(screen.getByRole('button', { name: /start assessment/i }));
- act(() => vi.advanceTimersByTime(3000));
- expect(screen.queryByRole('timer')).not.toBeInTheDocument();
- fireEvent.click(screen.getByRole('button', { name: /start section/i }));
- act(() => vi.advanceTimersByTime(2000));
- expect(screen.queryByRole('timer')).not.toBeInTheDocument();
- } finally {
- vi.useRealTimers();
- }
- });
-});
diff --git a/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.timer-showtimer-parity.test.tsx b/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.timer-showtimer-parity.test.tsx
deleted file mode 100644
index 982b7877..00000000
--- a/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.timer-showtimer-parity.test.tsx
+++ /dev/null
@@ -1,87 +0,0 @@
-import { describe, it, expect, vi } from 'vitest';
-import { render, screen, fireEvent, act, within } from '@testing-library/react';
-import { QumlProvider } from '../../context/QumlContext';
-import { MainPlayer } from './MainPlayer';
-import type { PlayerConfig } from '../../types';
-
-// Angular parity (section-player.component.ts:232-235, main-player.component.ts
-// :172,257,488-493) — `showTimer` only gates the LIVE widget's visibility; it
-// has no bearing on whether the clock is tracked, whether a time limit is
-// enforced, or whether the results screen can report duration. These configs
-// all set `showTimer: false` (or omit it) while still exercising the clock.
-
-const mcq = (id: string) => ({
- identifier: id,
- body: `${id}
`,
- primaryCategory: 'Multiple Choice Question',
- interactions: { response1: { options: [{ value: 0, label: 'Apple' }, { value: 1, label: 'Banana' }] } },
- responseDeclaration: {
- response1: { cardinality: 'single', type: 'integer', correctResponse: { value: 0 } },
- },
-});
-
-const enterAssessment = () => {
- fireEvent.click(screen.getByRole('button', { name: /start assessment/i }));
- fireEvent.click(screen.getByRole('button', { name: /start section/i }));
-};
-
-describe('MainPlayer — showTimer/summaryType parity (Angular)', () => {
- it('auto-submits at time-limit expiry even when showTimer is false (hidden limit is still enforced)', () => {
- const cfg: PlayerConfig = {
- context: {},
- config: { language: 'en' },
- data: {
- showTimer: false,
- timeLimits: { questionSet: { max: 2, min: 0 } },
- sections: [{ identifier: 's1', name: 'Section 1', children: [mcq('q1')] }],
- },
- };
- vi.useFakeTimers();
- try {
- render(
-
-
- ,
- );
- enterAssessment();
- expect(screen.getByText('Apple')).toBeInTheDocument();
- // No visible countdown — showTimer is false.
- expect(screen.queryByRole('timer')).not.toBeInTheDocument();
- // Past the 2s limit → auto-submit, no confirmation needed.
- act(() => vi.advanceTimersByTime(2100));
- expect(screen.getByRole('heading', { name: /your results/i })).toBeInTheDocument();
- } finally {
- vi.useRealTimers();
- }
- });
-
- it('reports duration on Results when showTimer is false and summaryType allows it', () => {
- const cfg: PlayerConfig = {
- context: {},
- config: { language: 'en' },
- data: {
- showTimer: false,
- summaryType: 'Score and Duration',
- sections: [{ identifier: 's1', name: 'Section 1', children: [mcq('q1')] }],
- },
- };
- vi.useFakeTimers();
- try {
- render(
-
-
- ,
- );
- enterAssessment();
- act(() => vi.advanceTimersByTime(3000)); // 3s elapsed, count-up mode (no time limit)
- fireEvent.click(screen.getAllByRole('radio')[0]);
- fireEvent.click(screen.getAllByRole('button', { name: /^submit$/i })[0]);
- const dialog = screen.getByRole('dialog');
- fireEvent.click(within(dialog).getByRole('button', { name: /^submit$/i }));
- expect(screen.getByRole('heading', { name: /your results/i })).toBeInTheDocument();
- expect(screen.getByText(/time taken/i)).toBeInTheDocument();
- } finally {
- vi.useRealTimers();
- }
- });
-});
diff --git a/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.tsx b/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.tsx
deleted file mode 100644
index cfa695ec..00000000
--- a/projects/sunbird-quml-player-react/src/components/MainPlayer/MainPlayer.tsx
+++ /dev/null
@@ -1,668 +0,0 @@
-import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
-import type { ReactNode } from 'react';
-import { DndProvider } from 'react-dnd';
-import { HTML5Backend } from 'react-dnd-html5-backend';
-import { useQuml } from '../../context/useQuml';
-import { SectionPlayer } from '../SectionPlayer/SectionPlayer';
-import { StartPage } from '../StartPage/StartPage';
-import { SectionIntro } from '../SectionIntro/SectionIntro';
-import { Sidebar } from '../Sidebar/Sidebar';
-import { MobileSectionsDrawer } from '../MobileSectionsDrawer/MobileSectionsDrawer';
-import { PlayerHeader } from '../PlayerHeader/PlayerHeader';
-import { SubmitModal } from '../SubmitModal/SubmitModal';
-import { ResultsScreen } from '../ResultsScreen/ResultsScreen';
-import { ReviewScreen } from '../ReviewScreen/ReviewScreen';
-import { t, readI18n } from '../../i18n/translations';
-import { transformSection, transformQuestion } from '../../services/transformation-service';
-import {
- loadQuestionSet,
- hasEmbeddedQuestions,
- transformEmbeddedQuestionSet,
-} from '../../services/data-service';
-import { QumlApiError } from '../../types/api';
-import { calculateScore } from '../../registry/scoring-registry';
-import { isAnswered } from '../../utils/answered';
-import type { Question, Section, PlayerConfig, I18nValue } from '../../types';
-import styles from './MainPlayer.module.scss';
-
-/**
- * MainPlayer — top-level orchestrator + assessment shell (Phase 5 engine +
- * Phase 6 experience).
- *
- * Owns the player FLOW state machine (local React state — NOT Context, per spec
- * §6.0): overview → sectionIntro → assessment → submit. Context stays the single
- * source of truth for runtime data (sections, indices, answers). Shell components
- * are children here; they receive Context-derived data as props and emit jump
- * intent that maps to setCurrentSection / setCurrentQuestion. Hosts the single
- * application-level DndProvider.
- *
- * Phase 7 extends the flow with `results`/`review` stages and a transient
- * `submitDialog`; Results/Review READ Context + the scoring-registry and never
- * own runtime answers.
- */
-interface MainPlayerProps {
- playerConfig: PlayerConfig;
- onPlayerEvent?: (event: unknown) => void;
- /** Reserved — telemetry flows through useTelemetry; wired to the SDK in a later phase. */
- onTelemetryEvent?: (event: unknown) => void;
-}
-
-type Stage = 'overview' | 'sectionIntro' | 'assessment' | 'results' | 'review';
-
-export function MainPlayer({ playerConfig, onPlayerEvent }: MainPlayerProps) {
- const {
- state,
- setPlayerConfig,
- setSections,
- setCurrentSection,
- setCurrentQuestion,
- setLoading,
- setError,
- clearError,
- resetState,
- setAttempt,
- } = useQuml();
- const language = state.language;
-
- // Assessment-level metadata source for the overview. Embedded: playerConfig.data.
- // Fetched: the raw questionset root returned by the data service.
- const [metadata, setMetadata] = useState>({});
-
- const [stage, setStage] = useState('overview');
- const [drawerOpen, setDrawerOpen] = useState(false);
- // Transient submit-confirmation dialog (spec §7.0); overlays the assessment shell.
- const [submitDialog, setSubmitDialog] = useState(false);
- // Where Review opens to (set when entering review from results).
- const [reviewStartIndex, setReviewStartIndex] = useState(0);
- // Assessment-level countdown (owned by the shell, not Context). Null = no limit.
- const [timeRemaining, setTimeRemaining] = useState(null);
- // One-shot guard for the showStartPage:'No' auto-advance past the overview.
- const autoStartedRef = useRef(false);
- // True once the assessment has been entered at least once this attempt — the
- // brand-click (onBrandClick) returns to Overview WITHOUT resetting progress
- // or the clock, so the CTA there must read "Resume", not "Start" (Retake is
- // the only path that clears this, since it's the only path that actually
- // restarts from zero).
- const [hasStarted, setHasStarted] = useState(false);
-
- // Section intros can be disabled via config (spec §6.0).
- const sectionIntrosEnabled =
- (playerConfig?.config as { showSectionIntro?: boolean } | undefined)?.showSectionIntro !== false;
-
- // Preview parity (Angular): the host can ask the player to skip the overview /
- // start page and the submit-confirmation step. These arrive on the questionset
- // metadata as 'Yes'/'No' strings. Absent → the full behaviour (show overview,
- // confirm on submit), so existing content is unaffected.
- // showStartPage:'No' → land straight in the assessment (see auto-start effect)
- // requiresSubmit:'No' → Submit goes straight to results, no confirmation modal
- const skipStartPage = metadata.showStartPage === 'No' || metadata.showStartPage === false;
- const requiresSubmitConfirmation =
- metadata.requiresSubmit !== 'No' && metadata.requiresSubmit !== false;
-
- // Angular parity (main-player.component.ts:249) — host/backend data under
- // `playerConfig.metadata`, not the player's own `config` (UI-only settings).
- // Read once here since it's needed beyond the overview (Retake gating below
- // + the exdata event effect further down).
- const maxAttempts =
- (playerConfig?.metadata as { maxAttempts?: number } | undefined)?.maxAttempts ?? null;
- // Angular parity (main-player.component.ts:253 `showReplay`) — once this
- // attempt IS the last allowed one, Retake must not offer another.
- const canRetake = maxAttempts == null || state.attemptNumber < maxAttempts;
-
- // Initialize config + normalized sections.
- //
- // Two data sources, decided by shape (never both):
- // - EMBEDDED: playerConfig.data.sections is present → normalize inline (sync).
- // - FETCHED: no embedded sections but an identifier → the data service
- // fetches the hierarchy + questions and returns normalized sections.
- //
- // Extracted so Retake (spec §7.5) can re-initialize after resetState() — which
- // returns initialState and therefore clears playerConfig/sections.
- const initializeFromConfig = useCallback(async () => {
- if (!playerConfig) return;
- setPlayerConfig(playerConfig);
-
- // Angular parity (main-player.component.ts:250) — the host tracks attempts
- // used across PAST sessions and passes the count back; this session's
- // attempt number is one past that. Retake's own `setAttempt(nextAttempt)`
- // (called right after this function) overrides this for the in-session
- // case, so this only matters on a fresh mount.
- const seedAttempt = (playerConfig.metadata as { currentAttempt?: number } | undefined)
- ?.currentAttempt;
- if (typeof seedAttempt === 'number') {
- setAttempt(seedAttempt + 1);
- }
-
- const data = (playerConfig.data as Record | undefined) ?? {};
- // Host-contract compatibility: the Sunbird editor/portal follow the Angular
- // contract — they pass the questionset under `playerConfig.metadata` and leave
- // `data` empty. Fall back to metadata so both config shapes load.
- const meta = (playerConfig.metadata as Record | undefined) ?? {};
- // Guard with Array.isArray: a non-array `sections` (e.g. a string) would have
- // a truthy `.length` and crash on `.map` in the embedded path below.
- const sectionsCandidate = data.sections ?? meta.sections;
- const rawSections = Array.isArray(sectionsCandidate) ? (sectionsCandidate as unknown[]) : [];
-
- // EMBEDDED path (unchanged behavior).
- if (rawSections.length > 0) {
- const sections = rawSections
- .map((raw) => {
- const normalized = transformSection(raw);
- if (!normalized) return null;
- const children = (((raw as { children?: unknown[] }).children ?? []) as unknown[])
- .map((q) => transformQuestion(q))
- .filter((q): q is Question => Boolean(q));
- return { ...normalized, children };
- })
- .filter((s): s is Section => Boolean(s));
- // Overview metadata comes from whichever source carried the sections.
- setMetadata(data.sections ? data : meta);
- setSections(sections);
- return;
- }
-
- // EMBEDDED-METADATA path: hosts (Sunbird editor/portal) pass the WHOLE
- // questionset — with question content embedded in its hierarchy — as
- // `metadata`. Render it directly, no network calls. This also avoids relying
- // on the player's own API endpoints matching the host's proxy routing.
- if (hasEmbeddedQuestions(meta)) {
- const sections = transformEmbeddedQuestionSet(meta);
- if (sections.length > 0) {
- setMetadata(meta);
- setSections(sections);
- return;
- }
- }
-
- // FETCHED path — delegate ALL network + normalization to the data service.
- // Require a real string id: a non-string (e.g. an object) would otherwise
- // build a bad request URL like `.../[object Object]`.
- const identifierCandidate = data.identifier ?? meta.identifier;
- const identifier = typeof identifierCandidate === 'string' ? identifierCandidate : undefined;
- if (!identifier) return;
- // API base URL only — the content/asset base (config.baseUrl) is separate and
- // used for image resolution, so it must NOT leak into API requests.
- const baseUrl = (playerConfig.context?.host as string | undefined) ?? '';
- // API path prefix (host slug, e.g. the portal's `/portal`). This is the React
- // stand-in for Angular's host-provided QuestionCursor choosing the URL. The
- // portal passes it as `config.apiSlug` (its existing convention — see
- // QumlEditorService `apiSlug: '/portal'`); `slug` is accepted as an alias.
- // data-service falls back to `/api` when neither is supplied.
- const cfg = playerConfig.config ?? {};
- const pathPrefix =
- (typeof cfg.apiSlug === 'string' ? cfg.apiSlug : undefined) ??
- (typeof cfg.slug === 'string' ? cfg.slug : undefined);
-
- setLoading(true);
- try {
- const { metadata: qsMetadata, sections } = await loadQuestionSet(identifier, {
- baseUrl,
- language: playerConfig.config?.language,
- pathPrefix,
- });
- setMetadata(qsMetadata as Record);
- setSections(sections);
- setLoading(false);
- } catch (err) {
- const message =
- err instanceof QumlApiError ? err.message : 'Failed to load the assessment.';
- setError(message);
- }
- }, [playerConfig, setPlayerConfig, setSections, setLoading, setError, setAttempt]);
-
- useEffect(() => {
- initializeFromConfig();
- }, [initializeFromConfig]);
-
- const summary = useMemo(() => {
- let correct = 0;
- let incorrect = 0;
- let partial = 0;
- let skipped = 0;
- let totalScore = 0;
- let maxScore = 0;
- for (const section of state.sections) {
- for (const q of section.children) {
- const max = q.maxScore ?? 1;
- maxScore += max;
- const answer = state.answers[q.identifier];
- if (!isAnswered(answer)) {
- skipped += 1;
- continue;
- }
- const score = calculateScore(q, answer, language);
- totalScore += score * max;
- if (score >= 1) correct += 1;
- else if (score > 0) partial += 1;
- else incorrect += 1;
- }
- }
- return { correct, incorrect, partial, skipped, totalScore: Math.round(totalScore), maxScore };
- }, [state.sections, state.answers, language]);
-
- // Overview / details data, derived from Context + raw config (spec §6.1–§6.2).
- const overview = useMemo(() => {
- const data = metadata;
- const totalQuestions = state.sections.reduce((n, s) => n + s.children.length, 0);
- const maxScore = state.sections.reduce(
- (n, s) => n + s.children.reduce((m, q) => m + (q.maxScore ?? 1), 0),
- 0,
- );
- const timeLimits = (data.timeLimits as { questionSet?: { max?: number } } | undefined)
- ?.questionSet;
- return {
- title: readI18n(data.name as I18nValue | undefined, language) || t(language, 'ASSESSMENT_OVERVIEW'),
- description: readI18n(data.description as I18nValue | undefined, language) || undefined,
- instructions: data.instructions as string | undefined,
- totalQuestions,
- totalSections: state.sections.length,
- timeLimit: Number(timeLimits?.max) || 0,
- // Angular parity (main-player.component.ts:172 → header *ngIf="showTimer"):
- // the timer is shown ONLY when the content opts in via `showTimer`. Absent /
- // false → no timer at all; the count-up fallback also requires it.
- showTimer: data.showTimer === true || data.showTimer === 'true',
- // Angular parity (main-player.component.ts:488-524) — gates score/duration
- // visibility on the results screen. 'Complete'→score as a fraction,
- // 'Duration'→score hidden, 'Score'→duration hidden, 'Score and Duration'/
- // absent→both shown as plain values.
- summaryType: data.summaryType as string | undefined,
- maxScore,
- // Absent (not sent by the backend) → unlimited attempts: null, distinct
- // from an explicit 0/low maxAttempts, so StartPage can show "No Limit"
- // instead of a fabricated default.
- attemptsLeft:
- maxAttempts == null ? null : Math.max(0, maxAttempts - (state.attemptNumber - 1)),
- };
- }, [metadata, maxAttempts, state.sections, state.attemptNumber, language]);
-
- // Angular parity (main-player.component.ts:258,276-282,415-417 emitMaxAttemptEvents
- // + replayContent) — tell the host when the CURRENT attempt is the last one
- // allowed, or already past the limit (the host decides how to react, e.g. its
- // own "no attempts left" messaging). Keyed on attemptNumber, so this covers
- // BOTH Angular call sites (component init AND Retake) in one place — Retake
- // changes attemptNumber, which re-fires this effect with the new value.
- useEffect(() => {
- if (maxAttempts == null) return;
- const current = state.attemptNumber;
- if (current < maxAttempts) return;
- onPlayerEvent?.({
- eid: 'exdata',
- edata: {
- type: 'exdata',
- currentattempt: current,
- isLastAttempt: current === maxAttempts,
- maxLimitExceeded: current > maxAttempts,
- },
- });
- // onPlayerEvent identity isn't guaranteed stable across host re-renders;
- // only the attempt boundary itself should re-trigger this.
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [state.attemptNumber, maxAttempts]);
-
- // Stages where the exam clock runs: once started, it keeps ticking through
- // section intros (switching sections doesn't stop the clock). It PAUSES on
- // Start/Overview, Results and Review.
- const isClockRunning = stage === 'assessment' || stage === 'sectionIntro';
-
- // Shell countdown. Remaining time is derived from a fixed deadline timestamp
- // rather than by decrementing per tick, so re-creating the interval at a
- // stage boundary can't accumulate drift.
- const deadlineRef = useRef(null);
- useEffect(() => {
- if (!isClockRunning || timeRemaining == null) {
- deadlineRef.current = null;
- return;
- }
- // Anchor the deadline from whatever time was left when the assessment
- // (re)started; a paused-then-resumed clock continues from the frozen value.
- deadlineRef.current = Date.now() + timeRemaining * 1000;
- const id = setInterval(() => {
- const remaining = Math.max(0, Math.ceil((deadlineRef.current! - Date.now()) / 1000));
- setTimeRemaining(remaining);
- if (remaining <= 0) clearInterval(id);
- }, 250);
- return () => clearInterval(id);
- // Re-anchor only when the clock starts/stops, NOT every tick.
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [isClockRunning]);
-
- // Count-up elapsed timer (Angular header showCountUp parity): when the
- // assessment has NO time limit, this tracks time spent instead of a
- // countdown. Same run/pause semantics as the countdown, anchored to a
- // timestamp so it never drifts.
- //
- // Angular parity — NOT gated on `showTimer`: showTimer only controls whether
- // the live widget is *visible* (main-player.component.ts:172, section-player
- // .component.ts:58,235 — fed straight into the timer display component,
- // nothing else). Duration tracking itself (main-player.component.ts:257
- // initialTime, :488-493 setDurationSpent) and time-limit enforcement
- // (section-player.component.ts:232-233) both run unconditionally in
- // Angular. Previously this effect also required `overview.showTimer`, so a
- // hidden timer (showTimer:false/unset) meant elapsed time was never tracked
- // at all — the results screen had nothing to show regardless of
- // `summaryType`. The header's OWN display of this value is still gated on
- // `showTimer` separately, further down — only the tracking moved.
- const [timeElapsed, setTimeElapsed] = useState(0);
- const elapsedAnchorRef = useRef(null);
- useEffect(() => {
- if (!isClockRunning || overview.timeLimit > 0) return;
- elapsedAnchorRef.current = Date.now() - timeElapsed * 1000;
- const id = setInterval(() => {
- setTimeElapsed(Math.floor((Date.now() - elapsedAnchorRef.current!) / 1000));
- }, 250);
- return () => clearInterval(id);
- // Re-anchor only when the clock starts/stops; timeElapsed is read once as
- // the resume point.
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [isClockRunning, overview.timeLimit]);
-
- // Time up → auto-submit straight to results (no confirmation dialog).
- useEffect(() => {
- if (timeRemaining === 0) {
- setSubmitDialog(false);
- setStage('results');
- }
- }, [timeRemaining]);
-
- // Flattened question list across all sections, for review + counts.
- const allQuestions = useMemo(
- () => state.sections.flatMap((s) => s.children),
- [state.sections],
- );
-
- // Per-section completion (every child answered) — drives the section step dots.
- const completed = useMemo(
- () =>
- state.sections.map((s) =>
- s.children.length > 0 && s.children.every((q) => isAnswered(state.answers[q.identifier])),
- ),
- [state.sections, state.answers],
- );
-
- // ── Flow transitions ───────────────────────────────────────────────────────
- const beginAssessmentTimer = () => {
- // Angular parity — NOT gated on `showTimer` (see the count-up effect's
- // comment above for the citations): a real `timeLimit` always counts down
- // and enforces auto-submit-at-zero, whether or not the content shows the
- // live widget. `showTimer` only gates the header's own display, below.
- if (timeRemaining == null && overview.timeLimit > 0) {
- setTimeRemaining(overview.timeLimit);
- }
- };
-
- const handleStart = () => {
- setCurrentSection(0);
- setCurrentQuestion(0);
- beginAssessmentTimer();
- setHasStarted(true);
- setStage(sectionIntrosEnabled ? 'sectionIntro' : 'assessment');
- };
-
- const handleBegin = () => {
- setCurrentQuestion(0);
- setStage('assessment');
- };
-
- // Overview section card → jump straight into that section's intro.
- const handleSectionSelectFromOverview = (index: number) => {
- setCurrentSection(index);
- setCurrentQuestion(0);
- beginAssessmentTimer();
- setHasStarted(true);
- setStage(sectionIntrosEnabled ? 'sectionIntro' : 'assessment');
- };
-
- // Submit (header) → open the confirmation dialog (spec §7.1), unless the host
- // opted out via requiresSubmit:'No' (then submit straight to results).
- const handleSubmitAssessment = () => {
- if (requiresSubmitConfirmation) setSubmitDialog(true);
- else handleConfirmSubmit();
- };
-
- const handleConfirmSubmit = () => {
- setSubmitDialog(false);
- setStage('results');
- onPlayerEvent?.({ type: 'quizEnd', summary });
- // Angular parity (main-player.component.ts:483-485 raiseEndEvent) — flag
- // to the host that this attempt, now finished, was the last one allowed.
- if (maxAttempts != null && state.attemptNumber >= maxAttempts) {
- onPlayerEvent?.({
- eid: 'exdata',
- edata: {
- type: 'exdata',
- currentattempt: state.attemptNumber,
- isLastAttempt: false,
- maxLimitExceeded: true,
- },
- });
- }
- };
-
- const handleCancelSubmit = () => setSubmitDialog(false);
-
- const handleReviewAll = () => {
- setReviewStartIndex(0);
- setStage('review');
- };
-
- // Retake (spec §7.5): clear answers via resetState(), re-initialize from the
- // config prop (resetState wipes config/sections), bump the attempt, return to
- // Overview, and reset the shell timer.
- const handleRetake = () => {
- const nextAttempt = state.attemptNumber + 1;
- resetState();
- initializeFromConfig();
- setAttempt(nextAttempt);
- setTimeRemaining(null);
- setTimeElapsed(0);
- setSubmitDialog(false);
- setHasStarted(false);
- setStage('overview');
- };
-
- const handleSectionEnd = () => {
- const nextIndex = state.currentSectionIndex + 1;
- if (nextIndex < state.sections.length) {
- setCurrentSection(nextIndex);
- setCurrentQuestion(0);
- setStage(sectionIntrosEnabled ? 'sectionIntro' : 'assessment');
- onPlayerEvent?.({ type: 'sectionEnd', sectionIndex: state.currentSectionIndex });
- } else if (requiresSubmitConfirmation) {
- // End of the last section → confirm before submitting.
- setSubmitDialog(true);
- } else {
- handleConfirmSubmit();
- }
- };
-
- const handleSectionJump = (index: number) => {
- setCurrentSection(index);
- setCurrentQuestion(0);
- setStage('assessment');
- };
-
- // showStartPage:'No' → auto-advance past the overview once sections are ready.
- // Angular parity (section-player.component.ts:195,248): with showStartPage:'No'
- // the player renders the FIRST QUESTION directly — no overview AND no section
- // intro (the intro screen is a React-only addition). So land on 'assessment',
- // not 'sectionIntro'. Later section-to-section intros are unaffected.
- // One-shot (ref-guarded) so an explicit later return to overview (retake /
- // brand click) is still respected.
- useEffect(() => {
- if (autoStartedRef.current || !skipStartPage) return;
- if (stage !== 'overview' || state.sections.length === 0) return;
- autoStartedRef.current = true;
- setCurrentSection(0);
- setCurrentQuestion(0);
- beginAssessmentTimer();
- setHasStarted(true);
- setStage('assessment');
- // Guarded by the ref; the setters/timer are stable enough here.
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [skipStartPage, stage, state.sections.length]);
-
- if (!state.playerConfig || state.loading) {
- return {t(language, 'LOADING')}
;
- }
- if (state.error) {
- // Retry: clear the error and re-run the fetch/normalize pipeline.
- const handleRetry = () => {
- clearError();
- initializeFromConfig();
- };
- return (
-
-
{state.error}
-
-
- );
- }
-
- const currentSection = state.sections[state.currentSectionIndex];
-
- // Global question counter (across all sections) for the shell header.
- const priorQuestions = state.sections
- .slice(0, state.currentSectionIndex)
- .reduce((n, s) => n + s.children.length, 0);
- const globalQuestionNumber = priorQuestions + state.currentQuestionIndex + 1;
-
- let content: ReactNode;
- if (stage === 'overview' && skipStartPage && !autoStartedRef.current) {
- // Initial auto-start still pending (effect above) — don't flash the overview
- // we're skipping. Gated on the ref so that an EXPLICIT later return to
- // overview (Retake / brand click) shows the real overview instead of a
- // permanent loading screen (the one-shot effect won't re-fire).
- content = {t(language, 'LOADING')}
;
- } else if (stage === 'overview') {
- content = (
-
- );
- } else if (stage === 'results') {
- // Total time spent: countdown mode → limit minus what was left; count-up
- // mode → the elapsed counter (both tick unconditionally once the
- // assessment stage starts — Angular parity, see the count-up effect's
- // comment above: NOT gated on `showTimer`, which only controls the live
- // widget's visibility, not whether time is tracked). `summaryType:'Score'`
- // hides duration on-screen — that gating lives in ResultsScreen, not here.
- const timeTaken =
- overview.timeLimit > 0 ? overview.timeLimit - (timeRemaining ?? overview.timeLimit) : timeElapsed;
- content = (
-
- );
- } else if (stage === 'review') {
- content = (
- setStage('results')}
- language={language}
- />
- );
- } else {
- // Persistent shell (spec §6.6/§6.12): header + sidebar wrap BOTH the section
- // intro and the in-section player; only the main area swaps between them.
- const mainArea =
- stage === 'sectionIntro' && currentSection ? (
- setStage('overview')}
- language={language}
- />
- ) : (
-
- );
-
- // The header timer is gated by the content's `showTimer` flag (Angular parity).
- // When enabled: countdown if a time limit exists, count-up elapsed otherwise.
- // When disabled: both props are null, so PlayerHeader renders no timer at all.
- content = (
- <>
- setDrawerOpen(true)}
- onBrandClick={() => setStage('overview')}
- language={language}
- />
-
-
-
-
-
{mainArea}
-
-
setDrawerOpen(false)}
- sections={state.sections}
- currentSectionIndex={state.currentSectionIndex}
- answers={state.answers}
- onSectionJump={handleSectionJump}
- language={language}
- />
-
-
- {submitDialog && (
-
- )}
- >
- );
- }
-
- return (
-
- {content}
-
- );
-}
diff --git a/projects/sunbird-quml-player-react/src/components/MobileSectionsDrawer/MobileSectionsDrawer.module.scss b/projects/sunbird-quml-player-react/src/components/MobileSectionsDrawer/MobileSectionsDrawer.module.scss
deleted file mode 100644
index e2b08f70..00000000
--- a/projects/sunbird-quml-player-react/src/components/MobileSectionsDrawer/MobileSectionsDrawer.module.scss
+++ /dev/null
@@ -1,93 +0,0 @@
-@use '../../styles/variables' as v;
-@use '../../styles/mixins' as m;
-
-// Mobile sections navigator — bottom sheet (matches the design's `sheetUp`).
-// `absolute` (anchored to MainPlayer's .appShell), not `fixed`, so the sheet
-// stays within the player box when embedded in a small frame (editor preview).
-// When the player fills the viewport (.appShell == viewport) it is identical to
-// fixed.
-.overlay {
- position: absolute;
- inset: 0;
- z-index: 1000;
- display: flex;
- align-items: flex-end; // dock the sheet to the bottom edge
- background: rgba(0, 0, 0, 0.4);
-}
-
-.panel {
- display: flex;
- flex-direction: column;
- width: 100%;
- // `%` (not `vh`) so the sheet height tracks the player box, not the browser
- // viewport: in a short embedded frame it can't grow taller than .appShell.
- // The overlay is absolute inset:0 (== .appShell height), so 80% == 80% of the
- // player; identical to `80vh` when the player fills the viewport.
- max-height: 80%;
- overflow-y: auto;
- -webkit-overflow-scrolling: touch;
- background: v.$ivory;
- border-top-left-radius: v.$r-lg;
- border-top-right-radius: v.$r-lg;
- box-shadow: v.$shadow-lg;
- animation: sheet-up v.$dur-base v.$ease-out;
-}
-
-// Grab handle affordance (typical of bottom sheets).
-.panel::before {
- content: '';
- align-self: center;
- width: 2.25rem;
- height: 0.25rem;
- margin: v.$space-3 0 0;
- border-radius: v.$r-pill;
- background: v.$gray-300;
- flex-shrink: 0;
-}
-
-@keyframes sheet-up {
- from {
- transform: translateY(100%);
- }
- to {
- transform: translateY(0);
- }
-}
-
-.panelHeader {
- position: sticky;
- top: 0;
- z-index: 1;
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: v.$space-4 v.$space-5;
- background: v.$ivory;
- border-bottom: 1px solid v.$gray-200;
-}
-
-.panelTitle {
- font-family: v.$ff-base;
- font-size: v.$text-md;
- font-weight: v.$fw-semibold;
- color: v.$dark;
-}
-
-.closeBtn {
- @include m.focus-ring;
-
- display: inline-flex;
- align-items: center;
- justify-content: center;
- padding: v.$space-1;
- border: none;
- border-radius: v.$r-sm;
- background: transparent;
- color: v.$g600;
- cursor: pointer;
-
- &:hover {
- background: v.$g100;
- color: v.$g900;
- }
-}
diff --git a/projects/sunbird-quml-player-react/src/components/MobileSectionsDrawer/MobileSectionsDrawer.test.tsx b/projects/sunbird-quml-player-react/src/components/MobileSectionsDrawer/MobileSectionsDrawer.test.tsx
deleted file mode 100644
index 7d7525e8..00000000
--- a/projects/sunbird-quml-player-react/src/components/MobileSectionsDrawer/MobileSectionsDrawer.test.tsx
+++ /dev/null
@@ -1,62 +0,0 @@
-import { describe, it, expect, vi } from 'vitest';
-import { render, screen, fireEvent } from '@testing-library/react';
-import { MobileSectionsDrawer } from './MobileSectionsDrawer';
-import type { Section } from '../../types';
-
-const sections: Section[] = [
- {
- identifier: 's1',
- name: 'Section One',
- children: [
- { identifier: 'q1', body: '', primaryCategory: 'multiple choice question', maxScore: 1 },
- ],
- timeLimits: { max: 0, min: 0 },
- allowSkip: true,
- shuffle: false,
- },
-];
-
-const baseProps = {
- sections,
- currentSectionIndex: 0,
- answers: {},
- onSectionJump: vi.fn(),
-};
-
-describe('MobileSectionsDrawer', () => {
- it('renders nothing when closed', () => {
- const { container } = render(
- ,
- );
- expect(container).toBeEmptyDOMElement();
- });
-
- it('renders a modal dialog when open', () => {
- render();
- const dialog = screen.getByRole('dialog');
- expect(dialog).toHaveAttribute('aria-modal', 'true');
- });
-
- it('closes on Escape', () => {
- const onClose = vi.fn();
- render();
- fireEvent.keyDown(document, { key: 'Escape' });
- expect(onClose).toHaveBeenCalled();
- });
-
- it('closes after a section jump', () => {
- const onClose = vi.fn();
- const onSectionJump = vi.fn();
- render(
- ,
- );
- fireEvent.click(screen.getByRole('button', { name: /Section One/i }));
- expect(onSectionJump).toHaveBeenCalledWith(0);
- expect(onClose).toHaveBeenCalled();
- });
-});
diff --git a/projects/sunbird-quml-player-react/src/components/MobileSectionsDrawer/MobileSectionsDrawer.tsx b/projects/sunbird-quml-player-react/src/components/MobileSectionsDrawer/MobileSectionsDrawer.tsx
deleted file mode 100644
index 93da481e..00000000
--- a/projects/sunbird-quml-player-react/src/components/MobileSectionsDrawer/MobileSectionsDrawer.tsx
+++ /dev/null
@@ -1,117 +0,0 @@
-import { useEffect, useRef } from 'react';
-import { t } from '../../i18n/translations';
-import { Sidebar } from '../Sidebar/Sidebar';
-import { CloseIcon } from '../icons';
-import type { Section, AnswersMap } from '../../types';
-import styles from './MobileSectionsDrawer.module.scss';
-
-/**
- * MobileSectionsDrawer — slide-in navigator for < 768px (spec §6.6).
- *
- * Reuses Sidebar/QuestionPalette content. Accessibility (spec §6.10):
- * focus trap while open, `Esc` closes, `aria-modal`, focus returns to the toggle.
- * Pure presentational beyond the focus-management effect; no Context mutation.
- */
-export interface MobileSectionsDrawerProps {
- isOpen: boolean;
- onClose: () => void;
- sections: Section[];
- currentSectionIndex: number;
- answers: AnswersMap;
- onSectionJump: (sectionIndex: number) => void;
- language?: string;
-}
-
-export function MobileSectionsDrawer({
- isOpen,
- onClose,
- sections,
- currentSectionIndex,
- answers,
- onSectionJump,
- language = 'en',
-}: MobileSectionsDrawerProps) {
- const panelRef = useRef(null);
- const previouslyFocused = useRef(null);
-
- // Focus management: trap focus inside the panel, restore on close.
- useEffect(() => {
- if (!isOpen) return;
-
- previouslyFocused.current = document.activeElement as HTMLElement | null;
- const panel = panelRef.current;
- const focusables = () =>
- Array.from(
- panel?.querySelectorAll(
- 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])',
- ) ?? [],
- ).filter((el) => !el.hasAttribute('disabled'));
-
- focusables()[0]?.focus();
-
- const onKeyDown = (e: KeyboardEvent) => {
- if (e.key === 'Escape') {
- e.preventDefault();
- onClose();
- return;
- }
- if (e.key !== 'Tab') return;
- const items = focusables();
- if (items.length === 0) return;
- const first = items[0];
- const last = items[items.length - 1];
- if (e.shiftKey && document.activeElement === first) {
- e.preventDefault();
- last.focus();
- } else if (!e.shiftKey && document.activeElement === last) {
- e.preventDefault();
- first.focus();
- }
- };
-
- document.addEventListener('keydown', onKeyDown);
- return () => {
- document.removeEventListener('keydown', onKeyDown);
- previouslyFocused.current?.focus?.();
- };
- }, [isOpen, onClose]);
-
- if (!isOpen) return null;
-
- return (
-
- {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}
-
e.stopPropagation()}
- >
-
- {t(language, 'NAVIGATION')}
-
-
-
-
{
- onSectionJump(i);
- onClose();
- }}
- language={language}
- />
-
-
- );
-}
diff --git a/projects/sunbird-quml-player-react/src/components/PlayerHeader/PlayerHeader.module.scss b/projects/sunbird-quml-player-react/src/components/PlayerHeader/PlayerHeader.module.scss
deleted file mode 100644
index a66f0c99..00000000
--- a/projects/sunbird-quml-player-react/src/components/PlayerHeader/PlayerHeader.module.scss
+++ /dev/null
@@ -1,320 +0,0 @@
-@use '../../styles/variables' as v;
-@use '../../styles/mixins' as m;
-
-.header {
- position: sticky;
- top: 0;
- z-index: 100;
- display: flex;
- align-items: center;
- justify-content: space-between;
- gap: v.$space-4;
- height: v.$header-h;
- padding: 0 v.$space-6;
- background: v.$white;
- border-bottom: 1px solid v.$gray-200;
-
- @include m.mobile {
- padding: 0 v.$space-4;
- }
-}
-
-.left,
-.right {
- display: flex;
- align-items: center;
- gap: v.$space-4;
- min-width: 0;
-
- @include m.mobile {
- gap: v.$space-2;
- }
-}
-
-.left {
- flex: 1 1 auto;
- // No overflow:hidden here — it was clipping the brand badge. The brand NAME
- // truncates itself (its own ellipsis) and is hidden on mobile anyway.
-}
-
-.right {
- flex-shrink: 0;
-}
-
-.menuBtn {
- @include m.focus-ring;
-
- display: none;
- flex-shrink: 0;
- align-items: center;
- justify-content: center;
- width: 2.5rem;
- height: 2.5rem;
- padding: v.$space-1;
- border: 1.5px solid v.$gray-200;
- border-radius: v.$r-sm;
- background: v.$white;
- color: v.$g700;
- cursor: pointer;
-
- &:hover {
- border-color: v.$g400;
- color: v.$g900;
- }
-
- // Visible on mobile (≤768px) where the sidebar is hidden — this is the entry
- // point to the sections/palette bottom sheet.
- @include m.mobile {
- display: inline-flex;
- }
-}
-
-// ── Brand ────────────────────────────────────────────────────────────────────
-.brand {
- @include m.focus-ring;
-
- display: inline-flex;
- align-items: center;
- gap: v.$space-3;
- min-width: 0;
- padding: v.$space-1;
- border: none;
- border-radius: v.$r-sm;
- background: transparent;
- cursor: pointer;
-
- &:hover .brandName {
- color: v.$brick;
- }
-}
-
-.brandBadge {
- flex-shrink: 0;
-}
-
-.brandBadge {
- display: flex;
- align-items: center;
- justify-content: center;
- width: 2rem;
- height: 2rem;
- border-radius: v.$r-pill;
- background: v.$brick;
- color: v.$white;
- font-size: v.$text-sm;
- font-weight: v.$fw-bold;
-}
-
-.brandName {
- min-width: 0;
- font-size: v.$text-md;
- font-weight: v.$fw-bold;
- color: v.$g900;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-
- // On mobile the header is tight (timer + counter + Submit); drop the brand
- // NAME but keep the badge as the home affordance, leaving room for the
- // sections menu button.
- @include m.mobile {
- display: none;
- }
-}
-
-// ── Section steps ────────────────────────────────────────────────────────────
-.steps {
- display: flex;
- align-items: center;
- gap: v.$space-2;
- margin: 0 0 0 v.$space-3;
- padding: 0 0 0 v.$space-4;
- border-inline-start: 1px solid v.$gray-200;
- list-style: none;
-
- // Hide the section-step rail on tablet and below — it competes for width
- // with the brand + timer/counter/submit cluster. The sidebar/drawer still
- // shows section progress.
- @include m.tablet {
- display: none;
- }
-}
-
-.step {
- display: flex;
- align-items: center;
-
- // Connector line between steps.
- &:not(:first-child)::before {
- content: '';
- width: v.$space-4;
- height: 1.5px;
- margin-inline-end: v.$space-2;
- background: v.$gray-300;
- }
-}
-
-.stepDot {
- display: flex;
- align-items: center;
- justify-content: center;
- width: 1.75rem;
- height: 1.75rem;
- border-radius: v.$r-pill;
- background: v.$g100;
- color: v.$gray-400;
- font-size: v.$text-xs;
- font-weight: v.$fw-bold;
-}
-
-.active .stepDot {
- background: v.$brick;
- color: v.$white;
-}
-
-.completed .stepDot {
- background: v.$success-bg;
- color: v.$success;
-}
-
-// ── Right cluster ────────────────────────────────────────────────────────────
-.timer {
- display: inline-flex;
- align-items: center;
- gap: v.$space-2;
- padding: v.$space-2 v.$space-3;
- border-radius: v.$r-pill;
- background: v.$g100;
- color: v.$g700;
- font-size: v.$text-sm;
- font-weight: v.$fw-semibold;
- font-variant-numeric: tabular-nums;
- flex-shrink: 0;
-
- @include m.mobile {
- padding: v.$space-1 v.$space-2;
- }
-}
-
-.timerLow {
- background: v.$danger-bg;
- color: v.$danger;
-}
-
-.helpWrap {
- position: relative;
- display: flex;
-
- @include m.mobile {
- display: none;
- }
-}
-
-.help {
- display: flex;
- align-items: center;
- justify-content: center;
- width: 1.75rem;
- height: 1.75rem;
- border-radius: v.$r-pill;
- border: 1.5px solid v.$gray-300;
- background: transparent;
- color: v.$gray-500;
- font-size: v.$text-sm;
- font-weight: v.$fw-bold;
- cursor: pointer;
-
- &:hover,
- &[aria-expanded='true'] {
- border-color: v.$brick;
- color: v.$brick;
- }
-}
-
-.legendBackdrop {
- position: fixed;
- inset: 0;
- z-index: 40;
-}
-
-.legend {
- position: absolute;
- top: calc(100% + 0.5rem);
- right: 0;
- z-index: 41;
- min-width: 13.5rem;
- padding: v.$space-4;
- background: v.$white;
- border: 1px solid v.$gray-200;
- border-radius: v.$r-md;
- box-shadow: v.$shadow-lg;
- display: flex;
- flex-direction: column;
- gap: v.$space-3;
-}
-
-.legendTitle {
- margin: 0;
- font-size: v.$text-xs;
- font-weight: v.$fw-bold;
- text-transform: uppercase;
- letter-spacing: 0.04em;
- color: v.$g500;
-}
-
-.legendItem {
- display: flex;
- align-items: center;
- gap: v.$space-3;
- font-size: v.$text-sm;
- color: v.$g700;
-}
-
-.legendDot {
- display: flex;
- align-items: center;
- justify-content: center;
- flex-shrink: 0;
- width: 1.5rem;
- height: 1.5rem;
- border-radius: v.$r-pill;
- background: v.$g100;
- color: v.$gray-400;
- font-size: v.$text-xs;
- font-weight: v.$fw-bold;
-
- &.active {
- background: v.$brick;
- color: v.$white;
- }
-
- &.completed {
- background: v.$success-bg;
- color: v.$success;
- }
-}
-
-.counter {
- font-size: v.$text-sm;
- font-weight: v.$fw-semibold;
- color: v.$g700;
- font-variant-numeric: tabular-nums;
- white-space: nowrap;
-}
-
-.submitBtn {
- @include m.button-base;
- @include m.focus-ring($color: v.$g700);
-
- flex-shrink: 0;
- background: v.$dark;
- color: v.$white;
-
- &:hover:not(:disabled) {
- background: v.$g800;
- }
-
- @include m.mobile {
- padding: v.$space-2 v.$space-3;
- }
-}
diff --git a/projects/sunbird-quml-player-react/src/components/PlayerHeader/PlayerHeader.test.tsx b/projects/sunbird-quml-player-react/src/components/PlayerHeader/PlayerHeader.test.tsx
deleted file mode 100644
index 9909c9c3..00000000
--- a/projects/sunbird-quml-player-react/src/components/PlayerHeader/PlayerHeader.test.tsx
+++ /dev/null
@@ -1,53 +0,0 @@
-import { describe, it, expect, vi } from 'vitest';
-import { render, screen, fireEvent } from '@testing-library/react';
-import { PlayerHeader } from './PlayerHeader';
-import type { Section } from '../../types';
-
-const mkSection = (id: string): Section => ({
- identifier: id,
- name: id,
- children: [],
- timeLimits: { max: 0, min: 0 },
- allowSkip: true,
- shuffle: false,
-});
-
-const baseProps = {
- brand: 'Sunbird',
- sections: [mkSection('a'), mkSection('b'), mkSection('c')],
- currentSectionIndex: 0,
- completed: [false, false, false],
- questionNumber: 1,
- totalQuestions: 9,
- onSubmit: vi.fn(),
-};
-
-describe('PlayerHeader', () => {
- it('renders brand, step indicators, counter and timer', () => {
- render();
- expect(screen.getByText('Sunbird')).toBeInTheDocument();
- expect(screen.getByText('1/9')).toBeInTheDocument();
- expect(screen.getByText('14:49')).toBeInTheDocument(); // mm:ss of 889
- const steps = screen.getAllByRole('listitem');
- expect(steps[0]).toHaveAttribute('aria-current', 'step');
- });
-
- it('hides the timer when no time remaining is given', () => {
- render();
- expect(screen.queryByRole('timer')).not.toBeInTheDocument();
- });
-
- it('emits onSubmit', () => {
- const onSubmit = vi.fn();
- render();
- fireEvent.click(screen.getByRole('button', { name: /submit/i }));
- expect(onSubmit).toHaveBeenCalledTimes(1);
- });
-
- it('emits onBrandClick when the brand is clicked', () => {
- const onBrandClick = vi.fn();
- render();
- fireEvent.click(screen.getByRole('button', { name: /sunbird/i }));
- expect(onBrandClick).toHaveBeenCalledTimes(1);
- });
-});
diff --git a/projects/sunbird-quml-player-react/src/components/PlayerHeader/PlayerHeader.tsx b/projects/sunbird-quml-player-react/src/components/PlayerHeader/PlayerHeader.tsx
deleted file mode 100644
index 0fbe40a6..00000000
--- a/projects/sunbird-quml-player-react/src/components/PlayerHeader/PlayerHeader.tsx
+++ /dev/null
@@ -1,166 +0,0 @@
-import { useState } from 'react';
-import { t, readI18n } from '../../i18n/translations';
-import { TimerIcon, MenuIcon } from '../icons';
-import type { Section } from '../../types';
-import styles from './PlayerHeader.module.scss';
-
-/**
- * PlayerHeader — persistent assessment shell header (Phase 6 design).
- *
- * Pure presentational: brand + section step indicators (left) and timer, help,
- * global question counter, and Submit (right). All data is supplied by MainPlayer
- * from Context; intent is emitted via callbacks. No Context mutation.
- */
-export interface PlayerHeaderProps {
- brand: string;
- sections: Section[];
- currentSectionIndex: number;
- completed: boolean[];
- /** Seconds remaining (countdown mode); null/omitted hides the countdown. */
- timeRemaining?: number | null;
- /**
- * Seconds elapsed (count-up mode — Angular header showCountUp parity, shown
- * when there is no time limit). Ignored while a countdown is active.
- */
- timeElapsed?: number | null;
- questionNumber: number;
- totalQuestions: number;
- onSubmit: () => void;
- onMenuClick?: () => void;
- /** Click the brand to return to the overview / start page. */
- onBrandClick?: () => void;
- language?: string;
-}
-
-function formatMmSs(seconds: number): string {
- const mins = Math.floor(seconds / 60);
- const secs = seconds % 60;
- return `${mins}:${String(secs).padStart(2, '0')}`;
-}
-
-export function PlayerHeader({
- brand,
- sections,
- currentSectionIndex,
- completed,
- timeRemaining = null,
- timeElapsed = null,
- questionNumber,
- totalQuestions,
- onSubmit,
- onMenuClick,
- onBrandClick,
- language = 'en',
-}: PlayerHeaderProps) {
- // Countdown takes precedence; count-up shows when there is no time limit.
- const showCountdown = timeRemaining != null;
- const showTimer = showCountdown || timeElapsed != null;
- const isTimeLow = showCountdown && timeRemaining <= 60;
- const [showLegend, setShowLegend] = useState(false);
-
- return (
-
-
- {onMenuClick && (
-
- )}
-
-
-
-
- {sections.map((section, index) => {
- const status =
- index === currentSectionIndex
- ? 'active'
- : completed[index]
- ? 'completed'
- : 'upcoming';
- return (
- -
- {String.fromCharCode(65 + index)}
-
- );
- })}
-
-
-
-
- {showTimer && (
-
-
-
- {formatMmSs(showCountdown ? timeRemaining! : timeElapsed!)}
-
-
- )}
-
-
-
-
- {showLegend && (
- <>
-
setShowLegend(false)} />
-
-
{t(language, 'HELP_LEGEND_TITLE')}
-
- A
- {t(language, 'SECTION_CURRENT')}
-
-
- A
- {t(language, 'SECTION_DONE')}
-
-
- B
- {t(language, 'SECTION_UPCOMING')}
-
-
- >
- )}
-
-
-
- {questionNumber}/{totalQuestions}
-
-
-
-
-
- );
-}
diff --git a/projects/sunbird-quml-player-react/src/components/ProgressIndicators/ProgressIndicators.module.scss b/projects/sunbird-quml-player-react/src/components/ProgressIndicators/ProgressIndicators.module.scss
deleted file mode 100644
index d8714142..00000000
--- a/projects/sunbird-quml-player-react/src/components/ProgressIndicators/ProgressIndicators.module.scss
+++ /dev/null
@@ -1,90 +0,0 @@
-@use '../../styles/variables' as v;
-
-.progressBar {
- display: flex;
- flex-direction: column;
- gap: v.$space-2;
- font-family: v.$ff-base;
-}
-
-.progressMeta {
- display: flex;
- justify-content: space-between;
- align-items: baseline;
-}
-
-.progressLabel {
- font-size: v.$text-xs;
- font-weight: v.$fw-semibold;
- color: v.$g600;
- text-transform: uppercase;
- letter-spacing: 0.04em;
-}
-
-.progressCount {
- font-size: v.$text-xs;
- font-weight: v.$fw-medium;
- color: v.$g500;
- font-variant-numeric: tabular-nums;
-}
-
-.track {
- width: 100%;
- height: 0.5rem;
- background: v.$gray-200;
- border-radius: v.$r-pill;
- overflow: hidden;
-}
-
-.fill {
- height: 100%;
- background: v.$brick;
- border-radius: v.$r-pill;
- transition: width v.$dur-base v.$ease-out;
-}
-
-.steps {
- display: flex;
- align-items: center;
- gap: v.$space-2;
- margin: 0;
- padding: 0;
- list-style: none;
-}
-
-.step {
- display: flex;
-}
-
-.dot {
- display: flex;
- align-items: center;
- justify-content: center;
- width: 1.75rem;
- height: 1.75rem;
- border-radius: v.$r-pill;
- border: 1.5px solid v.$gray-300;
- background: v.$white;
- color: v.$g500;
- font-family: v.$ff-base;
- font-size: v.$text-xs;
- font-weight: v.$fw-semibold;
- font-variant-numeric: tabular-nums;
- transition: all v.$dur-fast v.$ease-out;
-}
-
-.active .dot {
- border-color: v.$brick;
- background: v.$brick;
- color: v.$white;
-}
-
-.completed .dot {
- border-color: v.$success;
- background: v.$success-bg;
- color: v.$success;
-}
-
-.upcoming .dot {
- opacity: 0.85;
-}
diff --git a/projects/sunbird-quml-player-react/src/components/ProgressIndicators/ProgressIndicators.test.tsx b/projects/sunbird-quml-player-react/src/components/ProgressIndicators/ProgressIndicators.test.tsx
deleted file mode 100644
index 8a3aa5da..00000000
--- a/projects/sunbird-quml-player-react/src/components/ProgressIndicators/ProgressIndicators.test.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-import { describe, it, expect } from 'vitest';
-import { render, screen } from '@testing-library/react';
-import { ProgressBar, SectionSteps } from './ProgressIndicators';
-import type { Section } from '../../types';
-
-const mkSection = (id: string): Section => ({
- identifier: id,
- name: id,
- children: [],
- timeLimits: { max: 0, min: 0 },
- allowSkip: true,
- shuffle: false,
-});
-
-describe('ProgressBar', () => {
- it('exposes progressbar ARIA values', () => {
- render(
);
- const bar = screen.getByRole('progressbar');
- expect(bar).toHaveAttribute('aria-valuenow', '3');
- expect(bar).toHaveAttribute('aria-valuemax', '10');
- expect(bar).toHaveAttribute('aria-valuemin', '0');
- });
-});
-
-describe('SectionSteps', () => {
- it('marks the active section with aria-current', () => {
- const sections = [mkSection('a'), mkSection('b'), mkSection('c')];
- render(
-
,
- );
- const items = screen.getAllByRole('listitem');
- expect(items[1]).toHaveAttribute('aria-current', 'step');
- expect(items[0]).not.toHaveAttribute('aria-current');
- });
-});
diff --git a/projects/sunbird-quml-player-react/src/components/ProgressIndicators/ProgressIndicators.tsx b/projects/sunbird-quml-player-react/src/components/ProgressIndicators/ProgressIndicators.tsx
deleted file mode 100644
index 2a988db5..00000000
--- a/projects/sunbird-quml-player-react/src/components/ProgressIndicators/ProgressIndicators.tsx
+++ /dev/null
@@ -1,79 +0,0 @@
-import { t, readI18n } from '../../i18n/translations';
-import type { Section } from '../../types';
-import styles from './ProgressIndicators.module.scss';
-
-/**
- * Progress indicators (spec §6.5) — pure, derived entirely from Context props.
- * Two exports:
- * - ProgressBar: answered/total bar (role="progressbar").
- * - SectionSteps: active/completed/upcoming section dots.
- */
-
-export interface ProgressBarProps {
- answered: number;
- total: number;
- language?: string;
-}
-
-export function ProgressBar({ answered, total, language = 'en' }: ProgressBarProps) {
- const pct = total > 0 ? Math.round((answered / total) * 100) : 0;
- return (
-
-
- {t(language, 'PROGRESS')}
-
- {answered} {t(language, 'OF')} {total}
-
-
-
-
- );
-}
-
-export interface SectionStepsProps {
- sections: Section[];
- currentSectionIndex: number;
- completed: boolean[];
- language?: string;
-}
-
-export function SectionSteps({
- sections,
- currentSectionIndex,
- completed,
- language = 'en',
-}: SectionStepsProps) {
- return (
-
- {sections.map((section, index) => {
- const state =
- index === currentSectionIndex
- ? 'active'
- : completed[index]
- ? 'completed'
- : 'upcoming';
- return (
- -
-
- {index + 1}
-
-
- );
- })}
-
- );
-}
diff --git a/projects/sunbird-quml-player-react/src/components/QuestionBody/QuestionBody.module.scss b/projects/sunbird-quml-player-react/src/components/QuestionBody/QuestionBody.module.scss
deleted file mode 100644
index ac82b310..00000000
--- a/projects/sunbird-quml-player-react/src/components/QuestionBody/QuestionBody.module.scss
+++ /dev/null
@@ -1,67 +0,0 @@
-@use '../../styles/variables' as v;
-
-.body {
- font-family: v.$ff-question; // Noto Serif — editorial question stem (design)
- font-size: v.$text-base;
- line-height: v.$lh-normal;
- color: v.$g700;
- word-wrap: break-word;
- overflow-wrap: anywhere; // long URLs / unbroken strings never overflow
- max-width: 100%;
-
- // Images in body
- img {
- max-width: 100%;
- height: auto;
- margin: v.$space-3 0;
- border-radius: v.$r-sm;
- }
-
- // Tables — scroll horizontally inside their own box rather than the page.
- table {
- display: block;
- width: 100%;
- max-width: 100%;
- overflow-x: auto;
- -webkit-overflow-scrolling: touch;
- border-collapse: collapse;
- margin: v.$space-3 0;
-
- td,
- th {
- border: 1px solid v.$gray-200;
- padding: v.$space-2;
- text-align: left;
- }
- }
-
- // KaTeX — wide display math scrolls inside its own box (no page overflow).
- :global(.katex-display) {
- max-width: 100%;
- overflow-x: auto;
- overflow-y: hidden;
- padding-bottom: v.$space-1;
- }
-
- :global(.math-block) {
- max-width: 100%;
- overflow-x: auto;
- }
-
- // RTL support comes from dir="auto" on the container (direction resolved
- // from the content itself); `start` alignment follows whichever direction
- // the browser resolves, so tables align correctly in both scripts.
- table {
- td,
- th {
- text-align: start;
- }
- }
-
- // In an RTL UI (renderer wrapper sets dir="rtl") the body BLOCK aligns right
- // like the rest of the mirrored layout — while dir="auto" above still keeps
- // the CHARACTER order of English/math fallback content intact (1+1=?).
- [dir='rtl'] & {
- text-align: right;
- }
-}
diff --git a/projects/sunbird-quml-player-react/src/components/QuestionBody/QuestionBody.test.tsx b/projects/sunbird-quml-player-react/src/components/QuestionBody/QuestionBody.test.tsx
deleted file mode 100644
index c1a946a9..00000000
--- a/projects/sunbird-quml-player-react/src/components/QuestionBody/QuestionBody.test.tsx
+++ /dev/null
@@ -1,54 +0,0 @@
-import { describe, it, expect } from 'vitest';
-import { render } from '@testing-library/react';
-import { QuestionBody } from './QuestionBody';
-
-describe('QuestionBody', () => {
- it('renders plain HTML body', () => {
- const { container } = render(
What is 2+2?' }} />);
- expect(container.textContent).toContain('What is 2+2?');
- });
-
- it('renders images from the body', () => {
- const { container } = render(' }} />);
- expect(container.querySelector('img')).toBeInTheDocument();
- });
-
- it('renders tables from the body', () => {
- const { container } = render(
- | cell |
' }} />,
- );
- expect(container.querySelector('table')).toBeInTheDocument();
- expect(container.textContent).toContain('cell');
- });
-
- it('uses dir="auto" so content direction follows the text (Arabic)', () => {
- const { container } = render(
- السلام عليكم' }} language="ar" />,
- );
- const root = container.firstElementChild;
- // dir="auto" (not a forced rtl): Arabic content resolves RTL, while
- // English/math fallback keeps its LTR character order (e.g. "1+1=?").
- expect(root).toHaveAttribute('dir', 'auto');
- expect(root).toHaveAttribute('lang', 'ar');
- });
-
- it('uses dir="auto" and the given lang for non-Arabic', () => {
- const { container } = render(Hello' }} />);
- const root = container.firstElementChild;
- expect(root).toHaveAttribute('dir', 'auto');
- expect(root).toHaveAttribute('lang', 'en');
- });
-
- it('renders KaTeX math from .math elements', () => {
- const { container } = render(
- x^2' }} />,
- );
- // KaTeX replaces the element content with .katex markup
- expect(container.querySelector('.katex')).toBeInTheDocument();
- });
-
- it('does not crash on empty body', () => {
- const { container } = render();
- expect(container.firstElementChild).toBeInTheDocument();
- });
-});
diff --git a/projects/sunbird-quml-player-react/src/components/QuestionBody/QuestionBody.tsx b/projects/sunbird-quml-player-react/src/components/QuestionBody/QuestionBody.tsx
deleted file mode 100644
index 5ddc4394..00000000
--- a/projects/sunbird-quml-player-react/src/components/QuestionBody/QuestionBody.tsx
+++ /dev/null
@@ -1,95 +0,0 @@
-import { useEffect, useRef } from 'react';
-import katex from 'katex';
-import 'katex/dist/katex.min.css';
-import { resolveMediaHtml } from '../../utils/media';
-import type { MediaItem, MediaResolveContext } from '../../utils/media';
-import { readI18n } from '../../i18n/translations';
-import type { Question } from '../../types';
-import styles from './QuestionBody.module.scss';
-
-/**
- * QuestionBody — generic, shared renderer for question text.
- *
- * Responsibilities ONLY:
- * - Render raw HTML body (may contain images, tables, etc.)
- * - Render KaTeX math found in `.math` / `.math-block` elements
- * - RTL support (Arabic)
- *
- * It is question-type AGNOSTIC: no MCQ/SA/MTF/SEQ/REO/FTB logic, no answer
- * handling, no scoring/telemetry/navigation. Every Phase 4 question type reuses
- * this component to render its stem.
- */
-interface QuestionBodyProps {
- question: Pick;
- language?: string;
- /**
- * Media + offline resolution inputs. When supplied (e.g. by Hint for solution
- * content), its `media` takes precedence over `question.media`.
- */
- mediaCtx?: MediaResolveContext;
-}
-
-export function QuestionBody({ question, language = 'en', mediaCtx }: QuestionBodyProps) {
- const containerRef = useRef(null);
- // The HTML most recently written to the container. Parents rebuild the
- // `question`/`mediaCtx` props as fresh object literals on every render (and
- // the shell timer re-renders the tree every second), so the effect must NOT
- // rewrite innerHTML unless the RESOLVED content actually changed — rewriting
- // destroys and recreates embedded