diff --git a/routes/create/controllers/h5pPreviewController.js b/routes/create/controllers/h5pPreviewController.js index 5396494..b6169a9 100644 --- a/routes/create/controllers/h5pPreviewController.js +++ b/routes/create/controllers/h5pPreviewController.js @@ -99,11 +99,8 @@ router.get('/libs/*', (req, res) => { } const filePath = path.join(H5P_LIBS_DIR, requestedPath); - console.log('[H5P-LIBS] Serving:', requestedPath, '->', filePath); - res.sendFile(filePath, (err) => { if (err) { - console.error('[H5P-LIBS] NOT FOUND:', filePath, err.message); res.status(404).send('Library file not found'); } }); @@ -193,17 +190,6 @@ body { margin:0; padding:40px; font-family:-apple-system,BlinkMacSystemFont,"Seg // Read directly from h5p-libs (no temp dir or symlinks needed). const { cssFiles, jsFiles } = await resolveLibraryDependencies(syntheticH5pJson); - // Build server-side diagnostic info to embed in HTML (user has no backend access) - const serverDiag = { - quizId, - questionTypes: [...questionTypes], - dependencies: preloadedDependencies.map(d => `${d.machineName}-${d.majorVersion}.${d.minorVersion}`), - resolvedJsFiles: jsFiles, - resolvedCssFiles: cssFiles, - h5pLibsDir: H5P_LIBS_DIR, - timestamp: new Date().toISOString() - }; - // Serve library files through the existing /api route — works on all environments // without needing extra nginx/proxy configuration. const libBasePath = '/api/create/h5p-preview/libs'; @@ -294,15 +280,6 @@ ${cssTags} ${questionBlocks.join('\n')} - ${jsTags} @@ -312,122 +289,8 @@ ${jsTags} H5P.$body = jQuery('body'); H5P.$window = jQuery(window); - // ===== SERVER-SIDE INFO (embedded at render time) ===== - var __serverDiag = ${JSON.stringify(serverDiag)}; - var __libScripts = __serverDiag.resolvedJsFiles; - var __libBasePath = '${libBasePath}'; - - async function runDiagnostics() { - console.log('%c===== H5P LOADING DIAGNOSTICS =====', 'color: yellow; font-size: 16px; font-weight: bold;'); - console.log('Time:', new Date().toISOString()); - console.log('Page URL:', window.location.href); - - // 1. Server-side info (dependency resolution results from backend) - console.log('%c--- SERVER-SIDE INFO (from backend) ---', 'color: cyan; font-weight: bold;'); - console.log('Quiz ID:', __serverDiag.quizId); - console.log('Question types:', __serverDiag.questionTypes); - console.log('h5p-libs dir:', __serverDiag.h5pLibsDir); - console.log('Dependencies resolved:', __serverDiag.dependencies); - console.log('JS files resolved (' + __serverDiag.resolvedJsFiles.length + '):', __serverDiag.resolvedJsFiles); - console.log('CSS files resolved (' + __serverDiag.resolvedCssFiles.length + '):', __serverDiag.resolvedCssFiles); - - // 2. Check which H5P constructors are registered after script loading - console.log('%c--- H5P CONSTRUCTOR CHECK ---', 'color: cyan; font-weight: bold;'); - var h5pKeys = Object.keys(window.H5P || {}).filter(function(k) { - return typeof H5P[k] === 'function'; - }); - console.log('Registered constructors (' + h5pKeys.length + '):', h5pKeys); - var criticalLibs = ['DragText', 'Dialogcards', 'MultiChoice', 'TrueFalse', 'Question', 'Column', 'JoubelUI', 'TextUtilities']; - criticalLibs.forEach(function(name) { - var val = H5P[name]; - var status = val ? '✅ ' + typeof val : '❌ MISSING'; - console.log(' H5P.' + name + ':', status); - }); - - // 3. Fetch each script URL to check HTTP status and content-type - console.log('%c--- SCRIPT URL FETCH CHECKS ---', 'color: cyan; font-weight: bold;'); - - // Check h5p-core.js first - try { - var coreResp = await fetch('/api/create/h5p-preview/core/h5p-core.js', { method: 'HEAD' }); - console.log('h5p-core.js → Status:', coreResp.status, 'Content-Type:', coreResp.headers.get('content-type')); - } catch(e) { - console.error('h5p-core.js → FETCH ERROR:', e.message); - } - - // Check each library script - var problems = []; - for (var i = 0; i < __libScripts.length; i++) { - var scriptUrl = __libBasePath + '/' + __libScripts[i]; - try { - var resp = await fetch(scriptUrl); - var ct = resp.headers.get('content-type') || 'unknown'; - var status = resp.status; - var bodyText = await resp.text(); - var isJS = ct.includes('javascript') || ct.includes('ecmascript'); - var isHTML = ct.includes('html') || bodyText.trimStart().startsWith(' 0) { - console.error('🔴 ' + problems.length + ' scripts have problems:'); - problems.forEach(function(p) { - if (p.isHTML) { - console.error(' ' + p.file + ' → Server returned HTML instead of JS! This means nginx is NOT routing to Express.'); - } else if (p.error) { - console.error(' ' + p.file + ' → Network error: ' + p.error); - } else { - console.error(' ' + p.file + ' → Status: ' + p.status + ', Type: ' + p.contentType); - } - }); - } else if (h5pKeys.length === 0) { - console.error('🔴 No H5P constructors registered even though all scripts loaded OK. Possible execution error.'); - } else { - console.log('🟢 All ' + __libScripts.length + ' scripts loaded, ' + h5pKeys.length + ' constructors registered.'); - } - console.log('%c===== END DIAGNOSTICS =====', 'color: yellow; font-size: 16px; font-weight: bold;'); - - return problems; - } - jQuery(document).ready(function() { - // Run diagnostics first, then render - runDiagnostics().then(function(problems) { ${runnableCalls.join('\n')} - }); }); diff --git a/routes/create/h5p-libs/H5P.Dialogcards-1.9/dist/2aecfafb6066a6b8c73d.svg b/routes/create/h5p-libs/H5P.Dialogcards-1.9/dist/2aecfafb6066a6b8c73d.svg new file mode 100644 index 0000000..2fa4a9c --- /dev/null +++ b/routes/create/h5p-libs/H5P.Dialogcards-1.9/dist/2aecfafb6066a6b8c73d.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + diff --git a/routes/create/h5p-libs/H5P.Dialogcards-1.9/dist/h5p-dialogcards.css b/routes/create/h5p-libs/H5P.Dialogcards-1.9/dist/h5p-dialogcards.css new file mode 100644 index 0000000..974b544 --- /dev/null +++ b/routes/create/h5p-libs/H5P.Dialogcards-1.9/dist/h5p-dialogcards.css @@ -0,0 +1,557 @@ +.h5p-dialogcards .h5p-dialogcards-title p:first-child, +.h5p-dialogcards .h5p-dialogcards-card-text-area p:first-child { + margin-top: 0; +} +.h5p-dialogcards .h5p-dialogcards-title p:last-child, +.h5p-dialogcards .h5p-dialogcards-card-text-area p:last-child { + margin-bottom: 0; +} + +.h5p-dialogcards .h5p-dialogcards-title p, +.h5p-dialogcards .h5p-dialogcards-card-text-area p { + font-size: inherit; + line-height: inherit; + margin: inherit; +} + +.h5p-dialogcards-card-text-area { + outline: 0; +} + +.h5p-dialogcards { + overflow: hidden; + position: relative; +} + +.h5p-no-frame .h5p-dialogcards .h5p-dialogcards-title, +.h5p-transparent .h5p-dialogcards .h5p-dialogcards-title { + padding: 0 0 0.375em 0; +} + +.h5p-dialogcards .h5p-dialogcards-title { + padding: 1em 1em 0.375em; +} + +.h5p-dialogcards .h5p-dialogcards-title-inner { + font-size: 1.125em; +} + +.h5p-no-frame .h5p-dialogcards .h5p-dialogcards-description, +.h5p-transparent .h5p-dialogcards .h5p-dialogcards-description { + margin: 0 0 1em; +} + +.h5p-dialogcards .h5p-dialogcards-description { + margin: 0 1em 1em; +} + +.h5p-dialogcards .h5p-dialogcards-description > p { + margin: 0; +} + +.h5p-dialogcards .h5p-dialogcards-footer { + margin: auto; + overflow: hidden; + line-height: 2.35em; + padding: 1em; + max-width: 32em; + position: relative; +} + +.h5p-dialogcards .h5p-dialogcards-cardwrap { + position: absolute; + left: 100%; + width: 100%; + padding: 0 0.5em; + box-sizing: border-box; + visibility: hidden; + height: inherit; + + -webkit-transition: visibility 0s 0.3s, left 300ms; + transition: visibility 0s 0.3s, left 300ms; +} +.h5p-dialogcards .h5p-dialogcards-cardwrap.h5p-dialogcards-current { + visibility: visible; + left: 0; + + -webkit-transition: left 300ms; + transition: left 300ms; +} +.h5p-dialogcards .h5p-dialogcards-cardwrap.h5p-dialogcards-previous { + left: -100%; +} + +.h5p-dialogcards .h5p-dialogcards-cardholder { + margin: auto; + max-width: 32em; + height: 100%; + -webkit-transition: -webkit-transform 0.2s ease-in-out; + transition: transform 0.2s ease-in-out; +} + +.h5p-dialogcards .h5p-dialogcards-card-content { + background: #FFF; + box-shadow: 0 2px 15px rgba(0,0,0,0.30); + padding: 1em; +} + +.h5p-dialogcards .h5p-dialogcards-card-footer { + height: 2.25em; + display: flex; + flex-direction: row; + justify-content: space-between; +} + +.h5p-dialogcards .h5p-dialogcards-cardwrap.h5p-dialogcards-mode-normal .h5p-dialogcards-card-footer { + justify-content: center; +} + +.h5p-dialogcards .h5p-dialogcards-image-wrapper { + position: relative; +} + +.h5p-dialogcards .h5p-dialogcards-image-wrapper > .h5p-dialogcards-image { + text-align: center; + max-height: 100%; + max-width: 100%; + vertical-align: bottom; + position: absolute; + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.h5p-dialogcards .h5p-audio-inner.hide { + display: none; +} + +.h5p-dialogcards .h5p-dialogcards-card-text-wrapper { + position: relative; + overflow: hidden; + min-height: 12em; +} + +.h5p-dialogcards.h5p-text-scaling .h5p-dialogcards-card-text-wrapper { + height: 12em; +} + +.h5p-dialogcards .h5p-dialogcards-audio-wrapper { + display: block; + margin: 0 auto; + vertical-align: baseline; + font-size: 1.5em; + margin-bottom: 0.5em; + width: 1.5em; + height: 1.5em; +} + +.h5p-dialogcards .h5p-dialogcards-audio-wrapper.h5p-audio-not-supported { + width: 100%; + height: 100%; + color: red; + font-size: 1em; + text-align: center; +} + +.h5p-dialogcards .h5p-dialogcards-audio-wrapper.h5p-audio-not-supported .h5p-audio-not-supported-icon { + width: 1.5em; + height: 1.5em; + padding: 0.25em; + margin: 0 auto 1em auto; + border: 2px red solid; + border-radius: 50%; +} + +.h5p-dialogcards .h5p-dialogcards-audio-wrapper.h5p-audio-not-supported .h5p-audio-not-supported-icon span { + width: 100%; + height: 100%; + display: block; + background-image: url(2aecfafb6066a6b8c73d.svg); +} + +.h5p-dialogcards .h5p-dialogcards-audio-wrapper.hide { + display: none; +} + +.h5p-dialogcards .h5p-dialogcards-card-text-inner { + position: relative; + height: calc(100% - 2.25em); + padding: 1em 1.5em; +} + +.h5p-dialogcards.h5p-text-scaling .h5p-dialogcards-card-text-inner { + box-sizing: border-box; +} + +.h5p-dialogcards .h5p-dialogcards-card-text-inner-content { + position: absolute; + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); + width: 100%; + padding: 0 1em; + box-sizing: border-box; +} + +.h5p-dialogcards .h5p-dialogcards-card-text { + display: inline-block; + margin: 0.5em 0; + height: 4.5em; + line-height: 1.5; + width: 100%; +} + +.h5p-dialogcards .h5p-dialogcards-card-text.hide { + display: none; +} + +.h5p-dialogcards .h5p-dialogcards-collapse { + -webkit-transform: scale(0,1); + -ms-transform: scale(0,1); + transform: scale(0,1); +} + +.h5p-dialogcards .h5p-dialogcards-endcomment { + font-size: 1em; + color: #666; + text-align: center; + margin: 0em 1em; +} + +.h5p-dialogcards .h5p-dialogcards-middle { + display: table-cell; +} +.h5p-dialogcards .h5p-dialogcards-left { + text-align: left; +} + +.h5p-dialogcards .h5p-dialogcards-progress { + color: #757575; + text-align: center; +} + +.h5p-dialogcards .h5p-dialogcards-round { + float: left; + margin-left: 1.5em; + color: #757575; + font-weight: 400; + text-decoration: none solid rgb(153, 153, 153); +} + +.h5p-dialogcards .h5p-dialogcards-cards-left { + float: right; + margin-right: 1.5em; + color: #757575; + font-weight: 400; + text-decoration: none solid rgb(153, 153, 153); +} + +.h5p-dialogcards .h5p-joubelui-button.h5p-dialogcards-turn { + margin: 0; + font-weight: normal; + line-height: 1; + order: 1; +} + +.h5p-dialogcards .h5p-dialogcards-turn:before { + font-family: 'H5PFontAwesome4'; + content: "\f021"; +} + +.h5p-dialogcards .h5p-joubelui-button.h5p-dialogcards-show-summary { + margin: 0; + font-weight: normal; + line-height: 1; + order: 1; +} + +.h5p-dialogcards .h5p-dialogcards-show-summary:before { + font-family: 'H5PFontAwesome4'; + content: "\f0ca"; +} + +.h5p-dialogcards .h5p-joubelui-button.h5p-dialogcards-answer-button { + margin: 0; + border: 2px solid #ffffff; + border-radius: 67px; + background-color: #ffffff; + background-size: cover; + color: #b3b3b3; + font-weight: bold; + text-decoration: none solid rgb(179, 179, 179); + line-height: 1; + cursor: inherit; + font-size: 0.75em; +} + +.h5p-dialogcards .h5p-joubelui-button.h5p-dialogcards-button-hidden { + visibility: hidden; +} + +.h5p-dialogcards .h5p-joubelui-button.h5p-dialogcards-button-gone { + display: none; + visibility: hidden; +} + +.h5p-dialogcards .h5p-joubelui-button.h5p-dialogcards-answer-button:active { + background-color: #ffffff; + box-shadow: none; +} + +.h5p-dialogcards .h5p-joubelui-button.h5p-dialogcards-answer-button.h5p-dialogcards-quick-progression { + cursor: pointer; +} + +.h5p-dialogcards .h5p-joubelui-button.h5p-dialogcards-answer-button.correct { + order: 2; +} + +.h5p-dialogcards .h5p-joubelui-button.h5p-dialogcards-answer-button.correct:before { + font-family: 'H5PFontAwesome4'; + content: "\f00c"; + font-weight: normal; +} + +.h5p-dialogcards .h5p-joubelui-button.h5p-dialogcards-answer-button.correct.h5p-dialogcards-quick-progression { + border: 2px solid #1f824c; + color: #1f824c; + text-decoration: none solid rgb(31, 130, 76); +} + +.h5p-dialogcards .h5p-joubelui-button.h5p-dialogcards-answer-button.correct.h5p-dialogcards-quick-progression:hover { + color: #fff; + background-color: #1f824c; +} + +.h5p-dialogcards .h5p-joubelui-button.h5p-dialogcards-answer-button.incorrect { + order: 0; +} + +.h5p-dialogcards .h5p-joubelui-button.h5p-dialogcards-answer-button.incorrect:before { + font-family: 'H5PFontAwesome4'; + content: "\f00d"; + font-weight: normal; +} + +.h5p-dialogcards .h5p-joubelui-button.h5p-dialogcards-answer-button.incorrect.h5p-dialogcards-quick-progression { + border: 2px solid #d95354; + color: #d95354; + text-decoration: none solid rgb(217, 83, 84); +} + +.h5p-dialogcards .h5p-joubelui-button.h5p-dialogcards-answer-button.incorrect.h5p-dialogcards-quick-progression:hover { + color: #fff; + background-color: #d95354; +} + +.h5p-dialogcards .h5p-joubelui-button.h5p-dialogcards-footer-button { + position: absolute; + display: inline-block; + margin: 0; +} + +.h5p-dialogcards .h5p-dialogcards-prev { + left: 1em; +} + +.h5p-dialogcards .h5p-dialogcards-prev:before { + font-family: 'H5PFontAwesome4'; + content: "\f053"; + margin-right: 0.2em; +} + +.h5p-dialogcards .h5p-dialogcards-next { + right: 1em; +} + +.h5p-dialogcards .h5p-dialogcards-retry { + right: 1em; +} + +.h5p-dialogcards .h5p-dialogcards-retry:before { + font-family: 'H5PFontAwesome4'; + content: "\f01e"; +} + +.h5p-dialogcards .h5p-dialogcards-next:after { + font-family: 'H5PFontAwesome4'; + content: "\f054"; + margin-left: 0.2em; +} + +.h5p-dialogcards .joubel-tip-container { + position: absolute; + right: 0.5em; + top: 0.1em; + font-size: 1.2em; +} + +.h5p-dialogcards .h5p-dialogcards-cardwrap-set { + margin: auto; + max-width: 32em; +} + +.h5p-dialogcards .h5p-joubelui-button.h5p-dialogcards-disabled { + display: none; +} + +/* Audio button styling */ +/*TODO: Make Audio use JoubelUI button */ +.h5p-dialogcards .h5p-audio-minimal-button { + border: none; + background: #1a73d9; + font-weight: normal; + padding: 0; + font-size: 1em; + width: 1.5em; + height: 1.5em; + line-height: 1.5em; +} + +.h5p-dialogcards .h5p-audio-minimal-button:before { + font-size: 0.8em; + vertical-align: bottom; +} + +.h5p-dialogcards .h5p-audio-minimal-button.h5p-audio-minimal-pause:before { + font-size: 0.6em; +} + +.h5p-dialogcards .h5p-audio-minimal-button:focus, +.h5p-dialogcards .h5p-audio-minimal-button:hover { + background: #1356a3; +} + +.h5p-course-presentation .h5p-element .h5p-dialogcards-outer-element .h5p-element-inner.h5p-dialogcards.h5p-text-scaling { + overflow-y: hidden; +} + +/* Accessibility announcers, hidden from view */ +.h5p-dialogcards-card-side-announcer, +.h5p-dialogcards-at-progress { + position: absolute; + height: 0; + width: 0; + overflow: hidden; +} + +.h5p-dialogcards-summary-screen { + display: flex; + flex-direction: column; + align-items: center; + padding: 1em; +} + +.h5p-dialogcards-summary-screen .h5p-dialogcards-summary-container { + width: 100%; + display: flex; + flex-direction: column; + justify-content: center; + margin-bottom: 2em; +} + +.h5p-dialogcards-summary-screen .h5p-dialogcards-summary-header { + width: 100%; + font-weight: bold; + font-size: 1.2em; + text-align: center; +} + +.h5p-dialogcards-summary-screen .h5p-dialogcards-summary-subheader { + padding-top: 0.5em; + margin-bottom: 2em; + width: 100%; + text-align: center; +} + +.h5p-dialogcards-summary-screen .h5p-dialogcards-summary-message { + width: 100%; + font-size: 1.2em; + margin-top: 1em; + text-align: center; + font-weight: bold; + color: #1a73d9; +} + +.h5p-dialogcards-summary-screen .h5p-dialogcards-summary-footer { + width: 100%; + margin-top: 2em; + display: flex; + flex-direction: row; + justify-content: center; +} + +.h5p-dialogcards-summary-screen .h5p-dialogcards-button-next-round { +} + +.h5p-dialogcards-summary-screen .h5p-dialogcards-button-next-round:before { + font-family: 'H5PFontAwesome4'; + content: "\f061"; +} + +.h5p-dialogcards-summary-screen .h5p-dialogcards-button-restart:before { + font-family: 'H5PFontAwesome4'; + content: "\f01e"; +} + +.h5p-dialogcards-summary-screen .h5p-dialogcards-summary-table { + width: 100%; +} + +.h5p-dialogcards-summary-screen .h5p-dialogcards-summary-table td { + height: 1.6em; + border-bottom-style: solid; + border-bottom-width: 1px; + border-bottom-color: #d9d9d9; + text-align: left; +} + +.h5p-dialogcards-summary-screen .h5p-dialogcards-summary-table td.h5p-dialogcards-summary-table-row-category { + width: 100%; +} + +.h5p-dialogcards-summary-screen .h5p-dialogcards-summary-table td.h5p-dialogcards-summary-table-row-symbol { + padding-left: 0.5em; +} + +.h5p-dialogcards-summary-screen .h5p-dialogcards-summary-table td.h5p-dialogcards-summary-table-row-symbol.h5p-dialogcards-check:before { + font-family: 'H5PFontAwesome4'; + content: "\f00c"; + color: #1f824c; +} + +.h5p-dialogcards-summary-screen .h5p-dialogcards-summary-table td.h5p-dialogcards-summary-table-row-symbol.h5p-dialogcards-times:before { + font-family: 'H5PFontAwesome4'; + content: "\f00d"; + color: #d95354; +} + +.h5p-dialogcards-summary-screen .h5p-dialogcards-summary-table td.h5p-dialogcards-summary-table-row-score { + padding-left: 0.5em; + text-align: right; + font-weight: bold; +} + +.h5p-dialogcards-summary-screen .h5p-dialogcards-summary-table td.h5p-dialogcards-summary-table-row-score-divider { + color: #757575; + font-size: 0.75em; +} + +.h5p-dialogcards-gone { + display: none; + visibility: hidden; +} + +.button-tooltip { + background: #333e; + margin: auto; + padding: 5px; + position: absolute; + z-index: 1000; + font-size: 12px; + transform: translate(-50%, -70%); +} diff --git a/routes/create/h5p-libs/H5P.Dialogcards-1.9/dist/h5p-dialogcards.js b/routes/create/h5p-libs/H5P.Dialogcards-1.9/dist/h5p-dialogcards.js new file mode 100644 index 0000000..46e1664 --- /dev/null +++ b/routes/create/h5p-libs/H5P.Dialogcards-1.9/dist/h5p-dialogcards.js @@ -0,0 +1 @@ +(()=>{"use strict";var r=H5P.jQuery,e=function(){function e(e,t,a,i){var s=arguments.length>4&&void 0!==arguments[4]?arguments[4]:{},n=arguments.length>5?arguments[5]:void 0;return this.card=e,this.params=t||{},this.id=a,this.contentId=i,this.callbacks=s,this.$cardWrapper=r("
",{class:"h5p-dialogcards-cardwrap",role:"group",tabindex:"-1"}),this.$cardWrapper.addClass("h5p-dialogcards-mode-"+this.params.mode),"repetition"!==this.params.mode&&this.$cardWrapper.attr("aria-labelledby","h5p-dialogcards-progress-"+n),this.$cardHolder=r("
",{class:"h5p-dialogcards-cardholder"}).appendTo(this.$cardWrapper),this.createCardContent(e).appendTo(this.$cardHolder),this}var t=e.prototype;return t.createCardContent=function(e){var t=r("
",{class:"h5p-dialogcards-card-content"});this.createCardImage(e).appendTo(t);var a=r("
",{class:"h5p-dialogcards-card-text-wrapper"}).appendTo(t),i=r("
",{class:"h5p-dialogcards-card-text-inner"}).appendTo(a),s=r("
",{class:"h5p-dialogcards-card-text-inner-content"}).appendTo(i);this.createCardAudio(e).appendTo(s);var n=r("
",{class:"h5p-dialogcards-card-text"}).appendTo(s);return this.$cardTextArea=r("
",{class:"h5p-dialogcards-card-text-area",tabindex:"-1",html:e.text}).appendTo(n),e.text&&e.text.length||n.addClass("hide"),this.createCardFooter().appendTo(a),t},t.massageAttributeOutput=function(r){var e=(new DOMParser).parseFromString(r,"text/html"),t=document.createElement("div");return t.innerHTML=e.documentElement.textContent,t.textContent||t.innerText||""},t.createCardImage=function(e){this.$image;var t=r("
",{class:"h5p-dialogcards-image-wrapper"});return void 0!==e.image?(this.image=e.image,this.$image=r(''),e.imageAltText&&this.$image.attr("alt",this.massageAttributeOutput(e.imageAltText))):this.$image=r('
'),this.$image.appendTo(t),t},t.createCardAudio=function(e){if(this.audio,this.$audioWrapper=r("
",{class:"h5p-dialogcards-audio-wrapper"}),void 0!==e.audio){var t={files:e.audio,audioNotSupported:this.params.audioNotSupported};this.audio=new H5P.Audio(t,this.contentId),this.audio.attach(this.$audioWrapper),this.audio.audio&&this.audio.audio.preload&&(this.audio.audio.preload="none")}else this.$audioWrapper.addClass("hide");return this.$audioWrapper},t.createCardFooter=function(){var e=r("
",{class:"h5p-dialogcards-card-footer"}),t="h5p-dialogcards-button-hidden",a="-1";return"repetition"===this.params.mode&&(t="",this.params.behaviour.quickProgression&&(t="h5p-dialogcards-quick-progression",a="0")),this.$buttonTurn=H5P.JoubelUI.createButton({class:"h5p-dialogcards-turn",html:this.params.answer}).appendTo(e),"repetition"===this.params.mode&&(this.$buttonShowSummary=H5P.JoubelUI.createButton({class:"h5p-dialogcards-show-summary h5p-dialogcards-button-gone",html:this.params.showSummary}).appendTo(e),this.$buttonIncorrect=H5P.JoubelUI.createButton({class:"h5p-dialogcards-answer-button",html:this.params.incorrectAnswer}).addClass("incorrect").addClass(t).attr("tabindex",a).appendTo(e),this.$buttonCorrect=H5P.JoubelUI.createButton({class:"h5p-dialogcards-answer-button",html:this.params.correctAnswer}).addClass("correct").addClass(t).attr("tabindex",a).appendTo(e)),e},t.createButtonListeners=function(){var r=this;this.$buttonTurn.unbind("click").click((function(){r.turnCard()})),"repetition"===this.params.mode&&(this.$buttonIncorrect.unbind("click").click((function(e){e.target.classList.contains("h5p-dialogcards-quick-progression")&&r.callbacks.onNextCard({cardId:r.id,result:!1})})),this.$buttonCorrect.unbind("click").click((function(e){e.target.classList.contains("h5p-dialogcards-quick-progression")&&r.callbacks.onNextCard({cardId:r.id,result:!0})})))},t.showSummaryButton=function(r){this.getDOM().find(".h5p-dialogcards-answer-button").addClass("h5p-dialogcards-button-hidden").attr("tabindex","-1"),this.$buttonTurn.addClass("h5p-dialogcards-button-gone"),this.$buttonShowSummary.click((function(){return r()})).removeClass("h5p-dialogcards-button-gone").focus()},t.hideSummaryButton=function(){"normal"!==this.params.mode&&(this.getDOM().find(".h5p-dialogcards-answer-button").removeClass("h5p-dialogcards-button-hidden").attr("tabindex","0"),this.$buttonTurn.removeClass("h5p-dialogcards-button-gone"),this.$buttonShowSummary.addClass("h5p-dialogcards-button-gone").off("click"))},t.turnCard=function(){var r=this,e=this.getDOM(),t=e.find(".h5p-dialogcards-card-content"),a=e.find(".h5p-dialogcards-cardholder").addClass("h5p-dialogcards-collapse");t.find(".joubel-tip-container").remove();var i=t.hasClass("h5p-dialogcards-turned");t.toggleClass("h5p-dialogcards-turned",!i),this.isInTransition=!0,setTimeout((function(){if(a.removeClass("h5p-dialogcards-collapse"),r.changeText(i?r.getText():r.getAnswer()),i?a.find(".h5p-audio-inner").removeClass("hide"):r.removeAudio(a),"repetition"===r.params.mode&&!r.params.behaviour.quickProgression){var s=e.find(".h5p-dialogcards-answer-button");!1===s.hasClass("h5p-dialogcards-quick-progression")&&s.addClass("h5p-dialogcards-quick-progression").attr("tabindex",0)}setTimeout((function(){r.isInTransition=!1,r.addTipToCard(t,i?"front":"back"),"function"==typeof r.callbacks.onCardTurned&&r.callbacks.onCardTurned(i)}),200),r.resizeOverflowingText(),r.$cardTextArea.focus()}),200)},t.changeText=function(r){this.$cardTextArea.html(r),this.$cardTextArea.toggleClass("hide",!r||!r.length)},t.setProgressText=function(r,e){if("repetition"===this.params.mode){var t=this.params.progressText.replace("@card",r.toString()).replace("@total",e.toString());this.$cardWrapper.attr("aria-label",t)}},t.resizeOverflowingText=function(){if(this.params.behaviour.scaleTextNotCard){var r=this.getDOM().find(".h5p-dialogcards-card-text"),e=r.children();this.resizeTextToFitContainer(r,e)}},t.resizeTextToFitContainer=function(r,t){t.css("font-size","");var a=r.get(0).getBoundingClientRect().height,i=t.get(0).getBoundingClientRect().height,s=parseFloat(r.css("font-size")),n=parseFloat(t.css("font-size")),o=this.getDOM().closest(".h5p-container"),d=parseFloat(o.css("font-size"));if(i>a)for(var c=!0;c;){if((n-=e.SCALEINTERVAL)d){l=!1;break}t.css("font-size",n/s+"em"),(i=t.get(0).getBoundingClientRect().height)>=a&&(l=!1,n-=e.SCALEINTERVAL,t.css("font-size",n/s+"em"))}},t.addTipToCard=function(r,e,t){"back"!==e&&(e="front"),void 0===t&&(t=this.id),r.find(".joubel-tip-container").remove();var a=this.card.tips;if(void 0!==a&&void 0!==a[e]){var i=a[e].trim();i.length&&r.find(".h5p-dialogcards-card-text-wrapper .h5p-dialogcards-card-text-inner").after(H5P.JoubelUI.createTip(i,{tipLabel:this.params.tipButtonLabel}))}},t.setCardFocus=function(r){if(!0===r)this.$cardTextArea.focus();else{var e=this.getDOM();e.one("transitionend",(function(){e.focus()}))}},t.stopAudio=function(){var r=this;if(this.audio&&this.audio.audio){var e=this.audio.audio.duration;e>0&&ethis.cards.length))return"number"==typeof this.cards[r]&&this.loadCard(r),this.cards[r]},e.getCardIds=function(){return this.cards.map((function(r,e){return e}))},e.loadCard=function(r){r<0||r>this.cards.length||"number"==typeof this.cards[r]&&(this.cards[r]=new t(this.params.dialogs[r],this.params,r,this.contentId,this.callbacks,this.idCounter))},r}();function i(r){return function(r){if(Array.isArray(r))return s(r)}(r)||function(r){if("undefined"!=typeof Symbol&&null!=r[Symbol.iterator]||null!=r["@@iterator"])return Array.from(r)}(r)||function(r,e){if(r){if("string"==typeof r)return s(r,e);var t={}.toString.call(r).slice(8,-1);return"Object"===t&&r.constructor&&(t=r.constructor.name),"Map"===t||"Set"===t?Array.from(r):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?s(r,e):void 0}}(r)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function s(r,e){(null==e||e>r.length)&&(e=r.length);for(var t=0,a=Array(e);t0&&void 0!==arguments[0]?arguments[0]:[];return this.cards=r.filter((function(e,t){return r.indexOf(e)>=t})),this}var e=r.prototype;return e.getCards=function(){return this.cards},e.peek=function(r){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;return e=Math.max(0,e),"top"===r&&(r=0),"bottom"===r&&(r=this.cards.length-e),r<0||r>this.cards.length-1?[]:this.cards.slice(r,r+e)},e.add=function(r){var e=this,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"top";"number"==typeof r&&(r=[r]),r.forEach((function(a){var s;-1===e.cards.indexOf(a)&&("top"===t?t=0:"bottom"===t?t=e.cards.length:"random"===t&&(t=Math.floor(Math.random()*e.cards.length)),(s=e.cards).splice.apply(s,[t,0].concat(i(r))))}))},e.push=function(r){this.add(r,"top")},e.pull=function(){var r=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"top";return r=Math.max(1,Math.min(r,this.cards.length)),"top"===e&&(e=0),"bottom"===e&&(e=-r),e=Math.max(0,Math.min(e,this.cards.length-1)),this.cards.splice(e,r)},e.remove=function(r){var e=this;"number"==typeof r&&(r=[r]),r.forEach((function(r){var t=e.cards.indexOf(r);t>-1&&e.cards.splice(t,1)}))},e.shuffle=function(){for(var r=this.cards.length-1;r>0;r--){var e=Math.floor(Math.random()*(r+1)),t=[this.cards[e],this.cards[r]];this.cards[r]=t[0],this.cards[e]=t[1]}return this.cards},e.contains=function(r){return-1!==this.cards.indexOf(r)},e.length=function(){return this.cards.length},r}();function o(r){return function(r){if(Array.isArray(r))return d(r)}(r)||function(r){if("undefined"!=typeof Symbol&&null!=r[Symbol.iterator]||null!=r["@@iterator"])return Array.from(r)}(r)||function(r,e){if(r){if("string"==typeof r)return d(r,e);var t={}.toString.call(r).slice(8,-1);return"Object"===t&&r.constructor&&(t=r.constructor.name),"Map"===t||"Set"===t?Array.from(r):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?d(r,e):void 0}}(r)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function d(r,e){(null==e||e>r.length)&&(e=r.length);for(var t=0,a=Array(e);t0;t--){var a=Math.floor(Math.random()*(t+1)),i=[e[a],e[t]];e[t]=i[0],e[a]=i[1]}return e},e.find=function(r){var e=-1;return this.cardPiles.forEach((function(t,a){if(-1!==e)return e;t.contains(r)&&(e=a)})),e},e.reset=function(r){this.createPiles(r)},e.getCard=function(r){return this.cardPool.getCard(r)},e.getSize=function(){return this.cardPool.getCardIds().length},e.getPiles=function(){return this.cardPiles},e.getPileSizes=function(){return this.cardPiles.map((function(r){return r.length()}))},r}();const l=function(){function r(r,e){var t=this;this.params=r,this.callbacks=e,this.currentCallback=e.nextRound,this.fields=[],this.container=document.createElement("div"),this.container.classList.add("h5p-dialogcards-summary-screen");var a=this.createContainerDOM(r.summary);this.fields.round=a.getElementsByClassName("h5p-dialogcards-summary-subheader")[0],this.fields["h5p-dialogcards-round-cards-right"]=this.addTableRow(a,{category:this.params.summaryCardsRight,symbol:"h5p-dialogcards-check"}),this.fields["h5p-dialogcards-round-cards-wrong"]=this.addTableRow(a,{category:this.params.summaryCardsWrong,symbol:"h5p-dialogcards-times"}),this.fields["h5p-dialogcards-round-cards-not-shown"]=this.addTableRow(a,{category:this.params.summaryCardsNotShown});var i=this.createContainerDOM(r.summaryOverallScore);this.fields["h5p-dialogcards-overall-cards-completed"]=this.addTableRow(i,{category:this.params.summaryCardsCompleted,symbol:"h5p-dialogcards-check"}),this.fields["h5p-dialogcards-overall-completed-rounds"]=this.addTableRow(i,{category:this.params.summaryCompletedRounds,symbol:""});var s=document.createElement("div");s.classList.add("h5p-dialogcards-summary-message"),this.fields.message=s;var n=H5P.JoubelUI.createButton({class:"h5p-dialogcards-buttonNextRound",title:this.params.nextRound.replace("@round",2),html:this.params.nextRound.replace("@round",2)}).click(this.currentCallback).get(0);this.fields.button=n;var o=H5P.JoubelUI.createButton({class:"h5p-dialogcards-button-restart",title:this.params.startOver,html:this.params.startOver}).get(0),d=this.createConfirmationDialog({l10n:this.params.confirmStartingOver,instance:this},(function(){setTimeout((function(){t.callbacks.retry()}),100)}));o.addEventListener("click",(function(r){d.show(r.target.offsetTop)})),this.fields.buttonStartOver=o;var c=document.createElement("div");return c.classList.add("h5p-dialogcards-summary-footer"),c.appendChild(o),c.appendChild(n),this.container.appendChild(a),this.container.appendChild(i),this.container.appendChild(s),this.container.appendChild(c),this.hide(),this}var e=r.prototype;return e.getDOM=function(){return this.container},e.createContainerDOM=function(r){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",t=document.createElement("div");t.classList.add("h5p-dialogcards-summary-container");var a=document.createElement("div");a.classList.add("h5p-dialogcards-summary-header"),a.innerHTML=r,t.appendChild(a);var i=document.createElement("div");i.classList.add("h5p-dialogcards-summary-subheader"),i.innerHTML=e,t.appendChild(i);var s=document.createElement("table");return s.classList.add("h5p-dialogcards-summary-table"),t.appendChild(s),t},e.addTableRow=function(r,e){var t=r.getElementsByClassName("h5p-dialogcards-summary-table")[0],a=document.createElement("tr"),i=document.createElement("td");i.classList.add("h5p-dialogcards-summary-table-row-category"),i.innerHTML=e.category,a.appendChild(i);var s=document.createElement("td");s.classList.add("h5p-dialogcards-summary-table-row-symbol"),void 0!==e.symbol&&""!==e.symbol&&s.classList.add(e.symbol),a.appendChild(s);var n=document.createElement("td");return n.classList.add("h5p-dialogcards-summary-table-row-score"),a.appendChild(n),t.appendChild(a),n},e.update=function(){var r=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.done,a=void 0!==t&&t,i=e.round,s=void 0===i?void 0:i,n=e.message,o=void 0===n?void 0:n,d=e.results,c=void 0===d?[]:d;!0===a?(this.fields.buttonStartOver.classList.add("h5p-dialogcards-button-gone"),this.params.behaviour.enableRetry?(this.fields.button.classList.remove("h5p-dialogcards-button-next-round"),this.fields.button.classList.add("h5p-dialogcards-button-restart"),this.fields.button.innerHTML=this.params.retry,this.fields.button.title=this.params.retry,this.currentCallback=this.callbacks.retry):this.fields.button.classList.add("h5p-dialogcards-button-gone")):(this.fields.buttonStartOver.classList.remove("h5p-dialogcards-button-gone"),this.fields.button.classList.add("h5p-dialogcards-button-next-round"),this.fields.button.classList.remove("h5p-dialogcards-button-restart"),this.fields.button.innerHTML=this.params.nextRound,this.fields.button.title=this.params.nextRound,this.currentCallback=this.callbacks.nextRound),H5P.jQuery(this.fields.button).unbind("click").click(this.currentCallback),this.fields.round.innerHTML=this.params.round.replace("@round",s),a||void 0===s||(this.fields.button.innerHTML=this.params.nextRound.replace("@round",s+1),this.fields.button.title=this.params.nextRound.replace("@round",s+1)),a&&void 0!==o&&""!==o?(this.fields.message.classList.remove("h5p-dialogcards-gone"),this.fields.message.innerHTML=o):this.fields.message.classList.add("h5p-dialogcards-gone"),c.forEach((function(e){var t=void 0!==e.score.value?e.score.value:"";void 0!==e.score.max&&(t="".concat(t,' / ').concat(e.score.max)),r.fields[e.field].innerHTML=t}))},e.show=function(){var r=this;this.container.classList.remove("h5p-dialogcards-gone"),setTimeout((function(){r.fields.button.focus()}),0)},e.hide=function(){this.container.classList.add("h5p-dialogcards-gone")},e.createConfirmationDialog=function(r,e){r=r||{};var t=new H5P.ConfirmationDialog({instance:r.instance,headerText:r.l10n.header,dialogText:r.l10n.body,cancelText:r.l10n.cancelLabel,confirmText:r.l10n.confirmLabel});return t.on("confirmed",(function(){e()})),t.appendTo(this.getContainer()),t},e.getContainer=function(){var r=H5P.jQuery('[data-content-id="'+self.contentId+'"].h5p-content'),e=r.parents(".h5p-container");return(0!==e.length?e.last():0!==r.length?r:H5P.jQuery(document.body)).get(0)},r}();function u(r){if(void 0===r)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return r}function h(r,e){return h=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(r,e){return r.__proto__=e,r},h(r,e)}var p=H5P.jQuery,g=H5P.JoubelUI,m=function(r){var e,t;function a(e,t,i){var s;return(s=r.call(this)||this).idCounter=a.idCounter++,s.contentId=s.id=t,s.previousState=i.previousState||{},s.contentData=i||{},s.params=p.extend({title:"",mode:"normal",description:"",next:"Next",prev:"Previous",retry:"Retry",answer:"Turn",correctAnswer:"I got it right!",incorrectAnswer:"I got it wrong",round:"Round @round",cardsLeft:"Cards left: @number",nextRound:"Proceed to round @round",startOver:"Start over",showSummary:"Next",summary:"Summary",summaryCardsRight:"Cards you got right:",summaryCardsWrong:"Cards you got wrong:",summaryCardsNotShown:"Cards in pool not shown:",summaryOverallScore:"Overall Score",summaryCardsCompleted:"Cards you have completed learning:",summaryCompletedRounds:"Completed rounds:",summaryAllDone:"Well done! You have mastered all @cards cards by getting them correct @max times!",progressText:"Card @card of @total",cardFrontLabel:"Card front",cardBackLabel:"Card back",tipButtonLabel:"Show tip",audioNotSupported:"Your browser does not support this audio",confirmStartingOver:{header:"Start over?",body:"All progress will be lost. Are you sure you want to start over?",cancelLabel:"Cancel",confirmLabel:"Start over"},dialogs:[{text:"Horse",answer:"Hest"},{text:"Cow",answer:"Ku"}],behaviour:{enableRetry:!0,disableBackwardsNavigation:!1,scaleTextNotCard:!1,randomCards:!1,maxProficiency:5,quickProgression:!1}},e),s.cards=[],s.currentCardId=0,s.round=0,s.results=s.previousState.results||[],s.attach=function(r){s.$inner=r.addClass("h5p-dialogcards"),s.params.behaviour.scaleTextNotCard&&r.addClass("h5p-text-scaling");var e={mode:s.params.mode,dialogs:s.params.dialogs,audioNotSupported:s.params.audioNotSupported,answer:s.params.answer,showSummary:s.params.showSummary,incorrectAnswer:s.params.incorrectAnswer,correctAnswer:s.params.correctAnswer,progressText:s.params.progressText,tipButtonLabel:s.params.tipButtonLabel,behaviour:{scaleTextNotCard:s.params.behaviour.scaleTextNotCard,maxProficiency:s.params.behaviour.maxProficiency,quickProgression:s.params.behaviour.quickProgression},cardPiles:s.previousState.cardPiles};s.cardManager=new c(e,s.id,{onCardTurned:s.handleCardTurned,onNextCard:s.nextCard},s.idCounter),s.createDOM(0===s.round),void 0!==s.previousState.currentCardId&&(s.gotoCard(s.previousState.currentCardId),"repetition"===s.params.mode&&s.results.length===s.cardIds.length&&s.showSummary(!0)),s.updateNavigation(),s.trigger("resize")},s.createDOM=function(r){if(s.cardIds=r&&s.previousState.cardIds?s.previousState.cardIds:s.cardManager.createSelection(),s.cardPoolSize=s.cardPoolSize||s.cardManager.getSize(),!0===r){var e=p("
"+s.params.title+"
").text().trim();s.$header=p((e?'
'+s.params.title+"
":"")+'
'+s.params.description+"
"),s.summaryScreen=new l(s.params,{nextRound:s.nextRound,retry:s.restartRepetition})}!0===r?s.$cardwrapperSet=s.initCards(s.cardIds):(s.$cardwrapperSet.detach(),s.$cardwrapperSet=s.initCards(s.cardIds),s.$cardSideAnnouncer.before(s.$cardwrapperSet)),s.$cardwrapperSet.prepend(s.summaryScreen.getDOM()),!0===r&&(s.$cardSideAnnouncer=p("
",{html:s.params.cardFrontLabel,class:"h5p-dialogcards-card-side-announcer","aria-live":"polite"}),s.$footer=s.createFooter(),s.$mainContent=p("
").append(s.$header).append(s.$cardwrapperSet).append(s.$cardSideAnnouncer).append(s.$footer).appendTo(s.$inner),s.on("reset",(function(){this.reset()})),s.on("resize",s.resize),s.round=void 0!==s.previousState.round?s.previousState.round:1)},s.createFooter=function(){var r=p("