{"version":3,"file":"app-5f8dada8.f584a1446b2fc034d810.bundle.js","mappings":"AAGA","sources":["webpack://lernplattform-admin-frontend/../common/aurelia-components/scorm-player/scorm-player.html","webpack://lernplattform-admin-frontend/../common/aurelia-components/scroll-inset/scroll-inset.html","webpack://lernplattform-admin-frontend/../common/aurelia-components/self-writing/self-writing.html","webpack://lernplattform-admin-frontend/../common/aurelia-components/skill-icon/skill-icon.html","webpack://lernplattform-admin-frontend/../common/aurelia-components/slider-standard/slider-standard.html","webpack://lernplattform-admin-frontend/../common/aurelia-components/star-rating/star-rating.html","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-chapter-progress/statistics-chapter-progress.html","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-games-details/statistics-games-details.html","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-games/statistics-games.html","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-learning/statistics-learning.html","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-overview-list-item/statistics-overview-list-item.html","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-overview-points/statistics-overview-points.html","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-overview-progress/statistics-overview-progress.html","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-sub-header/statistics-sub-header.html","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-testexam/statistics-testexam.html","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-training/statistics-training.html","webpack://lernplattform-admin-frontend/../common/aurelia-components/scorm-player/index.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/scorm-player/scorm-player.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/scroll-inset/index.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/scroll-inset/scroll-inset.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/self-writing/index.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/self-writing/self-writing.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/skill-icon/index.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/skill-icon/skill-icon.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/slider-standard/index.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/slider-standard/slider-standard.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/star-rating/index.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/star-rating/star-rating.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-chapter-progress/index.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-chapter-progress/statistics-chapter-progress.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-games-details/index.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-games-details/statistics-games-details.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-games/index.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-games/statistics-games.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-learning/index.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-learning/statistics-learning.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-overview-list-item/index.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-overview-list-item/statistics-overview-list-item.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-overview-points/index.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-overview-points/statistics-overview-points.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-overview-progress/index.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-overview-progress/statistics-overview-progress.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-sub-header/index.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-sub-header/statistics-sub-header.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-testexam/index.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-testexam/statistics-testexam.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-training/index.ts","webpack://lernplattform-admin-frontend/../common/aurelia-components/statistics-training/statistics-training.ts"],"sourcesContent":["// Module\nvar code = \"<template class=\\\"scorm-player\\\"> <iframe class=\\\"scorm-player__player\\\" title.to-view=\\\"title\\\" src.to-view=\\\"scormPlayerSrc\\\"></iframe> </template>\";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"scroll-inset\\\"> <div ref=\\\"scrollerElement\\\" class=\\\"scroll-inset__scroller\\\"> <div class=\\\"scroll-inset__spacer\\\" aria-hidden=\\\"true\\\"></div> <slot></slot> <div class=\\\"scroll-inset__spacer\\\" aria-hidden=\\\"true\\\"></div> </div> <div class=\\\"scroll-inset__top-shadow ${showTopShadow ? 'scroll-inset__top-shadow--visible' : ''}\\\" aria-hidden=\\\"true\\\"></div> <div class=\\\"scroll-inset__bottom-shadow ${showBottomShadow ? 'scroll-inset__bottom-shadow--visible' : ''}\\\" aria-hidden=\\\"true\\\"></div> </template> \";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"self-writing self-writing--${classModifier}\\\"> <div ref=\\\"slotRoot\\\" show.to-view=\\\"!animation && !thinking\\\"> <slot></slot> </div> </template> \";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"skill-icon ${ disabled ? 'skill-icon--disabled' : '' }\\\"> <safe-icon class=\\\"skill-icon__icon\\\" icon-name=\\\"Twemoji/${iconKey}\\\"></safe-icon> <div if.to-view=\\\"title\\\" class=\\\"skill-icon__tooltip\\\">${title}</div> </template>\";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"slider-standard mdc-slider ${sliderType == sliderTypeEnum.pin ? 'mdc-slider--discrete' : ''}\\\" ref=\\\"domElement\\\" tabindex=\\\"0\\\" role=\\\"slider\\\" aria-valuemin=\\\"${min}\\\" aria-valuemax=\\\"${max}\\\" aria-valuenow=\\\"${value}\\\"> <div class=\\\"mdc-slider__track-container slider-standard__track-container\\\"> <div class=\\\"mdc-slider__track slider-standard__track\\\"></div> </div> <div class=\\\"mdc-slider__thumb-container slider-standard__thumb-container\\\"> <div class=\\\"mdc-slider__pin\\\" if.bind=\\\"sliderType == sliderTypeEnum.pin\\\"> <span class=\\\"mdc-slider__pin-value-marker slider-standard__real-pin\\\" ref=\\\"realPinLabelElement\\\"></span> <span class=\\\"slider-standard__fake-pin\\\">${fakePinLabel}</span> </div> <svg class=\\\"mdc-slider__thumb\\\" width=\\\"21\\\" height=\\\"21\\\"> <circle cx=\\\"10.5\\\" cy=\\\"10.5\\\" r=\\\"7.875\\\"></circle> </svg> <div class=\\\"mdc-slider__focus-ring\\\"></div> </div> </template> \";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"star-rating\\\"> <span if.to-view=\\\"showLabel\\\" class=\\\"star-rating__label star-rating__label--score\\\">${ratingLabel}/5</span> <safe-icon repeat.for=\\\"star of 5\\\" use-as-button t=\\\"[aria-label]common.star-rating.stars\\\" t-params.to-view=\\\"{ count: (star + 1) }\\\" class=\\\"star-rating__icon ${ rateable ? 'star-rating__icon--rateable' : '' } star-rating__icon--size-${size} ${ getStarIconHover(rating, hoveredRating, $index) ? 'star-rating__icon--hover' : ''}\\\" click.trigger=\\\"setRating($index)\\\" mouseenter.trigger=\\\"handleMouseEnter($index, $event)\\\" mouseleave.trigger=\\\"handleMouseLeave($index, $event)\\\" icon-name.to-view=\\\"getStarIconName(rating, hoveredRating, $index)\\\" icon-style.to-view=\\\"{'--fill-ratio': rating % 1}\\\"></safe-icon> <span if.to-view=\\\"ratingCount != null\\\" class=\\\"star-rating__label star-rating__label--count\\\">(${getRatingCountLabel(ratingCount, ratingCountLabel)})</span> </template>\";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"statistics-chapter-progress statistics-chapter-progress--${themeColor}\\\"> <h2 class=\\\"statistics-chapter-progress__title\\\" t=\\\"common.statistics-chapter-progress.title\\\"></h2> <div class=\\\"statistics-chapter-progress__chart-wrapper\\\"> <div repeat.for=\\\"progress of progressData\\\" class=\\\"statistics-chapter-progress__chapter-progress\\\"> <donut-chart class=\\\"statistics-chapter-progress__chapter-progress-donut\\\" override-max-percentage.to-view=\\\"overrideMaxPercentage\\\" value.to-view=\\\"progress.chapterProgressPercentage\\\" color.to-view=\\\"themeColor\\\"></donut-chart> <p class=\\\"statistics-chapter-progress__chapter-progress-caption\\\">${progress.chapterTitle}</p> <p class=\\\"statistics-chapter-progress__chapter-progress-value\\\" t=\\\"common.statistics-general.points\\\" t-params.to-view=\\\"{ points: progress.pointsEarned}\\\"></p> </div> </div> </template>\";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"statistics-games-details\\\"> <div class=\\\"statistics-games-details__item statistics-games-details__item--anchor\\\" click.delegate=\\\"toggleShowDetails()\\\"> <div class=\\\"lp-site-content-small statistics-games-details__item-content\\\"> <p class=\\\"statistics-games-details__item-text ${ description ? 'statistics-games-details__item-text--with-description' : '' }\\\" id=\\\"statistics-games-details-item-text-${id}\\\">${title}</p> <p if.to-view=\\\"description\\\" class=\\\"statistics-games-details__item-description statistics-games-details__item-value--style-${description.style} statistics-games-details__item-value--color-${description.color}\\\"> <span if.to-view=\\\"description.tk\\\" t-params.to-view=\\\"description.tkParams\\\" t.to-view=\\\"description.tk\\\"></span> <span else>${description.text}</span> </p> <safe-icon if.to-view=\\\"collapsable\\\" class=\\\"statistics-games-details__item-icon\\\" icon-name.to-view=\\\"showDetails ? `System/Arrow - Up` : `System/Arrow - Down`\\\" use-as-button aria-controls=\\\"statistics-games-details-list-${id}\\\" aria-expanded.to-view=\\\"showDetails\\\"></safe-icon> <div class=\\\"statistics-games-details__item-hr statistics-games-details__item-hr--first\\\"></div> </div> </div> <div if.to-view=\\\"donutChartConfig && showDetails\\\" class=\\\"statistics-games-details__chart-wrapper lp-site-content-small\\\"> <donut-chart class=\\\"statistics-games-details__chart\\\" value.to-view=\\\"donutChartConfig.value\\\"></donut-chart> <p class=\\\"statistics-games-details__chart-label\\\"> <span if.to-view=\\\"donutChartConfig.label.tk\\\" t-params.to-view=\\\"donutChartConfig.label.tkParams\\\" t.to-view=\\\"donutChartConfig.label.tk\\\"></span> <span else>${donutChartConfig.label.text}</span> </p> </div> <ul class=\\\"statistics-games-details__list\\\" id=\\\"statistics-games-details-list-${id}\\\" role=\\\"region\\\" aria-labelledby=\\\"statistics-games-details-item-text-${id}\\\"> <li repeat.for=\\\"detail of details\\\" class=\\\"statistics-games-details__item lp-site-content-small-no-padding ${ !showDetails && collapsable ? 'statistics-games-details__item--collapsed' : '' }\\\"> <div class=\\\"lp-site-content-small statistics-games-details__item-content\\\"> <p class=\\\"statistics-games-details__item-text statistics-games-details__item-text--style-${detail.text.style} statistics-games-details__item-text--color-${detail.text.color}\\\" t.to-view=\\\"detail.text.tk\\\"></p> <p class=\\\"statistics-games-details__item-center-value statistics-games-details__item-center-value--style-${detail.centerValue.style} statistics-games-details__item-center-value--color-${detail.centerValue.color}\\\"> <span if.to-view=\\\"detail.centerValue.tk\\\" t-params.to-view=\\\"detail.centerValue.tkParams\\\" t.to-view=\\\"detail.centerValue.tk\\\"></span> <span else>${detail.centerValue.text}</span> </p> <p class=\\\"statistics-games-details__item-value statistics-games-details__item-value--style-${detail.value.style} statistics-games-details__item-value--color-${detail.value.color}\\\"> <span if.to-view=\\\"detail.value.tk\\\" t-params.to-view=\\\"detail.value.tkParams\\\" t.to-view=\\\"detail.value.tk\\\"></span> <span else>${detail.value.text}</span> </p> <div class=\\\"statistics-games-details__item-hr\\\"></div> </div> </li> </ul> </template>\";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"statistics-games\\\"> <template if.to-view=\\\"!disabledInCourse\\\"> <div class=\\\"lp-site-content-small-safe-area-right\\\"> <statistics-sub-header t=\\\"[title]common.statistics-general.games\\\" theme-color=\\\"secondary3\\\" points.to-view=\\\"pointsGames\\\" list-items.to-view=\\\"listItems\\\"></statistics-sub-header> <h1 class=\\\"statistics-games__title\\\" t=\\\"common.statistics-general.sectionDetailsTitle\\\"></h1> <div if.to-view=\\\"!duelStatistics\\\" class=\\\"statistics-games__error lp-site-content-small\\\" t=\\\"common.statistics-games.failedToLoadDuelStatistics\\\"></div> </div> <statistics-games-details if.to-view=\\\"duelStatistics\\\" t=\\\"[title]common.statistics-games.duel\\\" details.to-view=\\\"gamesDetails\\\"></statistics-games-details> <statistics-games-details t=\\\"[title]common.statistics-games.bonusPoints\\\" details.to-view=\\\"bonusDetails\\\"></statistics-games-details> </template> <div else class=\\\"statistics-games statistics-games--disabled lp-site-content\\\"> <p class=\\\"statistics-games__disabled-text\\\" t=\\\"common.course.contentDisabled\\\"></p> </div> </template>\";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"statistics-learning lp-site-content-small-safe-area-right\\\"> <statistics-sub-header t=\\\"[title]common.statistics-general.learning\\\" list-items.to-view=\\\"listItems\\\" progress.to-view=\\\"learnProgress\\\"></statistics-sub-header> <statistics-chapter-progress progress-data.to-view=\\\"progressDataLearn\\\" role=\\\"main\\\" theme-color=\\\"primary\\\"></statistics-chapter-progress> </template>\";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"lp-site-content-no-padding statistics-overview-list-item statistics-overview-list-item--${config.color}\\\"> <div class=\\\"lp-site-content statistics-overview-list-item__content\\\"> <div class=\\\"statistics-overview-list-item__icon-wrapper\\\"> <safe-icon class=\\\"statistics-overview-list-item__icon\\\" icon-name.to-view=\\\"config.iconName\\\"></safe-icon> </div> <h3 if.to-view=\\\"config.text.tk\\\" class=\\\"statistics-overview-list-item__text\\\" t.to-view=\\\"config.text.tk\\\"></h3> <h3 else class=\\\"statistics-overview-list-item__text\\\">${config.text}</h3> <div class=\\\"statistics-overview-list-item__value-wrapper\\\"> <span if.to-view=\\\"config.value.tk\\\" class=\\\"statistics-overview-list-item__value\\\" t.to-view=\\\"config.value.tk\\\" t-params.to-view=\\\"config.value.tkParams\\\"></span> <span else class=\\\"statistics-overview-list-item__value\\\">${config.value}</span> <span if.to-view=\\\"config.valueDescription.tk\\\" class=\\\"statistics-overview-list-item__value-description\\\" t.to-view=\\\"config.valueDescription.tk\\\" t-params.to-view=\\\"config.valueDescription.tkParams\\\"></span> <span if.to-view=\\\"config.valueDescription && !config.valueDescription.tk\\\" class=\\\"statistics-overview-list-item__value-description\\\">${config.valueDescription}</span> </div> <safe-icon if.to-view=\\\"config.clickCallback\\\" class=\\\"statistics-overview-list-item__nav-icon\\\" icon-name=\\\"System/Arrow - Right\\\"></safe-icon> <div class=\\\"statistics-overview-list-item__hr\\\"></div> </div> <div if.to-view=\\\"config.clickCallback\\\" class=\\\"statistics-overview-list-item__click-area\\\" use-as-button t=\\\"[aria-label]${config.text.tk}\\\" click.trigger=\\\"handleItemClick()\\\"></div> </template>\";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"statistics-overview-points\\\" aria-labelledby=\\\"statistics-overview-points-title-${id}\\\" role=\\\"list\\\"> <div class=\\\"lp-site-content-tiny\\\"> <h3 class=\\\"statistics-overview-points__title\\\" id=\\\"statistics-overview-points-title-${id}\\\" t=\\\"common.statistics-overview-points.title\\\"></h3> <points-donut-chart class=\\\"statistics-overview-points__chart\\\" points-group.to-view=\\\"pointsGroup\\\"></points-donut-chart> </div> <statistics-overview-list-item repeat.for=\\\"config of listItems\\\" role=\\\"listitem\\\" class=\\\"lp-site-content-tiny-no-padding\\\" config.to-view=\\\"config\\\"></statistics-overview-list-item> </template>\";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"statistics-overview-progress\\\" aria-labelledby=\\\"statistics-overview-progress-title-${id}\\\" role=\\\"list\\\"> <div class=\\\"lp-site-content-tiny\\\"> <h3 class=\\\"statistics-overview-progress__title\\\" id=\\\"statistics-overview-progress-title-${id}\\\" t=\\\"common.statistics-overview-progress.title\\\"></h3> <multi-donut-chart class=\\\"statistics-overview-progress__chart\\\" max-stroke-width=\\\"20\\\" values.to-view=\\\"[learnProgressPercentage, trainProgressPercentageClamped]\\\" colors.to-view=\\\"donutChartColors\\\"></multi-donut-chart> </div> <statistics-overview-list-item repeat.for=\\\"config of listItems\\\" role=\\\"listitem\\\" class=\\\"lp-site-content-tiny-no-padding\\\" config.to-view=\\\"config\\\"></statistics-overview-list-item> </template>\";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"statistics-sub-header statistics-sub-header--${themeColor} lp-site-content-small-safe-area-right\\\" aria-labelledby=\\\"statistics-sub-header-title\\\" role=\\\"banner\\\"> <h1 class=\\\"statistics-sub-header__title\\\" id=\\\"statistics-sub-header-title\\\">${title}</h1> <rounded-progress-bar if.to-view=\\\"progress != null\\\" class=\\\"statistics-sub-header__bar\\\" progress-color.to-view=\\\"themeColor\\\" progress.to-view=\\\"progress\\\"></rounded-progress-bar> <h2 else class=\\\"statistics-sub-header__points ${!listItems.length ? 'statistics-sub-header__points--only' : ''}\\\" t=\\\"common.statistics-general.pointsFull\\\" t-params.to-view=\\\"{count: points}\\\"></h2> <ul class=\\\"statistics-sub-header__list\\\"> <li repeat.for=\\\"listItem of listItems\\\" class=\\\"statistics-sub-header__list-item\\\"> <h3 class=\\\"statistics-sub-header__list-item-title\\\" t.to-view=\\\"listItem.text.tk\\\"></h3> <div class=\\\"statistics-sub-header__list-item-value-wrapper\\\"> <span if.to-view=\\\"listItem.value.tk\\\" class=\\\"statistics-sub-header__list-item-value\\\" t.to-view=\\\"listItem.value.tk\\\" t-params.to-view=\\\"listItem.value.tkParams\\\"></span> <span else class=\\\"statistics-sub-header__list-item-value\\\">${listItem.value}</span> <span if.to-view=\\\"listItem.valueDescription\\\" class=\\\"statistics-sub-header__list-item-description\\\" t.to-view=\\\"listItem.valueDescription.tk\\\" t-params.to-view=\\\"listItem.valueDescription.tkParams\\\"></span> </div> <div class=\\\"statistics-sub-header__list-item-hr\\\"></div> </li> </ul> </template>\";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"statistics-testexam\\\"> <div if.to-view=\\\"previousExamAttemptsWithConfirmedStatus.length === 0\\\" class=\\\"statistics-testexam__empty lp-site-content-small-no-padding\\\"> <img class=\\\"statistics-testexam__placeholder-img\\\" t=\\\"[alt]common.statistics-testexam.noPreviousResults\\\" src.to-view=\\\"placeholderImage\\\"> <span class=\\\"statistics-testexam__empty-text\\\" t=\\\"common.statistics-testexam.noPreviousResults\\\"></span> </div> <div else class=\\\"lp-site-content-small-no-padding\\\"> <div if.to-view=\\\"showHeader\\\" class=\\\"lp-site-content-small-safe-area-right\\\"> <statistics-sub-header t=\\\"[title]common.statistics-general.testexam\\\" theme-color=\\\"testexam\\\" points.to-view=\\\"pointsGroup.testexam\\\" list-items.to-view=\\\"listItems\\\"></statistics-sub-header> <h1 class=\\\"statistics-testexam__title\\\" t=\\\"common.statistics-testexam.sectionDetailsTitle\\\"></h1> </div> <section if.to-view=\\\"previousExamAttemptsWithConfirmedStatus.length\\\" class=\\\"lp-site-content-small\\\"> <h2 class=\\\"statistics-testexam__headline\\\" t.to-view=\\\"chartTitleTk\\\"></h2> <css-bar-chart bar-chart-config.to-view=\\\"barChartConfig\\\"></css-bar-chart> <div class=\\\"statistics-testexam__legend\\\"> <div if.to-view=\\\"hasSingleExams\\\" class=\\\"statistics-testexam__legend-text\\\" t=\\\"common.statistics-testexam.legendExamSingle\\\"></div> <div if.to-view=\\\"hasComboExams\\\" class=\\\"statistics-testexam__legend-text statistics-testexam__legend-text--combo\\\" t=\\\"common.statistics-testexam.legendExamCombo\\\"></div> </div> </section> <div if.to-view=\\\"previousExamAttemptsWithConfirmedStatus.length > 4\\\" class=\\\"statistics-testexam__toggle lp-site-content-small\\\"> <h3 class=\\\"statistics-testexam__toggle-text\\\" id=\\\"statistics-testexam-toggle-text\\\" t=\\\"common.statistics-testexam.showPreviousAttempts\\\"></h3> <button-lightswitch class=\\\"statistics-testexam__toggle-button\\\" label-id=\\\"statistics-testexam-toggle-text\\\" click.trigger=\\\"toggleExamlistView()\\\" value.to-view=\\\"showPreviousExamAttempts\\\"></button-lightswitch> </div> </div> <testexam-previous-results if.to-view=\\\"previousExamAttemptsWithConfirmedStatus.length\\\" course-id.to-view=\\\"courseId\\\" student-id.to-view=\\\"studentId\\\" previous-exams.to-view=\\\"displayedPreviousExamAttempts\\\" allow-result-detail-view.to-view=\\\"allowResultDetailView\\\" open-result-as-page.to-view=\\\"openResultAsPage\\\" route-to-overview.to-view=\\\"routeToOverview\\\"></testexam-previous-results> </template>\";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"statistics-training lp-site-content-small-safe-area-right\\\"> <statistics-sub-header t=\\\"[title]common.statistics-general.training\\\" list-items.to-view=\\\"listItems\\\" theme-color=\\\"secondary1\\\" progress.to-view=\\\"trainProgressPercentageClamped\\\"></statistics-sub-header> <statistics-chapter-progress progress-data.to-view=\\\"progressDataTrain\\\" override-max-percentage.to-view=\\\"true\\\" role=\\\"main\\\" theme-color=\\\"secondary\\\"></statistics-chapter-progress> </template>\";\n// Exports\nexport default code;","import { PLATFORM, FrameworkConfiguration } from 'aurelia-framework';\n\nexport function configure(config: FrameworkConfiguration): void {\n  config.globalResources(PLATFORM.moduleName('common/aurelia-components/scorm-player/scorm-player'));\n}\n","import { bindable, computedFrom, PLATFORM, useView } from 'aurelia-framework';\nimport { Config } from 'common/fe-config/config';\n\n@useView(PLATFORM.moduleName('./scorm-player.html'))\nexport class ScormPlayer {\n  @bindable() title: string | null = null;\n  @bindable() scormUrl: string | null = null;\n\n  @computedFrom('scormUrl')\n  public get scormPlayerSrc(): string {\n    return `${Config().scorm.playerUrl}?sco_path=${this.scormUrl}`;\n  }\n}\n","import { FrameworkConfiguration, PLATFORM } from 'aurelia-framework';\n\nexport function configure(config: FrameworkConfiguration): void {\n  config.globalResources(PLATFORM.moduleName('common/aurelia-components/scroll-inset/scroll-inset'));\n}\n","import { autoinject, bindable, PLATFORM, useView } from 'aurelia-framework';\nimport { SubscriptionManager, SubscriptionManagerService } from 'common/aurelia-services/SubscriptionManagerService';\nimport { assertNotNullOrUndefined } from 'common/utils/assert';\n\n@autoinject()\n@useView(PLATFORM.moduleName('./scroll-inset.html'))\nexport class ScrollInset {\n  @bindable() public showShadows: boolean = true;\n  private showTopShadow = false;\n  private showBottomShadow = false;\n  private lastKnownScrollPosition = 0;\n\n  private scrollerElement: HTMLDivElement | null = null;\n  private subscriptionManager: SubscriptionManager;\n\n  constructor(\n    subscriptionManagerService: SubscriptionManagerService,\n  ) {\n    this.subscriptionManager = subscriptionManagerService.createSubscriptionManager();\n  }\n\n  protected attached(): void {\n    assertNotNullOrUndefined(this.scrollerElement, 'scrollerElement cannot be null or undefined');\n    const scroller = this.scrollerElement;\n    if(!this.showShadows) return;\n    this.updateShadows(scroller);\n\n    this.subscriptionManager.subscribeToDomEvent(scroller, 'scroll', () => {\n      this.updateShadows(scroller);\n    });\n  }\n\n  protected detached(): void {\n    this.subscriptionManager.disposeSubscriptions();\n  }\n\n  private updateShadows(scroller: HTMLDivElement): void {\n    const { scrollTop, scrollHeight, offsetHeight } = scroller;\n    const visibleAfterOffset = 24;\n    this.showTopShadow = scrollTop > visibleAfterOffset;\n    this.showBottomShadow = offsetHeight === scrollHeight || Math.ceil(scrollTop) < (scrollHeight - offsetHeight - visibleAfterOffset);\n  }\n}\n","import { PLATFORM, FrameworkConfiguration } from 'aurelia-framework';\n\nexport function configure(config: FrameworkConfiguration): void {\n  config.globalResources(PLATFORM.moduleName('common/aurelia-components/self-writing/self-writing'));\n}\n","import { autoinject, bindable, computedFrom, PLATFORM, useView } from 'aurelia-framework';\nimport { AnimationUtils } from 'common/utils/AnimationUtils';\nimport { DomUtils } from 'common/utils/DomUtils';\n\n/**\n * Self-writing text.\n * Text can be provided with the 'write' bindable, either as text or a HTML-Node.\n * Alternatively, the slot can be used to provide HTML.\n * While the animation is active, all JS is stripped out.\n * \n * Use the \"thinking\" bindable to keep displaying a caret even if the writing has finished\n * Use the \"disabled\" bindable to skip the animation\n * Use the \"cps\" bindable to change how fast the animation should be\n * \n * @event animation-finished\n */\n@useView(PLATFORM.moduleName('./self-writing.html'))\n@autoinject()\nexport class SelfWriting {\n  private static readonly CARET_ATTRIBUTE = 'self-writing-caret';\n  private static readonly HIDE_CLASS = 'aurelia-hide';\n\n  /** text or HTML to write */\n  @bindable() write: string | HTMLElement | null = '';\n\n  /** characters per second */\n  @bindable() cps: number = 50;\n\n  /** if false, the text is not animated and changes instantly */\n  @bindable() disabled = false;\n\n  /** makes the caret blink ;) */\n  @bindable() thinking = false;\n\n  private element: HTMLElement;\n\n  // Animation\n  private animation: { cancel: () => void } | undefined = undefined;\n  private writtenRootNode: Node | null = null;\n  private referenceRootNode: Node | null = null;\n  private elementWithCaret: Element | null = null;\n\n  // Slot stuff\n  private slotRootObserver: MutationObserver;\n  private slotRoot: HTMLElement | null = null;\n  private slotContents: Node | null = null;\n\n  constructor(\n    element: Element,\n  ) {\n    this.element = element as HTMLElement;\n\n    // Observe the slot and update contents if not disabled\n    this.slotRootObserver = new MutationObserver(() => {\n      if(this.disabled) return;\n      this.updateSlotContents();\n      this.handleWritingParametersChanged();\n    });\n  }\n\n  protected attached(): void {\n    if(this.slotRoot) {\n      this.slotRootObserver.observe(this.slotRoot, {\n        subtree: true,\n        childList: true,\n        characterData: true,\n      });\n    }\n\n    this.updateSlotContents();\n    this.handleWritingParametersChanged();\n  }\n\n  protected detached(): void {\n    this.slotRootObserver.disconnect();\n    this.stopAnimation();\n  }\n\n  private writeChanged(): void {\n    this.handleWritingParametersChanged();\n  }\n\n  private thinkingChanged(): void {\n    // 'thinking' mode displays the animation version, so it needs to be regenerated, if 'disabled' is true\n    if(this.thinking && this.disabled) {\n      this.updateSlotContents();\n      this.handleWritingParametersChanged();\n    }\n\n    this.updateWrittenNodeVisibility();\n  }\n\n  private disabledChanged(): void {\n    if(!this.disabled) this.updateSlotContents();\n  }\n\n  @computedFrom('animation', 'thinking')\n  private get classModifier(): string {\n    if(this.animation) return 'writing';\n    if(this.thinking) return 'thinking';\n    return 'done';\n  }\n\n  private updateSlotContents(): void {\n    if(!this.slotRoot) return;\n\n    // If there is no text in the slot, we consider it empty\n    if(this.slotRoot?.innerText.trim()) {\n      const clone = this.slotRoot.cloneNode(true) as HTMLElement;\n      clone.classList.remove(SelfWriting.HIDE_CLASS);\n      this.slotContents = clone;\n    } else {\n      this.slotContents = null;\n    }\n  }\n\n  private handleWritingParametersChanged(): void {\n    if(!this.element.isConnected) return;\n\n    this.startAnimation();\n  }\n\n  private setWrittenRootNode(node: Node): void {\n    this.writtenRootNode?.parentNode?.removeChild(this.writtenRootNode);\n    this.writtenRootNode = node;\n    this.element.append(node);\n  }\n\n  private updateWrittenNodeVisibility(): void {\n    if(!(this.writtenRootNode instanceof HTMLElement)) return;\n\n    this.writtenRootNode.classList.toggle(SelfWriting.HIDE_CLASS, !!this.slotContents && !this.animation && !this.thinking);\n  }\n\n  private async startAnimation(): Promise<void> {\n    this.stopAnimation();\n\n    // setup\n    const toWrite = this.slotContents ?? this.write;\n    this.referenceRootNode = toWrite instanceof Node\n      ? toWrite.cloneNode(true)\n      : document.createTextNode(toWrite?.trim() ?? '');\n\n    this.setWrittenRootNode(this.cloneEmpty(this.referenceRootNode));\n\n    if(!this.writtenRootNode) return;\n\n    // if disabled, still simulate the animation, since it also processes the tree to render\n    let stepsToDo = this.disabled ? Number.POSITIVE_INFINITY : 0;\n    let currentState: NodeTraversalState | null = {\n      writingNode: this.writtenRootNode,\n      referenceNode: this.referenceRootNode,\n    };\n\n    // helper functions\n    const continueWithChild = (childData: NodeTraversalState): void => {\n      currentState = childData;\n    };\n\n    const continueWithParent = (): void => {\n      currentState = currentState?.referenceNode.parentNode && currentState?.writingNode.parentNode ? {\n        referenceNode: currentState.referenceNode.parentNode,\n        writingNode: currentState.writingNode.parentNode,\n      } : null;\n    };\n\n    // start the animation\n    this.animation = AnimationUtils.setAnimationFrameInterval((elapsedMs, deltaMs) => {\n      stepsToDo += deltaMs * this.cps / 1000;\n      if(stepsToDo < 1) return;\n\n      while(stepsToDo >= 1) {\n        // we're done if the last state was cleared\n        if(!currentState) {\n          DomUtils.fireEvent(this.element, {\n            name: 'animation-finished',\n            bubbles: false,\n          });\n          this.stopAnimation();\n          break;\n        }\n\n        const { referenceNode, writingNode } = currentState;\n        // handle text nodes\n        if(referenceNode instanceof Text && writingNode instanceof Text) {\n          if(writingNode.nodeValue?.trim()) this.setElementWithCaret(writingNode.parentElement);\n          const { finished, stepsTaken } = this.continueProcessTextNode(referenceNode, writingNode, stepsToDo);\n\n          if(finished) continueWithParent();\n\n          stepsToDo -= stepsTaken;\n\n          // traverse children of element nodes\n        } else if(referenceNode instanceof Element && writingNode instanceof Element) {\n          const childData = this.processElementNode(referenceNode, writingNode);\n\n          if(childData) continueWithChild(childData);\n          else continueWithParent();\n\n        } else {\n          console.error('doms unexpectedly don\\'t match');\n          this.stopAnimation();\n          break;\n        }\n      }\n    });\n\n    this.updateWrittenNodeVisibility();\n  }\n\n  private continueProcessTextNode(referenceNode: Text, writingNode: Text, stepsAvailable: number): { finished: boolean; stepsTaken: number } {\n    const referenceText = referenceNode.nodeValue ?? '';\n    const writtenText = writingNode.nodeValue ?? '';\n    const steps = Math.min(Math.floor(stepsAvailable), referenceText.length - writtenText.length);\n    writingNode.nodeValue = writtenText + referenceText.slice(writtenText.length, writtenText.length + steps);\n\n    return {\n      finished: writingNode.nodeValue.length >= referenceText.length,\n      stepsTaken: steps,\n    };\n  }\n\n  private processElementNode(referenceNode: Element, writingNode: Element): NodeTraversalState | null {\n    // strip away all script and style tags, and non-text/element nodes, such as comment nodes\n    // continue with the first one that we can work with\n    let nextReferenceChild: ChildNode | undefined;\n    for(let i = 0; i < referenceNode.childNodes.length; i++) {\n      nextReferenceChild = referenceNode.childNodes.item(writingNode.childNodes.length);\n      if(nextReferenceChild && (\n        ['script', 'style'].includes(nextReferenceChild.nodeName.toLocaleLowerCase())\n        || (!(nextReferenceChild instanceof Element) && !(nextReferenceChild instanceof Text))\n      )) {\n        nextReferenceChild.remove();\n        continue;\n      }\n\n      if(nextReferenceChild) break;\n    }\n\n    if(!nextReferenceChild) {\n      return null;\n    }\n\n    // trim text content, to avoid spending time animating whitespace\n    if(nextReferenceChild instanceof Text) {\n      nextReferenceChild.nodeValue = nextReferenceChild.nodeValue?.replace(/\\s+/g, ' ') ?? '';\n    }\n\n    // strip all \"scripty\" attributes\n    if(nextReferenceChild instanceof Element) {\n      for(const attributeName of nextReferenceChild.getAttributeNames()) {\n        if(attributeName.toLocaleLowerCase().startsWith('on')\n          || nextReferenceChild.getAttribute(attributeName)?.toLocaleLowerCase().includes('javascript')\n        ) {\n          nextReferenceChild.removeAttribute(attributeName);\n        }\n      }\n    }\n\n    const nextWritingChild = this.cloneEmpty(nextReferenceChild);\n\n    writingNode.appendChild(nextWritingChild);\n\n    return {\n      referenceNode: nextReferenceChild,\n      writingNode: nextWritingChild,\n    };\n  }\n\n  private setElementWithCaret(element: Element | null): void {\n    if(this.elementWithCaret === element) return;\n    this.elementWithCaret?.removeAttribute(SelfWriting.CARET_ATTRIBUTE);\n    element?.setAttribute(SelfWriting.CARET_ATTRIBUTE, '');\n    this.elementWithCaret = element;\n  }\n\n  // currently unused, but might be useful\n  private findLastText(node: Node): Node | null {\n    if(node instanceof Text && node.nodeValue?.trim()) return node;\n\n    const children = Array.from(node.childNodes);\n    for(let i = children.length - 1; i >= 0; i--) {\n      const found = this.findLastText(children[i]);\n      if(found) return found;\n    }\n\n    return null;\n  }\n\n  private cloneEmpty(nextChild: Node): Node {\n    return nextChild instanceof Text\n      ? document.createTextNode('')\n      : nextChild.cloneNode(false);\n  }\n\n  private stopAnimation(): void {\n    this.animation?.cancel();\n    this.animation = undefined;\n    this.updateWrittenNodeVisibility();\n  }\n}\n\ntype NodeTraversalState = {\n  referenceNode: Node;\n  writingNode: Node;\n};\n","import { PLATFORM, FrameworkConfiguration } from 'aurelia-framework';\n\nexport function configure(config: FrameworkConfiguration): void {\n  config.globalResources(PLATFORM.moduleName('common/aurelia-components/skill-icon/skill-icon'));\n}\n","import { bindable, PLATFORM, useView } from 'aurelia-framework';\n\n@useView(PLATFORM.moduleName('./skill-icon.html'))\nexport class SkillIcon {\n  @bindable() iconKey: string | null = null;\n  @bindable() title: string | null = null;\n  @bindable() disabled: boolean = false;\n}","import { PLATFORM, FrameworkConfiguration } from 'aurelia-framework';\n\nexport function configure(config: FrameworkConfiguration): void {\n  config.globalResources(PLATFORM.moduleName('common/aurelia-components/slider-standard/slider-standard'));\n}\n","import { MDCSlider } from '@material/slider';\nimport { autoinject, bindable, PLATFORM, TaskQueue, useView } from 'aurelia-framework';\nimport { SubscriptionManager, SubscriptionManagerService } from 'common/aurelia-services/SubscriptionManagerService';\nimport { assertNotNullOrUndefined } from 'common/utils/assert';\nimport { DomUtils } from 'common/utils/DomUtils';\nimport { MathUtils } from 'common/utils/MathUtils';\n\nenum SliderType {\n  standard = 'standard',\n  pin = 'pin'\n}\n\n/**\n * @event {SliderStandardValueChangedEvent} value-changed\n */\n@useView(PLATFORM.moduleName('./slider-standard.html'))\n@autoinject()\nexport class SliderStandard {\n  @bindable() public value = 0;\n  @bindable() public min = 0;\n  @bindable() public max = 100;\n  @bindable() public sliderType: SliderType | null = null;\n  /**\n   * entries in this dictionary are replaced on the slider's pin\n   */\n  @bindable() public overrideLabels: Record<number, string> = {};\n  private domElement: HTMLElement | null = null;\n  private slider: MDCSlider | null = null;\n  private taskQueue: TaskQueue;\n  private subscriptionManager: SubscriptionManager;\n  private sliderTypeEnum = SliderType;\n\n  private fakePinLabel: string | null = null;\n  private realPinLabelElement: HTMLElement | null = null;\n\n  constructor(taskQueue: TaskQueue, subscriptionManagerService: SubscriptionManagerService) {\n    this.taskQueue = taskQueue;\n    this.subscriptionManager = subscriptionManagerService.createSubscriptionManager();\n  }\n\n  public attached(): void {\n    assertNotNullOrUndefined(this.domElement, 'forgot to ref domElement');\n    assertNotNullOrUndefined(this.realPinLabelElement, 'pin element not found');\n\n    this.slider = new MDCSlider(this.domElement);\n\n    this.subscriptionManager.subscribeToDomEvent(this.domElement, 'MDCSlider:change', () => {\n      if(this.slider && this.domElement) {\n        this.value = this.slider.value;\n\n        DomUtils.fireEvent<SliderStandardValueChangedEvent['detail']>(this.domElement, {\n          name: 'value-changed',\n          detail: {\n            value: this.value,\n          },\n        });\n      }\n    });\n\n    this.subscriptionManager.subscribeToDomMutation(this.realPinLabelElement, () => {\n      if(this.realPinLabelElement) {\n        this.fakePinLabel = (this.realPinLabelElement.textContent && this.overrideLabels[Number.parseInt(this.realPinLabelElement.textContent, 10)])\n          || this.realPinLabelElement.textContent;\n      }\n    }, { childList: true });\n\n    this.subscriptionManager.subscribeToElementResize(this.domElement, () => {\n      if(this.slider) {\n        this.slider.layout();\n      }\n    });\n  }\n\n  protected detached(): void {\n    this.subscriptionManager.disposeSubscriptions();\n  }\n\n  private valueChanged(): void {\n    if(this.slider) {\n      this.slider.value = MathUtils.clamp(this.value, this.min, this.max);\n    }\n  }\n\n  private maxChanged(): void {\n    if(this.slider) {\n      this.slider.step = ((this.max + 1) / 100);\n    }\n  }\n}\n\nexport type SliderStandardValueChangedEvent = Event & { detail: { value: number } };","import { PLATFORM, FrameworkConfiguration } from 'aurelia-framework';\n\nexport function configure(config: FrameworkConfiguration): void {\n  config.globalResources(PLATFORM.moduleName('common/aurelia-components/star-rating/star-rating'));\n}\n","import { autoinject, bindable, computedFrom, PLATFORM, useView } from 'aurelia-framework';\nimport { DomUtils } from 'common/utils/DomUtils';\nimport { MathUtils } from 'common/utils/MathUtils';\nimport { StringUtils } from 'common/utils/StringUtils';\n\nexport enum StarRatingSize {\n  Large = 'large',\n  Medium = 'medium',\n  Small = 'small'\n}\n\n@autoinject\n@useView(PLATFORM.moduleName('./star-rating.html'))\nexport class StarRating {\n  @bindable() public rating = 1;\n  @bindable() public rateable = false;\n  @bindable() public size: StarRatingSize = StarRatingSize.Medium;\n  @bindable() public showLabel = false;\n  @bindable() public ratingCount: number | null = null;\n  @bindable() public ratingCountLabel: string | null = null;\n\n  private domElement: HTMLElement;\n\n  private hoveredRating: number | null = null;\n\n  constructor(element: Element) {\n    this.domElement = element as HTMLElement;\n  }\n\n  private setRating(index: number): void {\n    if(!this.rateable) return;\n    this.rating = index + 1;\n  }\n\n  private ratingChanged(): void {\n    DomUtils.fireEvent<IRatingChangedEventDetail>(this.domElement, {\n      name: 'rating-changed',\n      detail: {\n        value: this.rating,\n      },\n    });\n  }\n\n  @computedFrom('rating', 'ratingCount')\n  private get ratingLabel(): string | number {\n    if(this.ratingCount === 0) return '-';\n    return parseFloat(MathUtils.clamp(this.rating, 0, 5).toFixed(1));\n  }\n\n  private getStarIconName(rating: number, hoveredRating: number, starIndex: number): string {\n    const ratingToUse = hoveredRating ?? rating;\n    if(ratingToUse <= starIndex) return 'System/Star';\n    if(ratingToUse < starIndex + 1) return 'System/Star Half Filled';\n    return 'System/Star Filled';\n  }\n\n  private getStarIconHover(rating: number, hoveredRating: number, starIndex: number): boolean {\n    if(!hoveredRating) return false;\n    return rating <= starIndex;\n  }\n\n  private handleMouseEnter(starIndex: number): void {\n    if(!this.rateable) return;\n    this.hoveredRating = starIndex + 1;\n  }\n\n  private handleMouseLeave(starIndex: number): void {\n    if(this.hoveredRating === starIndex + 1) {\n      this.hoveredRating = null;\n    }\n  }\n\n  private getRatingCountLabel(ratingCount?: number, ratingCountLabel?: string): string {\n    return `${StringUtils.formatNumberGrouped(ratingCount ?? 0)}${ratingCountLabel ? ` ${ratingCountLabel}` : ''}`;\n  }\n}\n\nexport interface IRatingChangedEventDetail {\n  value: number;\n}\n","import { PLATFORM, FrameworkConfiguration } from 'aurelia-framework';\n\nexport function configure(config: FrameworkConfiguration): void {\n  config.globalResources(PLATFORM.moduleName('common/aurelia-components/statistics-chapter-progress/statistics-chapter-progress'));\n}\n","import { bindable, PLATFORM, useView } from 'aurelia-framework';\nimport { Color } from '../donut-chart/donut-chart';\n\n@useView(PLATFORM.moduleName('./statistics-chapter-progress.html'))\nexport class StatisticsChapterProgress {\n  @bindable() public progressData: IProgressData[] = [];\n  @bindable() public themeColor: Color = Color.Primary;\n  @bindable() public overrideMaxPercentage: boolean = false;\n}\n\nexport interface IProgressData {\n  chapterId: number;\n  chapterTitle: string;\n  chapterProgressPercentage: number;\n  pointsEarned: number;\n}\n","import { PLATFORM, FrameworkConfiguration } from 'aurelia-framework';\n\nexport function configure(config: FrameworkConfiguration): void {\n  config.globalResources(PLATFORM.moduleName('common/aurelia-components/statistics-games-details/statistics-games-details'));\n}\n","import { bindable, PLATFORM, useView } from 'aurelia-framework';\nimport { IdGeneratorService } from 'common/aurelia-services/IdGeneratorService';\nimport { IText } from 'common/interfaces/translations.interface';\n\nexport enum DetailsColor {\n  Secondary3 = 'secondary3',\n  Dismiss = 'dismiss',\n  Confirm = 'confirm',\n  YellowDark = 'yellow-dark'\n}\n\nexport enum DetailsTextStyle {\n  Uppercase = 'uppercase',\n  Emphasized = 'emphasized',\n}\n\n@useView(PLATFORM.moduleName('./statistics-games-details.html'))\nexport class StatisticsGamesDetails {\n  @bindable() public title: string | null = null;\n  @bindable() public description: IDetailsText | null = null;\n  @bindable() public details: IDetailsConfig[] = [];\n  @bindable() public donutChartConfig: IDetailsDonutChartConfig | null = null;\n  @bindable() public showDetails = true;\n  @bindable() public collapsable = true;\n  private id: string;\n\n  constructor(idGenerator: IdGeneratorService) {\n    this.id = idGenerator.getId().toString();\n  }\n\n  private toggleShowDetails(): void {\n    this.showDetails = !this.showDetails;\n  }\n}\n\nexport interface IDetailsText extends IText {\n  color?: DetailsColor;\n  style?: DetailsTextStyle;\n  text?: string;\n}\n\nexport interface IDetailsDonutChartConfig {\n  label: IDetailsText;\n  total: number;\n  value: number;\n}\n\nexport interface IDetailsConfig {\n  text: IDetailsText;\n  value: IDetailsText;\n  centerValue?: IDetailsText;\n}\n","import { PLATFORM, FrameworkConfiguration } from 'aurelia-framework';\n\nexport function configure(config: FrameworkConfiguration): void {\n  config.globalResources(PLATFORM.moduleName('common/aurelia-components/statistics-games/statistics-games'));\n}\n","import { autoinject, bindable, computedFrom, PLATFORM, useView } from 'aurelia-framework';\nimport { ICoursePointsGroupedDto } from 'common/dto/course/points/course.points.interface';\nimport { IQuizDuelStatisticsDto } from 'common/dto/course/quiz/quiz.response';\nimport { StringUtils } from 'common/utils/StringUtils';\nimport { DetailsColor, IDetailsConfig } from '../statistics-games-details/statistics-games-details';\nimport { IListItemConfig } from '../statistics-sub-header/statistics-sub-header';\n\n@autoinject()\n@useView(PLATFORM.moduleName('./statistics-games.html'))\nexport class StatisticsGames {\n  @bindable() public duelStatistics: IQuizDuelStatisticsDto | null = null;\n  @bindable() public pointsGroup: ICoursePointsGroupedDto | null = null;\n  @bindable() public disabledInCourse = false;\n\n  @computedFrom('pointsGroup')\n  private get pointsGames(): number {\n    if(!this.pointsGroup) return 0;\n    return this.pointsGroup.activityStreak + this.pointsGroup.duel + this.pointsGroup.lecture;\n  }\n\n  @computedFrom('pointsGroup', 'learnProgress')\n  private get listItems(): IListItemConfig[] {\n    return [\n      {\n        text: { tk: 'common.statistics-games.duel' },\n        value: { tk: 'common.statistics-general.points', tkParams: { points: this.pointsGroup?.duel ?? 0 } },\n      },\n      {\n        text: { tk: 'common.statistics-games.bonusPoints' },\n        value: { tk: 'common.statistics-general.points', tkParams: { points: this.pointsGroup?.activityStreak ?? 0 } },\n      },\n    ];\n  }\n\n  @computedFrom('duelStatistics')\n  private get gamesDetails(): IDetailsConfig[] {\n    return [\n      {\n        text: { tk: 'common.statistics-general.gamePoints' },\n        value: {\n          tk: 'common.statistics-games.points',\n          tkParams: {\n            count: this.duelStatistics?.totalPoints ?? 0,\n          },\n          color: DetailsColor.Secondary3,\n        },\n      },\n      {\n        text: { tk: 'common.statistics-games.duelGamesPlayed' },\n        value: { text: `${this.duelStatistics?.totalDuels ?? 0}` },\n      },\n      {\n        text: { tk: 'common.statistics-games.duelGamesWon' },\n        value: {\n          text: `${this.duelStatistics?.duelsWon ?? 0}`,\n        },\n      },\n      {\n        text: { tk: 'common.statistics-games.duelCorrectAnswerCount' },\n        value: {\n          text: `${StringUtils.formatNumberGrouped(this.duelStatistics?.correctAnswers ?? 0)}`,\n          color: DetailsColor.Confirm,\n        },\n      },\n      {\n        text: { tk: 'common.statistics-games.duelWrongAnswerCount' },\n        value: {\n          text: `${StringUtils.formatNumberGrouped((this.duelStatistics?.totalAnswers ?? 0) - (this.duelStatistics?.correctAnswers ?? 0))}`,\n          color: DetailsColor.Dismiss,\n        },\n      },\n      {\n        text: { tk: 'common.statistics-games.duelAverageAnswerTime' },\n        value: this.duelStatistics?.averageAnswerTime\n          ? { tk: 'common.statistics-games.duelAverageAnswerTimeSeconds', tkParams: { time: this.duelStatistics.averageAnswerTime } }\n          : { text: '-' },\n      },\n    ];\n  }\n\n  @computedFrom('pointsGroup')\n  private get bonusDetails(): IDetailsConfig[] {\n    return [\n      {\n        text: { tk: 'common.statistics-games.activityStreak' },\n        value: {\n          tk: 'common.statistics-games.points',\n          tkParams: { count: this.pointsGroup?.activityStreak ?? 0 },\n          color: DetailsColor.Secondary3,\n        },\n      },\n    ];\n  }\n}\n","import { PLATFORM, FrameworkConfiguration } from 'aurelia-framework';\n\nexport function configure(config: FrameworkConfiguration): void {\n  config.globalResources(PLATFORM.moduleName('common/aurelia-components/statistics-learning/statistics-learning'));\n}\n","import { bindable, computedFrom, PLATFORM, useView } from 'aurelia-framework';\nimport { IListItemConfig } from 'common/aurelia-components/statistics-sub-header/statistics-sub-header';\nimport { COURSE_TOTAL_LEARN_POINTS } from 'common/constants/course.constants';\nimport { ICoursePointsGroupedDto } from 'common/dto/course/points/course.points.interface';\nimport { ITotalActivityTime } from 'common/dto/course/progress/course.progress.interface';\nimport { MathUtils } from 'common/utils/MathUtils';\nimport { TimeUtils } from 'common/utils/TimeUtils';\nimport { IProgressData } from '../statistics-chapter-progress/statistics-chapter-progress';\n\n@useView(PLATFORM.moduleName('./statistics-learning.html'))\nexport class StatisticsLearning {\n  @bindable() public progressDataLearn: IProgressData[] | null = null;\n  @bindable() public learnProgress: number | null = null;\n  @bindable() public pointsGroup: ICoursePointsGroupedDto | null = null;\n  @bindable() public totalActivityTime: ITotalActivityTime | null = null;\n\n  @computedFrom('pointsGroup', 'learnProgress', 'totalActivityTime')\n  private get listItems(): IListItemConfig[] {\n    return [\n      {\n        text: { tk: 'common.statistics-general.progressTotal' },\n        value: `${MathUtils.roundProgress(this.learnProgress ?? 0)}%`,\n      },\n      {\n        text: { tk: 'common.statistics-general.pointsTotal' },\n        value: {\n          tk: 'common.statistics-general.points',\n          tkParams: { points: this.pointsGroup?.learning ?? 0 },\n        },\n        valueDescription: { tk: 'common.statistics-general.xOfYPoints', tkParams: { points: COURSE_TOTAL_LEARN_POINTS } },\n      },\n      {\n        text: { tk: 'common.statistics-general.timeLearnedTotal' },\n        value: TimeUtils.getDurationFormatted((this.totalActivityTime?.secondsLearned ?? 0)),\n      },\n    ];\n  }\n}\n","import { PLATFORM, FrameworkConfiguration } from 'aurelia-framework';\n\nexport function configure(config: FrameworkConfiguration): void {\n  config.globalResources(PLATFORM.moduleName('common/aurelia-components/statistics-overview-list-item/statistics-overview-list-item'));\n}\n","import { bindable, PLATFORM, useView } from 'aurelia-framework';\nimport { ThemeColorType } from 'common/aurelia-classes/SiteThemer';\nimport { IText } from 'common/interfaces/translations.interface';\n\n@useView(PLATFORM.moduleName('./statistics-overview-list-item.html'))\nexport class StatisticsOverviewListItem {\n  @bindable() public config: IStatisticsOverviewListItemConfig | null = null;\n\n  private handleItemClick(): void {\n    this.config?.clickCallback?.();\n  }\n}\n\nexport interface IStatisticsOverviewListItemConfig {\n  iconName: string | null;\n  color: ThemeColorType;\n  text: IText | string;\n  value: IText | string;\n  valueDescription?: IText | string;\n  clickCallback?: () => void;\n}\n","import { PLATFORM, FrameworkConfiguration } from 'aurelia-framework';\n\nexport function configure(config: FrameworkConfiguration): void {\n  config.globalResources(PLATFORM.moduleName('common/aurelia-components/statistics-overview-points/statistics-overview-points'));\n}\n","import { bindable, computedFrom, PLATFORM, useView } from 'aurelia-framework';\nimport { ThemeColorType } from 'common/aurelia-classes/SiteThemer';\nimport { IdGeneratorService } from 'common/aurelia-services/IdGeneratorService';\nimport { COURSE_TARGET_TRAINING_POINTS, COURSE_TOTAL_LEARN_POINTS } from 'common/constants/course.constants';\nimport { ICoursePointsGroupedDto } from 'common/dto/course/points/course.points.interface';\nimport { MathUtils } from 'common/utils/MathUtils';\nimport { IStatisticsOverviewListItemConfig } from '../statistics-overview-list-item/statistics-overview-list-item';\n\n@useView(PLATFORM.moduleName('./statistics-overview-points.html'))\nexport class StatisticsOverviewPoints {\n  @bindable() public pointsGroup: ICoursePointsGroupedDto | null = null;\n  @bindable() public trainMaxPoints: number | null = null;\n  @bindable() public showGames = true;\n  private id: string;\n\n  constructor(idGenerator: IdGeneratorService) {\n    this.id = idGenerator.getId().toString();\n  }\n\n  @computedFrom('pointsGroup', 'trainMaxPoints', 'showGames')\n  private get listItems(): IStatisticsOverviewListItemConfig[] {\n    const items = [\n      {\n        iconName: 'System/Menu/Wissen',\n        color: ThemeColorType.Primary,\n        text: { tk: 'common.statistics-general.learning' },\n        value: { tk: 'common.statistics-general.points', tkParams: { points: this.pointsGroup?.learning ?? 0 } },\n        valueDescription: { tk: 'common.statistics-general.xOfYPoints', tkParams: { points: COURSE_TOTAL_LEARN_POINTS } },\n      },\n      {\n        iconName: 'System/Menu/Wissen',\n        color: ThemeColorType.Secondary1,\n        text: { tk: 'common.statistics-general.training' },\n        value: { tk: 'common.statistics-general.points', tkParams: { points: this.pointsGroup?.training ?? 0 } },\n        valueDescription: {\n          tk: 'common.statistics-general.xOfYTargetPoints',\n          tkParams: { points: MathUtils.roundToDigit(this.trainMaxPoints ?? COURSE_TARGET_TRAINING_POINTS, 4) },\n        },\n      },\n      {\n        iconName: 'System/Menu/Wissen',\n        color: ThemeColorType.Testexam,\n        text: { tk: 'common.statistics-general.testexam' },\n        value: { tk: 'common.statistics-general.points', tkParams: { points: this.pointsGroup?.testexam ?? 0 } },\n      },\n    ];\n\n    if(this.showGames) {\n      items.push({\n        iconName: 'System/Menu/Games',\n        color: ThemeColorType.Secondary3,\n        text: { tk: 'common.statistics-general.games' },\n        value: {\n          tk: 'common.statistics-general.points',\n          tkParams: { points: (this.pointsGroup?.duel ?? 0) + (this.pointsGroup?.activityStreak ?? 0) + (this.pointsGroup?.lecture ?? 0) },\n        },\n      });\n    }\n\n    return items;\n  }\n}\n","import { PLATFORM, FrameworkConfiguration } from 'aurelia-framework';\n\nexport function configure(config: FrameworkConfiguration): void {\n  config.globalResources(PLATFORM.moduleName('common/aurelia-components/statistics-overview-progress/statistics-overview-progress'));\n}\n","import { bindable, computedFrom, PLATFORM, useView } from 'aurelia-framework';\nimport { ThemeColorType } from 'common/aurelia-classes/SiteThemer';\nimport { IdGeneratorService } from 'common/aurelia-services/IdGeneratorService';\nimport { MathUtils } from 'common/utils/MathUtils';\nimport { IStatisticsOverviewListItemConfig } from '../statistics-overview-list-item/statistics-overview-list-item';\n\n@useView(PLATFORM.moduleName('./statistics-overview-progress.html'))\nexport class StatisticsOverviewProgress {\n  @bindable() public learnProgressPercentage = 0;\n  @bindable() public trainProgressPercentage = 0;\n  private donutChartColors: ThemeColorType[] = [\n    ThemeColorType.Primary,\n    ThemeColorType.Secondary1,\n  ];\n  private id: string;\n\n  constructor(idGenerator: IdGeneratorService) {\n    this.id = idGenerator.getId().toString();\n  }\n\n  @computedFrom('trainProgressPercentage')\n  private get trainProgressPercentageClamped(): number {\n    return MathUtils.roundProgress(this.trainProgressPercentage);\n  }\n\n  @computedFrom('learnProgressPercentage', 'trainProgressPercentage')\n  private get listItems(): IStatisticsOverviewListItemConfig[] {\n    return [\n      {\n        iconName: 'System/Menu/Wissen',\n        color: ThemeColorType.Primary,\n        text: { tk: 'common.statistics-general.learning' },\n        value: `${MathUtils.roundProgress(this.learnProgressPercentage)}%`,\n      },\n      {\n        iconName: 'System/Menu/Wissen',\n        color: ThemeColorType.Secondary1,\n        text: { tk: 'common.statistics-general.training' },\n        value: `${MathUtils.roundProgress(this.trainProgressPercentage, false)}%`,\n      },\n    ];\n  }\n}\n","import { PLATFORM, FrameworkConfiguration } from 'aurelia-framework';\n\nexport function configure(config: FrameworkConfiguration): void {\n  config.globalResources(PLATFORM.moduleName('common/aurelia-components/statistics-sub-header/statistics-sub-header'));\n}\n","import { bindable, PLATFORM, useView } from 'aurelia-framework';\nimport { ThemeColorType } from 'common/aurelia-classes/SiteThemer';\nimport { IText } from 'common/interfaces/translations.interface';\n\n@useView(PLATFORM.moduleName('./statistics-sub-header.html'))\nexport class StatisticsSubHeader {\n  @bindable() public title: string | null = null;\n  @bindable() public progress: number | null = null;\n  @bindable() public points = 0;\n  @bindable() public themeColor: ThemeColorType = ThemeColorType.Primary;\n  @bindable() public listItems: IListItemConfig[] = [];\n}\n\nexport interface IListItemConfig {\n  text: IText;\n  value: IText | string;\n  valueDescription?: IText;\n}\n","import { FrameworkConfiguration, PLATFORM } from 'aurelia-framework';\n\nexport function configure(config: FrameworkConfiguration): void {\n  config.globalResources(PLATFORM.moduleName('common/aurelia-components/statistics-testexam/statistics-testexam'));\n}\n","import { bindable, computedFrom, PLATFORM, useView } from 'aurelia-framework';\nimport { ICoursePointsGroupedDto } from 'common/dto/course/points/course.points.interface';\nimport { ITotalActivityTime } from 'common/dto/course/progress/course.progress.interface';\nimport { QuizStatus } from 'common/dto/course/quiz/quiz.response';\nimport { QuizAttemptStatus } from 'common/enum/quiz.attempt.status.enum';\nimport { ExamType } from 'common/enum/quiz.enum';\nimport { StatisticsUtils } from 'common/utils/StatisticsUtils';\nimport { TimeUtils } from 'common/utils/TimeUtils';\nimport Moment from 'moment';\nimport { ICssBarChartConfig } from '../css-bar-chart/css-bar-chart';\nimport { imageNameToString } from '../images';\nimport { IListItemConfig } from '../statistics-sub-header/statistics-sub-header';\n\n@useView(PLATFORM.moduleName('./statistics-testexam.html'))\nexport class StatisticsTestexam {\n  @bindable() public previousExamAttempts: QuizStatus[] = [];\n  @bindable() public pointsGroup: ICoursePointsGroupedDto | null = null;\n  @bindable() public totalActivityTime: ITotalActivityTime | null = null;\n  @bindable() public courseId: number | null = null;\n  @bindable() public studentId: number | null = null;\n\n  @bindable() public showHeader = false;\n  @bindable() public chartTitleTk = '';\n  @bindable() public routeToOverview: string = '';\n  @bindable() public openResultAsPage = false;\n  @bindable() public allowResultDetailView = true;\n  @bindable() public placeholderImage = imageNameToString.TestexamCropped;\n\n  private previousExamAttemptsWithConfirmedStatus: QuizStatus[] = [];\n  private lastFourPreviousExamAttempts: QuizStatus[] = [];\n  private displayedPreviousExamAttempts: QuizStatus[] = [];\n  private showPreviousExamAttempts = false;\n\n  protected activate(): void {\n    this.updateExamlist();\n  }\n\n  private previousExamAttemptsChanged(): void {\n    this.updateExamlist();\n  }\n\n  private updateExamlist(): void {\n    this.previousExamAttemptsWithConfirmedStatus = this.previousExamAttempts\n      .filter(attempt => attempt.state !== QuizAttemptStatus.Ready && attempt.state !== QuizAttemptStatus.Running);\n    this.lastFourPreviousExamAttempts = this.previousExamAttemptsWithConfirmedStatus.slice(0, 4);\n    this.setExamlistView(false);\n  }\n\n  private toggleExamlistView(): void {\n    this.showPreviousExamAttempts = !this.showPreviousExamAttempts;\n    this.setExamlistView(this.showPreviousExamAttempts);\n  }\n\n  private setExamlistView(showAll: boolean): void {\n    if(showAll) {\n      this.displayedPreviousExamAttempts = this.previousExamAttemptsWithConfirmedStatus;\n    } else {\n      this.displayedPreviousExamAttempts = this.lastFourPreviousExamAttempts;\n    }\n  }\n\n  private getLabel(exam: QuizStatus): string {\n    if(!('startTimestamp' in exam)) return '';\n    const day = Moment(exam.startTimestamp * 1000).format('Do');\n    const month = Moment(exam.startTimestamp * 1000).format('MMM').slice(0, 3);\n    return `${day} ${month}`;\n  }\n\n  @computedFrom('previousExamAttemptsWithConfirmedStatus.length')\n  private get barChartConfig(): ICssBarChartConfig[] {\n    const barChartConfig: ICssBarChartConfig[] = [];\n    for(const exam of this.previousExamAttemptsWithConfirmedStatus) {\n      if(exam.state !== QuizAttemptStatus.Finished) continue;\n      const subExams = exam.subQuizSessions?.length ? exam.subQuizSessions : [exam];\n      const values = subExams\n        .sort((a, b) => {\n          if(!a.examType || !b.examType) return -1;\n          if(a.examType === ExamType.FS_GW) return -1;\n          if(b.examType === ExamType.FS_GW) return 1;\n          return a.examType.localeCompare(b.examType);\n        })\n        .map(sE => {\n          const percent = StatisticsUtils.getPercentageFromQuizStatus(sE as QuizStatus);\n          return {\n            value: Math.max(1, percent),\n            tooltip: `${sE.courseTitle} ${percent}%`,\n          };\n        });\n\n      barChartConfig.push({\n        label: this.getLabel(exam),\n        values,\n      });\n    }\n    return barChartConfig.reverse();\n  }\n\n  @computedFrom('previousExamAttemptsWithConfirmedStatus.length')\n  private get hasSingleExams(): boolean {\n    return this.previousExamAttemptsWithConfirmedStatus.length > 0\n      && this.previousExamAttemptsWithConfirmedStatus?.some(exam => exam.examType !== ExamType.FS_COMBO && exam.state === QuizAttemptStatus.Finished);\n  }\n\n  @computedFrom('previousExamAttemptsWithConfirmedStatus.length')\n  private get hasComboExams(): boolean {\n    return this.previousExamAttemptsWithConfirmedStatus.length > 0\n      && this.previousExamAttemptsWithConfirmedStatus?.some(exam => exam.examType === ExamType.FS_COMBO && exam.state === QuizAttemptStatus.Finished);\n  }\n\n\n  @computedFrom('totalActivityTime')\n  private get listItems(): IListItemConfig[] {\n    return [\n      {\n        text: { tk: 'common.statistics-general.timeInTestexamTotal' },\n        value: `~${TimeUtils.getDurationFormatted((this.totalActivityTime?.secondsInTestexam ?? 0))}`,\n      },\n    ];\n  }\n}\n","import { PLATFORM, FrameworkConfiguration } from 'aurelia-framework';\n\nexport function configure(config: FrameworkConfiguration): void {\n  config.globalResources(PLATFORM.moduleName('common/aurelia-components/statistics-training/statistics-training'));\n}\n","import { bindable, computedFrom, PLATFORM, useView } from 'aurelia-framework';\nimport { COURSE_TARGET_TRAINING_POINTS } from 'common/constants/course.constants';\nimport { ICoursePointsGroupedDto } from 'common/dto/course/points/course.points.interface';\nimport { ITotalActivityTime } from 'common/dto/course/progress/course.progress.interface';\nimport { MathUtils } from 'common/utils/MathUtils';\nimport { TimeUtils } from 'common/utils/TimeUtils';\nimport { IProgressData } from '../statistics-chapter-progress/statistics-chapter-progress';\nimport { IListItemConfig } from '../statistics-sub-header/statistics-sub-header';\n\n@useView(PLATFORM.moduleName('./statistics-training.html'))\nexport class StatisticsTraining {\n  @bindable() public progressDataTrain: IProgressData[] | null = null;\n  @bindable() public trainProgress: number | null = null;\n  @bindable() public trainMaxPoints: number | null = null;\n  @bindable() public recentTrainingsCount: number = 0;\n  @bindable() public pointsGroup: ICoursePointsGroupedDto | null = null;\n  @bindable() public totalActivityTime: ITotalActivityTime | null = null;\n\n  @computedFrom('trainProgress')\n  private get trainProgressPercentageClamped(): number {\n    return this.trainProgress ? MathUtils.roundProgress(this.trainProgress) : 0;\n  }\n\n  @computedFrom(\n    'pointsGroup',\n    'trainProgress',\n    'trainMaxPoints',\n    'recentTrainingsCount',\n    'totalActivityTime',\n  )\n  private get listItems(): IListItemConfig[] {\n    return [\n      {\n        text: { tk: 'common.statistics-general.progressTotal' },\n        value: `${MathUtils.roundProgress(this.trainProgress ?? 0, false)}%`,\n      },\n      {\n        text: { tk: 'common.statistics-general.pointsTotal' },\n        value: {\n          tk: 'common.statistics-general.points',\n          tkParams: { points: this.pointsGroup?.training ?? 0 },\n        },\n        valueDescription: {\n          tk: 'common.statistics-general.xOfYPointsApproximately',\n          tkParams: { points: MathUtils.roundToDigit(this.trainMaxPoints ?? COURSE_TARGET_TRAINING_POINTS, 4) },\n        },\n      },\n      {\n        text: { tk: 'common.statistics-general.trainingsCount' },\n        value: `${this.recentTrainingsCount}`,\n      },\n      {\n        text: { tk: 'common.statistics-general.timeTrainedTotal' },\n        value: TimeUtils.getDurationFormatted((this.totalActivityTime?.secondsTrained ?? 0)),\n      },\n    ];\n  }\n}\n"],"names":[],"sourceRoot":""}