{"version":3,"file":"app-fe3f4675.f584a1446b2fc034d810.bundle.js","mappings":"AAGA","sources":["webpack://lernplattform-admin-frontend/./src/resources/elements/color-select/color-select.html","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-clipboard-card-preview/preview-clipboard-card-block/preview-clipboard-card-block.html","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-clipboard-card-preview/preview-clipboard-card-layout-container/preview-clipboard-card-layout-container.html","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-color-select/content-editor-color-select-preview/content-editor-color-select-preview.html","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-color-select/content-editor-color-select.html","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-container-options/content-editor-container-options.html","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-dragged-block/content-editor-dragged-block.html","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-enum-options/content-editor-enum-options.html","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-header-bar/content-editor-header-bar.html","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-icon-button/content-editor-icon-button.html","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-inspector/content-editor-inspector-attribute/content-editor-inspector-attribute.html","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-inspector/content-editor-inspector-section-alignment/content-editor-inspector-section-alignment.html","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-inspector/content-editor-inspector-section-attributes/content-editor-inspector-section-attributes.html","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-inspector/content-editor-inspector-section-sizing-side/content-editor-inspector-section-sizing-side.html","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-inspector/content-editor-inspector-section-sizing/content-editor-inspector-section-sizing.html","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-inspector/content-editor-inspector-section-styles/content-editor-inspector-section-styles.html","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-inspector/content-editor-inspector-section/content-editor-inspector-section.html","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-inspector/content-editor-inspector.html","webpack://lernplattform-admin-frontend/./src/resources/elements/color-select/color-select.ts","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-clipboard-card-preview/index.ts","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-clipboard-card-preview/preview-clipboard-card-block/preview-clipboard-card-block.ts","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-clipboard-card-preview/preview-clipboard-card-layout-container/preview-clipboard-card-layout-container.ts","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-color-select/content-editor-color-select.ts","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-color-select/index.ts","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-container-options/content-editor-container-options.ts","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-dragged-block/content-editor-dragged-block.ts","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-enum-options/content-editor-enum-options.ts","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-header-bar/content-editor-header-bar.ts","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-icon-button/content-editor-icon-button.ts","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-inspector/content-editor-inspector-attribute/content-editor-inspector-attribute.ts","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-inspector/content-editor-inspector-section-alignment/content-editor-inspector-section-alignment.ts","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-inspector/content-editor-inspector-section-attributes/content-editor-inspector-section-attributes.ts","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-inspector/content-editor-inspector-section-sizing-side/content-editor-inspector-section-sizing-side.ts","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-inspector/content-editor-inspector-section-sizing/content-editor-inspector-section-sizing.ts","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-inspector/content-editor-inspector-section-styles/content-editor-inspector-section-styles.ts","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-inspector/content-editor-inspector-section/content-editor-inspector-section.ts","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-inspector/content-editor-inspector.ts","webpack://lernplattform-admin-frontend/./src/resources/elements/content-editor-inspector/index.ts"],"sourcesContent":["// Module\nvar code = \"<template> <div class=\\\"form-group\\\"> <div class=\\\"form-label\\\">${title}</div> <label repeat.for=\\\"color of colors\\\"> <div class=\\\"color-select__preview ${ value === color ? 'color-select__preview--selected' : '' }\\\" click.delegate=\\\"handleColorSelected(color)\\\" css=\\\"background-color:${getColorValue(color)};\\\"></div> </label> <div if.to-view=\\\"showAltSelect\\\" class=\\\"d-flex\\\"> <input class=\\\"form-control mr-2 color-select__picker\\\" type=\\\"color\\\" change.trigger=\\\"value = pickerValue\\\" value.two-way=\\\"pickerValue\\\" colorpick-eyedropper-active=\\\"true\\\"> <div class=\\\"input-group\\\"> <input type=\\\"text\\\" placeholder=\\\"#000000\\\" blur.trigger=\\\"updatePicker()\\\" class=\\\"form-control\\\" pattern.to-view=\\\"hexColorPattern\\\" value.two-way=\\\"value\\\"> <div class=\\\"input-group-append\\\"> <button-standard click.trigger=\\\"resetValues()\\\" icon-name=\\\"System/Tabler/X\\\" btn-color=\\\"danger\\\"></button-standard> </div> </div> </div> </div> </template>\";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"preview-clipboard-card-block\\\" style.to-view=\\\"style\\\"> <course-lecture-block-audio if.to-view=\\\"block.type === BlockType.AUDIO\\\" class=\\\"preview-clipboard-card-block__block\\\" block.to-view=\\\"block\\\"></course-lecture-block-audio> <course-lecture-block-video if.to-view=\\\"block.type === BlockType.VIDEO || block.type === BlockType.YOUTUBE || block.type === BlockType.VIMEO\\\" class=\\\"preview-clipboard-card-block__block\\\" block.to-view=\\\"block\\\" is-static.to-view=\\\"isNonInteractivePreview\\\"></course-lecture-block-video> <course-lecture-block-text if.to-view=\\\"block.type === BlockType.TEXT\\\" class=\\\"preview-clipboard-card-block__block\\\" block.to-view=\\\"block\\\" show-annotations.to-view=\\\"true\\\"></course-lecture-block-text> <course-lecture-block-spacer if.to-view=\\\"block.type === BlockType.SPACER\\\" class=\\\"preview-clipboard-card-block__block\\\"></course-lecture-block-spacer> </template> \";\n// Exports\nexport default code;","// Module\nvar code = \"<template class.to-view=\\\"styleClasses\\\" style.to-view=\\\"{ '--preview-clipboard-card-layout-container-scale-factor': scaleFactor }\\\"> <div class=\\\"preview-clipboard-card-layout-container__content\\\" style.to-view=\\\"layoutStyles\\\"> <preview-clipboard-card-block if.to-view=\\\"mode === 'block'\\\" class=\\\"preview-clipboard-card-layout-container__block\\\" block-id.to-view=\\\"layoutContainer.blockId\\\"></preview-clipboard-card-block> <preview-clipboard-card-layout-container if.to-view=\\\"mode === 'children' && orderedChildIds != null\\\" repeat.for=\\\"childId of orderedChildIds\\\" class=\\\"preview-clipboard-card-layout-container__child\\\" layout-container-id.to-view=\\\"childId\\\"></preview-clipboard-card-layout-container> </div> </template> \";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"content-editor-color-select-preview ${ !color ? 'content-editor-color-select-preview--no-color' : '' }\\\" style.to-view=\\\"{ '--content-editor-color-select-preview-color': color }\\\" bindable=\\\"color\\\"> </template>\";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"content-editor-color-select\\\"> <div class=\\\"content-editor-color-select__color-wrapper\\\" style.to-view=\\\"{ '--content-editor-color-select-color-wrapper-column-count': colors.length + 1 }\\\"> <content-editor-color-select-preview click.delegate=\\\"resetColor()\\\"></content-editor-color-select-preview> <content-editor-color-select-preview repeat.for=\\\"color of colors\\\" click.delegate=\\\"handleColorSelected(getColorValue(color))\\\" color.to-view=\\\"getColorValue(color)\\\"></content-editor-color-select-preview> </div> <div class=\\\"content-editor-color-select__input-wrapper\\\"> <div class=\\\"input-group content-editor-color-select__input-group\\\"> <label class=\\\"form-control content-editor-color-select__input content-editor-color-select__input--color input-group-prepend\\\"> <content-editor-color-select-preview color.to-view=\\\"value\\\"></content-editor-color-select-preview> <input type=\\\"color\\\" ref=\\\"colorPickerDomElement\\\" class=\\\"invisible\\\" change.trigger=\\\"handleColorPicked()\\\" value.two-way=\\\"pickerValue\\\" colorpick-eyedropper-active=\\\"true\\\"> </label> <input type=\\\"text\\\" class=\\\"form-control content-editor-color-select__input\\\" placeholder.to-view=\\\"`#000000`\\\" change.trigger=\\\"updatePicker()\\\" pattern.to-view=\\\"hexColorPattern\\\" value.two-way=\\\"value\\\"> </div> <x-icon class=\\\"content-editor-color-select__input-icon\\\" click.trigger=\\\"showPicker()\\\" icon-type=\\\"custom\\\" size=\\\"unspecified\\\" icon-name=\\\"Uce/EyeDropper\\\"></x-icon> </div> </template>\";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"content-editor-container-options ${ displayCardOptions ? 'content-editor-container-options__card' : '' } ${ selected ? 'content-editor-container-options__card--selected' : '' }\\\"> <template if.to-view=\\\"layoutContainer.id\\\"></template> <draggable if.to-view=\\\"displayCardOptions\\\" drag-dom-element.to-view=\\\"draggedContainerElement\\\" payload.to-view=\\\"dndPayload\\\" dnd-active.to-view=\\\"dndActive\\\" drag-allowed.to-view=\\\"dndAllowed\\\" context.to-view=\\\"dndContext\\\"> <button-standard icon-name=\\\"System/DragAlt\\\" btn-size=\\\"icon\\\" tooltip-tk=\\\"pages.content-editor.tooltips.drag\\\" btn-color=\\\"none\\\" icon-color=\\\"white\\\"></button-standard> </draggable> <content-editor-dragged-block ref=\\\"draggedContainerElement\\\" icon-name=\\\"Uce/Card\\\"></content-editor-dragged-block> <button-standard if.to-view=\\\"!containerMode\\\" icon-name=\\\"Uce/Delete\\\" click.delegate=\\\"removeContainer()\\\" btn-size=\\\"icon\\\" tooltip-tk=\\\"globals.delete\\\" btn-color=\\\"secondary\\\"></button-standard> <button-standard if.to-view=\\\"block.type === BlockType.AUDIO\\\" icon-name=\\\"Uce/Volume\\\" click.delegate=\\\"changeContent()\\\" btn-size=\\\"icon\\\" tooltip-tk=\\\"pages.content-editor.tooltips.changeAudio\\\" btn-color=\\\"secondary\\\"></button-standard> <button-standard if.to-view=\\\"block.type === BlockType.MP_QUESTION\\\" icon-name=\\\"Uce/Question\\\" click.delegate=\\\"changeContent()\\\" btn-size=\\\"icon\\\" tooltip-tk=\\\"pages.content-editor.tooltips.changeQuestion\\\" btn-color=\\\"secondary\\\"></button-standard> <button-standard if.to-view=\\\"block.type === BlockType.FILE\\\" icon-name=\\\"Uce/File\\\" click.delegate=\\\"changeContent()\\\" btn-size=\\\"icon\\\" tooltip-tk=\\\"pages.content-editor.tooltips.changeFile\\\" btn-color=\\\"secondary\\\"></button-standard> <button-standard if.to-view=\\\"block.type === BlockType.MP_SCORM\\\" icon-name=\\\"Uce/Scorm\\\" click.delegate=\\\"changeContent()\\\" btn-size=\\\"icon\\\" tooltip-tk=\\\"pages.content-editor.tooltips.changeScorm\\\" btn-color=\\\"secondary\\\"></button-standard> <button-standard if.to-view=\\\"block.type === BlockType.FORMULA\\\" icon-name=\\\"Uce/SuperScript\\\" click.delegate=\\\"changeContent()\\\" btn-size=\\\"icon\\\" tooltip-tk=\\\"pages.content-editor.tooltips.editFormula\\\" btn-color=\\\"secondary\\\"></button-standard> <button-standard if.to-view=\\\"block.type === BlockType.MP_TILES\\\" icon-name=\\\"Uce/Tiles\\\" click.delegate=\\\"changeContent()\\\" btn-size=\\\"icon\\\" tooltip-tk=\\\"pages.content-editor.tooltips.changeTile\\\" btn-color=\\\"secondary\\\"></button-standard> <button-standard if.to-view=\\\"isPresentation && !containerMode\\\" icon-name=\\\"Uce/Copy\\\" click.delegate=\\\"copyContent()\\\" btn-size=\\\"icon\\\" tooltip-tk=\\\"pages.content-editor.tooltips.copy\\\" btn-color=\\\"secondary\\\"></button-standard> <button-standard if.to-view=\\\"isVideo\\\" icon-name=\\\"Uce/Film\\\" click.delegate=\\\"changeContent()\\\" btn-size=\\\"icon\\\" tooltip-tk=\\\"pages.content-editor.tooltips.changeVideo\\\" btn-color=\\\"secondary\\\"></button-standard> <button-standard if.to-view=\\\"block.type === BlockType.VIDEO\\\" icon-name=\\\"Uce/Pip\\\" click.delegate=\\\"handleVideoPip()\\\" btn-size=\\\"icon\\\" tooltip-tk=\\\"pages.content-editor.tooltips.pip\\\" btn-color=\\\"secondary\\\"></button-standard> <template if.to-view=\\\"block.type === BlockType.VIDEO && isDualVideo\\\"> <button-standard if.to-view=\\\"block.pipVideoPosition === 'top-left'\\\" icon-name=\\\"Uce/PipTopRight\\\" click.delegate=\\\"handleVideoPipSide()\\\" btn-size=\\\"icon\\\" tooltip-tk=\\\"pages.content-editor.tooltips.pipSideAlignRight\\\" btn-color=\\\"secondary\\\"></button-standard> <button-standard else icon-name=\\\"Uce/PipTopLeft\\\" click.delegate=\\\"handleVideoPipSide()\\\" btn-size=\\\"icon\\\" tooltip-tk=\\\"pages.content-editor.tooltips.pipSideAlignLeft\\\" btn-color=\\\"secondary\\\"></button-standard> <button-standard icon-name=\\\"Uce/PipOff\\\" click.delegate=\\\"handleVideoPipOff()\\\" btn-size=\\\"icon\\\" tooltip-tk=\\\"pages.content-editor.tooltips.pip\\\" btn-color=\\\"secondary\\\"></button-standard> </template> <template if.to-view=\\\"block.type === BlockType.PICTURE\\\"> <button-standard if.to-view=\\\"block.picture != null\\\" icon-name=\\\"Uce/Crop\\\" click.delegate=\\\"handlePictureCrop()\\\" btn-size=\\\"icon\\\" tooltip-tk=\\\"pages.content-editor.tooltips.crop\\\" btn-color=\\\"secondary\\\"></button-standard> <button-standard icon-name=\\\"Uce/Photo\\\" click.delegate=\\\"changeContent()\\\" btn-size=\\\"icon\\\" tooltip-tk=\\\"pages.content-editor.tooltips.changeImage\\\" btn-color=\\\"secondary\\\"></button-standard> <button-standard if.to-view=\\\"block.picture != null\\\" icon-name=\\\"Uce/RemovePhoto\\\" click.delegate=\\\"removeImage()\\\" btn-size=\\\"icon\\\" tooltip-tk=\\\"pages.content-editor.tooltips.removeImage\\\" btn-color=\\\"secondary\\\"></button-standard> </template> <button-standard if.to-view=\\\"!isIas && !disableInspector\\\" icon-name=\\\"Uce/Dots\\\" click.delegate=\\\"openInspectorForLayoutContainer()\\\" btn-size=\\\"icon\\\" tooltip-tk=\\\"pages.content-editor.tooltips.editElement\\\" btn-color=\\\"${ containerMode || displayCardOptions ? 'secondary' : 'none' }\\\" icon-color=\\\"${ containerMode || displayCardOptions ? '' : 'white' }\\\"></button-standard> </template>\";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"content-editor-dragged-block\\\"> <safe-icon class=\\\"content-editor-dragged-block__icon\\\" icon-name.to-view=\\\"iconName\\\"></safe-icon> <safe-icon class=\\\"content-editor-dragged-block__modifier-icon\\\" icon-name.to-view=\\\"modifierIconName\\\"></safe-icon> </template> \";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"content-editor-enum-options content-editor-enum-options--size-${btnSize}\\\"> <button-standard icon-name.to-view=\\\"selectedOptionIcon\\\" btn-size.to-view=\\\"btnSize\\\" tooltip-tk=\\\"${tooltipTk}\\\" btn-color=\\\"secondary\\\" click.delegate=\\\"showMenu = !showMenu\\\"></button-standard> <div if.to-view=\\\"showMenu\\\" class=\\\"content-editor-enum-options__menu\\\"> <div repeat.for=\\\"item of items\\\" click.trigger=\\\"handleOptionSelected(item.option)\\\" class=\\\"content-editor-enum-options__item ${ selectedOption === item.option ? 'content-editor-enum-options__item--selected' : '' }\\\"> <x-icon class=\\\"content-editor-enum-options__item-icon ${ selectedOption === item.option ? 'content-editor-enum-options__item-icon--selected' : '' }\\\" icon-type=\\\"custom\\\" size=\\\"unspecified\\\" icon-name=\\\"${item.icon}\\\"></x-icon> <span class=\\\"content-editor-enum-options__item-text ${ selectedOption === item.option ? 'content-editor-enum-options__item-text--selected' : '' }\\\" t=\\\"${item.textTk}\\\"></span> </div> </div> </template> \";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"content-editor-header-bar\\\"> <button-standard class=\\\"content-editor-header-bar__button\\\" icon-name=\\\"System/Tabler/Chevron-Left\\\" click.delegate=\\\"navigateBack()\\\" btn-type=\\\"uce\\\"></button-standard> <div class=\\\"content-editor-header-bar__info mr-auto ${titleInlineEditField.isEditing ? 'content-editor-header-bar__info--editing' : ''}\\\"> <inline-edit-field class=\\\"content-editor-header-bar__title\\\" view-model.ref=\\\"titleInlineEditField\\\" value.to-view=\\\"title\\\" mode=\\\"click\\\" show-edit-border.to-view=\\\"false\\\" max-length.to-view=\\\"60\\\" min-length.to-view=\\\"1\\\" validation-failed-event.trigger=\\\"onTitleValidationFailed($event)\\\" save-event.trigger=\\\"onSaveTitle($event)\\\"></inline-edit-field> <div if.to-view=\\\"editorMode === ContentEditorMode.PRESENTATION && isShared\\\" class=\\\"content-editor-header-bar__sub-title\\\" t=\\\"pages.content-editor.sharedWithTenant\\\"></div> <button-standard if.to-view=\\\"editorMode !== ContentEditorMode.PRESENTATION && !titleInlineEditField.isEditing\\\" class=\\\"content-editor-header-bar__preview-btn\\\" btn-type=\\\"uce\\\" btn-color=\\\"primary\\\" icon-name=\\\"Uce/Eye\\\" t=\\\"[btnText]globals.preview\\\" click.delegate=\\\"showPreview()\\\"></button-standard> </div> <draggable repeat.for=\\\"contentElementType of mostUsedContentElementTypes\\\" class=\\\"${ inspectorMode === InspectorMode.Container ? 'content-editor-header-bar__most-used-block-disabled' : '' }\\\" payload.to-view=\\\"{\\n               source: DndPayloadSource.New,\\n               createNewType: contentElementType,\\n             }\\\" dnd-active.to-view=\\\"dndActive\\\" drag-dom-element.to-view=\\\"draggedContentElements[$index]\\\" context.to-view=\\\"dndContext\\\"> <content-editor-dragged-block ref=\\\"draggedContentElements[$index]\\\" icon-name.to-view=\\\"getIconName(contentElementType)\\\" modifier-icon-name.to-view=\\\"getModifierIconName(contentElementType)\\\"></content-editor-dragged-block> <div class=\\\"content-editor-header-bar__drag-handle ${contentElementType === dndPayload ? 'content-editor-header-bar__drag-handle--ghost' : ''}\\\"> <safe-icon class=\\\"content-editor-header-bar__drag-icon ${ inspectorMode === InspectorMode.Container ? 'content-editor-header-bar__drag-icon--disabled' : '' }\\\" icon-name.to-view=\\\"getIconName(contentElementType)\\\"></safe-icon> </div> </draggable> <button-standard class=\\\"content-editor-header-bar__button mr-5 ml-2 ${ isSidebarBlocksActive ? 'content-editor-header-bar__button--active' : '' }\\\" btn-type=\\\"uce\\\" btn-color=\\\"primary\\\" t=\\\"[btnText]pages.content-editor.blocks\\\" click.delegate=\\\"toggleSidebarBlocks()\\\"></button-standard> <div if.to-view=\\\"!isIas\\\" class=\\\"content-editor-header-bar__separator\\\"></div> <button-standard if.to-view=\\\"!isIas\\\" class=\\\"content-editor-header-bar__button mr-5 ml-5 ${ isSidebarTemplatesActive ? 'content-editor-header-bar__button--active' : '' }\\\" btn-type=\\\"uce\\\" btn-color=\\\"primary\\\" t=\\\"[btnText]pages.content-editor.templates\\\" click.delegate=\\\"toggleSidebarTemplates()\\\"></button-standard> <template if.to-view=\\\"!isIas && !isInspectorDisabled\\\"> <div class=\\\"content-editor-header-bar__separator\\\"></div> <button-standard class=\\\"content-editor-header-bar__button mr-5 ml-5 ${ isSidebarInspectorActive ? 'content-editor-header-bar__button--active' : '' }\\\" btn-type=\\\"uce\\\" btn-color=\\\"primary\\\" t=\\\"[btnText]pages.content-editor.design\\\" click.delegate=\\\"toggleSidebarInspector()\\\"></button-standard> <div class=\\\"content-editor-header-bar__separator\\\"></div> <button-lightswitch t=\\\"[label]pages.content-editor.container\\\" class=\\\"content-editor-header-bar__switch\\\" label-before.to-view=\\\"true\\\" value.to-view=\\\"containerMode\\\" value-changed.delegate=\\\"toggleContainerMode($event)\\\" theme=\\\"uce\\\"></button-lightswitch> </template> <div if.to-view=\\\"editorMode === ContentEditorMode.PRESENTATION\\\" class=\\\"content-editor-header-bar__separator\\\"></div> <dropdown-button if.to-view=\\\"editorMode === ContentEditorMode.PRESENTATION\\\" theme=\\\"uce\\\" placement=\\\"bottom-end\\\" show-arrow.to-view=\\\"false\\\" close-on-inside-click.to-view=\\\"false\\\"> <button-standard slot=\\\"button\\\" class=\\\"content-editor-header-bar__button ml-3\\\" icon-name=\\\"System/Tabler/Dots\\\" btn-type=\\\"uce\\\"></button-standard> <div class=\\\"dropdown-item pointer\\\" click.delegate=\\\"onDeletePresentation()\\\"> <span t.to-view=\\\"deleteTk\\\"></span> <safe-icon class=\\\"content-editor-header-bar__delete-presentation-icon\\\" icon-name=\\\"System/Tabler/Trash\\\"></safe-icon> </div> <div if.to-view=\\\"showShareWithTenant\\\" class=\\\"dropdown-divider\\\"></div> <div if.to-view=\\\"showShareWithTenant\\\" class=\\\"dropdown-item\\\"> <button-lightswitch t=\\\"[label]pages.content-editor.shareWithTenant\\\" class=\\\"content-editor-header-bar__switch\\\" label-before.to-view=\\\"true\\\" value.to-view=\\\"isShared\\\" value-changed.delegate=\\\"onSharedWithTenantChanged($event)\\\" theme=\\\"uce\\\"></button-lightswitch> </div> </dropdown-button> </template> \";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"content-editor-icon-button ${ active ? 'content-editor-icon-button--active' : '' }\\\"> <safe-icon class=\\\"content-editor-icon-button__icon ${ active ? 'content-editor-icon-button__icon--active' : '' }\\\" icon-name.to-view=\\\"icon\\\"></safe-icon> </template> \";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"content-editor-inspector-attribute ${ asButton ? 'content-editor-inspector-attribute--as-button' : ''}\\\"> <span class=\\\"content-editor-inspector-attribute__text\\\" t.to-view=\\\"textTk\\\"></span> <div class=\\\"content-editor-inspector-attribute__options\\\"> <slot></slot> </div> </template> \";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"content-editor-inspector-section-attributes\\\"> <content-editor-inspector-attribute text-tk=\\\"pages.content-editor.inspector.horizontal\\\"> <content-editor-icon-button icon=\\\"Uce/HAlignLeft\\\" active.to-view=\\\"layoutContainer.style.horizontalAlignment === LayoutContainerHAlignment.Left\\\" click.delegate=\\\"setHAlign(LayoutContainerHAlignment.Left)\\\"></content-editor-icon-button> <content-editor-icon-button icon=\\\"Uce/HAlignCenter\\\" active.to-view=\\\"layoutContainer.style.horizontalAlignment === LayoutContainerHAlignment.Center\\\" click.delegate=\\\"setHAlign(LayoutContainerHAlignment.Center)\\\"></content-editor-icon-button> <content-editor-icon-button icon=\\\"Uce/HAlignRight\\\" active.to-view=\\\"layoutContainer.style.horizontalAlignment === LayoutContainerHAlignment.Right\\\" click.delegate=\\\"setHAlign(LayoutContainerHAlignment.Right)\\\"></content-editor-icon-button> </content-editor-inspector-attribute> <content-editor-inspector-attribute text-tk=\\\"pages.content-editor.inspector.vertical\\\"> <content-editor-icon-button icon=\\\"Uce/VAlignTop\\\" active.to-view=\\\"layoutContainer.style.verticalAlignment === LayoutContainerVAlignment.Top\\\" click.delegate=\\\"setVAlign(LayoutContainerVAlignment.Top)\\\"></content-editor-icon-button> <content-editor-icon-button icon=\\\"Uce/VAlignCenter\\\" active.to-view=\\\"layoutContainer.style.verticalAlignment === LayoutContainerVAlignment.Center\\\" click.delegate=\\\"setVAlign(LayoutContainerVAlignment.Center)\\\"></content-editor-icon-button> <content-editor-icon-button icon=\\\"Uce/VAlignBottom\\\" active.to-view=\\\"layoutContainer.style.verticalAlignment === LayoutContainerVAlignment.Bottom\\\" click.delegate=\\\"setVAlign(LayoutContainerVAlignment.Bottom)\\\"></content-editor-icon-button> </content-editor-inspector-attribute> </template> \";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"content-editor-inspector-section-attributes\\\"> <content-editor-inspector-attribute text-tk=\\\"pages.content-editor.inspector.padding\\\" as-button.to-view=\\\"true\\\" click.delegate=\\\"toggleSpacing()\\\"> <button-lightswitch value.to-view=\\\"layoutContainer.style.spacing\\\" theme=\\\"uce\\\"></button-lightswitch> </content-editor-inspector-attribute> <template if.to-view=\\\"layoutContainer.type === LayoutContainerType.Card\\\"> <content-editor-inspector-attribute text-tk=\\\"pages.content-editor.inspector.separators\\\" as-button.to-view=\\\"true\\\" click.delegate=\\\"toggleSeparators()\\\"> <button-lightswitch value.to-view=\\\"layoutContainer.style.separator\\\" theme=\\\"uce\\\"></button-lightswitch> </content-editor-inspector-attribute> <content-editor-inspector-attribute text-tk=\\\"pages.content-editor.inspector.direction\\\"> <content-editor-icon-button icon=\\\"System/Tabler/Arrow-Down\\\" active.to-view=\\\"layoutContainer.layout.direction === LayoutContainerDirection.Vertical\\\" click.delegate=\\\"setDirection(LayoutContainerDirection.Vertical)\\\"></content-editor-icon-button> <content-editor-icon-button icon=\\\"System/Tabler/Arrow-Right\\\" active.to-view=\\\"layoutContainer.layout.direction === LayoutContainerDirection.Horizontal\\\" click.delegate=\\\"setDirection(LayoutContainerDirection.Horizontal)\\\"></content-editor-icon-button> </content-editor-inspector-attribute> </template> <content-editor-inspector-attribute text-tk=\\\"pages.content-editor.inspector.corners\\\"> <content-editor-icon-button icon=\\\"Uce/CornerRound\\\" active.to-view=\\\"layoutContainer.style.corner === CornerStyle.Rounded\\\" click.delegate=\\\"setCornerStyle(CornerStyle.Rounded)\\\"></content-editor-icon-button> <content-editor-icon-button icon=\\\"Uce/Corner\\\" active.to-view=\\\"layoutContainer.style.corner === CornerStyle.Cornered\\\" click.delegate=\\\"setCornerStyle(CornerStyle.Cornered)\\\"></content-editor-icon-button> </content-editor-inspector-attribute> <content-editor-inspector-attribute if.to-view=\\\"sizingAvailable\\\" text-tk=\\\"pages.content-editor.inspector.sizing\\\"> <content-editor-icon-button icon=\\\"Uce/SizeSm\\\" active.to-view=\\\"layoutContainer.style.blockSize === LayoutContainerBlockSize.Small\\\" click.delegate=\\\"setBlockSize(LayoutContainerBlockSize.Small)\\\"></content-editor-icon-button> <content-editor-icon-button icon=\\\"Uce/SizeMd\\\" active.to-view=\\\"layoutContainer.style.blockSize === LayoutContainerBlockSize.Medium\\\" click.delegate=\\\"setBlockSize(LayoutContainerBlockSize.Medium)\\\"></content-editor-icon-button> <content-editor-icon-button icon=\\\"Uce/SizeLg\\\" active.to-view=\\\"layoutContainer.style.blockSize === LayoutContainerBlockSize.Large\\\" click.delegate=\\\"setBlockSize(LayoutContainerBlockSize.Large)\\\"></content-editor-icon-button> <content-editor-icon-button icon=\\\"Uce/Fill\\\" active.to-view=\\\"layoutContainer.style.blockSize === LayoutContainerBlockSize.Full\\\" click.delegate=\\\"setBlockSize(LayoutContainerBlockSize.Full)\\\"></content-editor-icon-button> </content-editor-inspector-attribute> <content-editor-inspector-attribute text-tk=\\\"pages.content-editor.inspector.backgroundColor\\\"> <content-editor-color-select-preview click.delegate=\\\"toggleColorSelect()\\\" color.to-view=\\\"layoutContainer.style.backgroundColor\\\"></content-editor-color-select-preview> <content-editor-color-select if.to-view=\\\"showColorSelect\\\" class=\\\"content-editor-inspector-section-attributes__color-select\\\" current-color.to-view=\\\"layoutContainer.style.backgroundColor\\\" color-selected.trigger=\\\"handleColorSelected($event)\\\"></content-editor-color-select> </content-editor-inspector-attribute> <template if.to-view=\\\"containerMode || layoutContainer.type === LayoutContainerType.Card\\\"> <button-standard class=\\\"content-editor-inspector-section-attributes__button-standard\\\" t=\\\"[btnText]pages.content-editor.inspector.backgroundImageSelect\\\" click.delegate=\\\"setBackgroundImage()\\\" icon-name=\\\"Uce/Photo\\\" btn-color=\\\"secondary\\\" btn-fill-mode=\\\"fill-width-align-left\\\"></button-standard> <button-standard if.to-view=\\\"layoutContainer.style.backgroundImage != null\\\" class=\\\"content-editor-inspector-section-attributes__button-standard\\\" t=\\\"[btnText]pages.content-editor.inspector.backgroundImageRemove\\\" click.delegate=\\\"removeBackgroundImage()\\\" icon-name=\\\"Uce/Trash\\\" btn-type=\\\"outline\\\" btn-color=\\\"danger\\\" btn-fill-mode=\\\"fill-width-align-left\\\"></button-standard> </template> </template>\";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"content-editor-inspector-section-sizing-side\\\"> <content-editor-inspector-attribute text-tk=\\\"pages.content-editor.inspector.${side}\\\"> <input type=\\\"number\\\" class=\\\"form-control content-editor-inspector-section-sizing-side__input ${ customBlockSizeError ? 'content-editor-inspector-section-sizing-side__input--invalid' : '' }\\\" value.two-way=\\\"customBlockSize\\\" min.to-view=\\\"-100\\\" max.to-view=\\\"100\\\" change.trigger=\\\"onSaveCustomBlockSize()\\\"/> <content-editor-icon-button icon=\\\"Uce/SizeSm\\\" active.to-view=\\\"BlockStyleSizingDefault.Small === block.styleSpacingOptions[side]\\\" click.delegate=\\\"setDefaultBlockSize(BlockStyleSizingDefault.Small, side)\\\"></content-editor-icon-button> <content-editor-icon-button icon=\\\"Uce/SizeMd\\\" active.to-view=\\\"BlockStyleSizingDefault.Medium === block.styleSpacingOptions[side]\\\" click.delegate=\\\"setDefaultBlockSize(BlockStyleSizingDefault.Medium, side)\\\"></content-editor-icon-button> <content-editor-icon-button icon=\\\"Uce/SizeLg\\\" active.to-view=\\\"BlockStyleSizingDefault.Large === block.styleSpacingOptions[side]\\\" click.delegate=\\\"setDefaultBlockSize(BlockStyleSizingDefault.Large, side)\\\"></content-editor-icon-button> <content-editor-icon-button icon=\\\"Uce/Delete\\\" click.delegate=\\\"unsetBlockSize()\\\"></content-editor-icon-button> </content-editor-inspector-attribute> </template>\";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"content-editor-inspector-section-sizing\\\"> <content-editor-inspector-section-sizing-side if.to-view=\\\"block\\\" block.to-view=\\\"block\\\" update-block-sizing.trigger=\\\"saveBlockSize($event)\\\" side=\\\"left\\\"></content-editor-inspector-section-sizing-side> <content-editor-inspector-section-sizing-side if.to-view=\\\"block\\\" block.to-view=\\\"block\\\" update-block-sizing.trigger=\\\"saveBlockSize($event)\\\" side=\\\"right\\\"></content-editor-inspector-section-sizing-side> </template>]\";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"content-editor-inspector-section-styles\\\"> <template if.to-view=\\\"layoutContainer.id\\\"></template> <div class=\\\"content-editor-inspector-section-styles__style\\\" click.delegate=\\\"setStyle(false, false)\\\"> <safe-icon if.to-view=\\\"selectedStyle === SelectedStyle.Plain\\\" class=\\\"content-editor-inspector-section-styles__selected-icon\\\" icon-name=\\\"Uce/Check\\\"></safe-icon> </div> <div class=\\\"content-editor-inspector-section-styles__style content-editor-inspector-section-styles__style--shadow\\\" click.delegate=\\\"setStyle(true, false)\\\"> <safe-icon if.to-view=\\\"selectedStyle === SelectedStyle.Shadow\\\" class=\\\"content-editor-inspector-section-styles__selected-icon\\\" icon-name=\\\"Uce/Check\\\"></safe-icon> </div> <div class=\\\"content-editor-inspector-section-styles__style content-editor-inspector-section-styles__style--border\\\" click.delegate=\\\"setStyle(false, true)\\\"> <safe-icon if.to-view=\\\"selectedStyle === SelectedStyle.Border\\\" class=\\\"content-editor-inspector-section-styles__selected-icon\\\" icon-name=\\\"Uce/Check\\\"></safe-icon> </div> <div class=\\\"content-editor-inspector-section-styles__style content-editor-inspector-section-styles__style--shadow content-editor-inspector-section-styles__style--border\\\" click.delegate=\\\"setStyle(true, true)\\\"> <safe-icon if.to-view=\\\"selectedStyle === SelectedStyle.BorderAndShadow\\\" class=\\\"content-editor-inspector-section-styles__selected-icon\\\" icon-name=\\\"Uce/Check\\\"></safe-icon> </div> </template> \";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"content-editor-inspector-section\\\"> <div class=\\\"content-editor-inspector-section__header\\\"> <span class=\\\"content-editor-inspector-section__header-title\\\" t.to-view=\\\"titleTk\\\"></span> <safe-icon class=\\\"content-editor-inspector-section__header-icon\\\" icon-name.to-view=\\\"collapsed ? `System/Arrow - Down` : `System/Arrow - Up`\\\" click.delegate=\\\"collapsed = !collapsed\\\"></safe-icon> </div> <div class=\\\"content-editor-inspector-section__content ${ collapsed ? 'content-editor-inspector-section__content--collapsed' : ''}\\\"> <slot></slot> </div> </template> \";\n// Exports\nexport default code;","// Module\nvar code = \"<template class=\\\"content-editor-inspector\\\"> <template if.to-view=\\\"layoutContainer.id\\\"></template> <div class=\\\"h6 content-editor-inspector__header\\\"> <span class=\\\"h6 content-editor-inspector__header-text\\\" t=\\\"pages.content-editor.${modeTk}\\\"></span> <safe-icon class=\\\"content-editor-inspector__icon-close\\\" icon-name=\\\"System/Close\\\" click.delegate=\\\"handleClose()\\\"></safe-icon> </div> <div if.to-view=\\\"layoutContainer == null\\\" class=\\\"content-editor-inspector__no-selection\\\"> <safe-icon class=\\\"content-editor-inspector__icon-no-selection\\\" icon-name=\\\"Uce/Dots\\\"></safe-icon> <p class=\\\"content-editor-inspector__no-selection-message\\\" t=\\\"pages.content-editor.inspector.select${selectMessageTk}\\\"></p> </div> <div else> <content-editor-inspector-section title-tk=\\\"pages.content-editor.inspector.attributes\\\"> <content-editor-inspector-section-attributes layout-container-id.to-view=\\\"layoutContainerId\\\" context-identifier.to-view=\\\"contextIdentifier\\\" container-mode.to-view=\\\"inspectorMode === InspectorMode.Container\\\" spacing-available.from-view=\\\"spacingAvailable\\\" sizing-available.from-view=\\\"sizingAvailable\\\"></content-editor-inspector-section-attributes> </content-editor-inspector-section> <template if.to-view=\\\"spacingAvailable && inspectorMode === InspectorMode.Element\\\"> <div class=\\\"content-editor-inspector__separator\\\"></div> <content-editor-inspector-section title-tk=\\\"pages.content-editor.inspector.spacing\\\"> <content-editor-inspector-section-sizing layout-container-id.to-view=\\\"layoutContainerId\\\" context-identifier.to-view=\\\"contextIdentifier\\\"></content-editor-inspector-section-sizing> </content-editor-inspector-section> <div class=\\\"content-editor-inspector__separator\\\"></div> </template> <template if.to-view=\\\"sizingAvailable && inspectorMode === InspectorMode.Element\\\"> <content-editor-inspector-section title-tk=\\\"pages.content-editor.inspector.alignment\\\"> <content-editor-inspector-section-alignment layout-container-id.to-view=\\\"layoutContainerId\\\" context-identifier.to-view=\\\"contextIdentifier\\\"></content-editor-inspector-section-alignment> </content-editor-inspector-section> </template> <div class=\\\"content-editor-inspector__separator\\\"></div> <content-editor-inspector-section title-tk=\\\"pages.content-editor.inspector.style${styleTk}\\\"> <content-editor-inspector-section-styles layout-container-id.to-view=\\\"layoutContainerId\\\" context-identifier.to-view=\\\"contextIdentifier\\\"></content-editor-inspector-section-styles> </content-editor-inspector-section> <template if.to-view=\\\"inspectorMode === InspectorMode.Container || cardSelected\\\"> <div class=\\\"content-editor-inspector__separator content-editor-inspector__separator--container\\\"></div> <button-standard class=\\\"content-editor-inspector__button-standard\\\" t=\\\"[btnText]pages.content-editor.inspector.redistribute\\\" click.delegate=\\\"redistributeChildren()\\\" icon-name=\\\"Uce/Wand\\\" btn-color=\\\"secondary\\\" btn-fill-mode=\\\"fill-width-align-left\\\"></button-standard> <button-standard if.to-view=\\\"inspectorMode === InspectorMode.Container\\\" class=\\\"content-editor-inspector__button-standard\\\" t=\\\"[btnText]pages.content-editor.inspector.delete\\\" click.delegate=\\\"deleteContainer()\\\" icon-name=\\\"Uce/Trash\\\" btn-type=\\\"outline\\\" btn-color=\\\"danger\\\" btn-fill-mode=\\\"fill-width-align-left\\\"></button-standard> </template> </div> </template>\";\n// Exports\nexport default code;","import { autoinject, bindable } from 'aurelia-framework';\nimport { SiteThemer } from 'common/aurelia-classes/SiteThemer';\nimport { ThemeColor } from 'common/enum/theme.enums';\nimport { HEX_COLOR_PATTERN } from '../../../globals/colors';\n\n@autoinject()\nexport class ColorSelect {\n  @bindable() public title = '';\n  @bindable() public colors: Array<ThemeColor> = [];\n  @bindable() public value: string | null = null;\n  @bindable() public showAltSelect: boolean = false;\n\n  private hexColorPattern = HEX_COLOR_PATTERN;\n  private pickerValue: string | null = null;\n\n  constructor(\n    private siteThemer: SiteThemer,\n  ) { }\n\n  private valueChanged(): void {\n    if(this.value) {\n      this.pickerValue = this.getColorValue(this.value as ThemeColor);\n    }\n  }\n\n  private handleColorSelected(color: ThemeColor): void {\n    this.value = color;\n  }\n\n  private updatePicker(): void {\n    const formattedColor = this.value?.length === 4\n      ? this.value.split('')\n        .map(item => item === '#' ? item : item + item)\n        .join('')\n      : this.getColorValue(this.value as ThemeColor);\n    this.pickerValue = formattedColor;\n  }\n\n  private resetValues(): void {\n    this.pickerValue = null;\n    this.value = null;\n  }\n\n  private getColorValue(color: ThemeColor): string {\n    return this.siteThemer.getThemeColor(color);\n  }\n}\n","import { FrameworkConfiguration, PLATFORM } from 'aurelia-framework';\n\nexport function configure(config: FrameworkConfiguration): void {\n  config.globalResources(PLATFORM.moduleName('resources/elements/content-editor-clipboard-card-preview/preview-clipboard-card-layout-container/preview-clipboard-card-layout-container'));\n  config.globalResources(PLATFORM.moduleName('resources/elements/content-editor-clipboard-card-preview/preview-clipboard-card-block/preview-clipboard-card-block'));\n}\n","import { autoinject, bindable, computedFrom } from 'aurelia-framework';\nimport { selectState } from 'common/aurelia-decorators/select-state';\nimport { UniversalBlock } from 'common/dto/content-editor/content.editor.interface';\nimport { BlockType } from 'common/dto/course/content/course.types';\nimport { GenericFitAndFill } from 'common/enum/content.enum';\nimport { CssUtils } from 'common/utils/CssUtils';\nimport { blockByIdSelectorCreator } from 'store/clipboard.selectors';\n\n@autoinject()\nexport class PreviewClipboardCardBlock {\n  @bindable() public blockId: number | null = null;\n\n  @selectState(PreviewClipboardCardBlock, blockByIdSelectorCreator, ['blockId']) private block?: UniversalBlock | null;\n  private BlockType = BlockType;\n\n  // show picture block as background image for easy display in card preview.\n  @computedFrom('block.picture.url', 'block.styleFillMode')\n  private get style(): Record<string, unknown> {\n    const style: Record<string, unknown> = {};\n    if(this.block?.picture?.url) {\n      style['background-image'] = CssUtils.imageUrl(this.block.picture.url);\n      style['background-position'] = 'center';\n      style['background-repeat'] = 'no-repeat';\n      style['height'] = '100%';\n      if(this.block.styleFillMode) {\n        // close approach for simple display of styleFillMode in case of presentation:\n        switch(this.block.styleFillMode) {\n          case GenericFitAndFill.Fill:\n            style['background-size'] = 'cover';\n            break;\n          default:\n            style['background-size'] = 'contain';\n        }\n      } else {\n        // for course-page content default to contain\n        style['background-size'] = 'contain';\n      }\n    }\n\n    return style;\n  }\n}\n\n","import { autoinject, bindable, ObserverLocator, Parser } from 'aurelia-framework';\nimport { LayoutStyles } from 'common/aurelia-components/content-editor/universal-layout-container/universal-layout-container';\nimport { selectState, SelectStateObservableComponent } from 'common/aurelia-decorators/select-state';\nimport { UniversalLayoutContainer } from 'common/dto/content-editor/content.editor.interface';\nimport { CornerStyle, LayoutContainerDirection, LayoutContainerType } from 'common/dto/course/layout.container.interface';\nimport {\n  cardLayoutContainerByIdSelectorCreator,\n  layoutContainerByIdSelectorCreator,\n  layoutContainerChildIdsOrderedSelectorCreator,\n  layoutContainerItemSizeOrderedSelectorCreator,\n} from 'store/clipboard.selectors';\n\nenum Mode {\n  Block = 'block',\n  Children = 'children',\n}\n\n@autoinject()\nexport class PreviewClipboardCardLayoutContainer extends SelectStateObservableComponent {\n  @bindable() public layoutContainerId: number | null = null;\n\n  @selectState(PreviewClipboardCardLayoutContainer, cardLayoutContainerByIdSelectorCreator, ['layoutContainerId']) private cardLayoutContainer?: UniversalLayoutContainer | null;\n  @selectState(PreviewClipboardCardLayoutContainer, layoutContainerByIdSelectorCreator, ['layoutContainerId']) private childLayoutContainer?: UniversalLayoutContainer | null;\n  @selectState(PreviewClipboardCardLayoutContainer, layoutContainerChildIdsOrderedSelectorCreator, ['layoutContainerId']) private orderedChildIds?: number[];\n  @selectState(PreviewClipboardCardLayoutContainer, layoutContainerItemSizeOrderedSelectorCreator, ['layoutContainerId']) private orderedItemSizes?: number[];\n  private layoutContainer: UniversalLayoutContainer | null = null;\n  private styleClasses: string | null = null;\n  private layoutStyles: LayoutStyles | null = null;\n  private mode: Mode | null = null;\n  private domElement: HTMLElement;\n  private scaleFactor = 0.5;\n\n  constructor(\n    element: Element,\n    parser: Parser,\n    observerLocator: ObserverLocator,\n  ) {\n    super(parser, observerLocator);\n    this.domElement = element as HTMLElement;\n  }\n\n  private cardLayoutContainerChanged(): void {\n    if(this.cardLayoutContainer != null) {\n      this.layoutContainer = this.cardLayoutContainer;\n      this.updateStyles();\n      this.updateContentStyles();\n    }\n  }\n\n  private childLayoutContainerChanged(): void {\n    if(this.childLayoutContainer != null) {\n      this.layoutContainer = this.childLayoutContainer;\n      this.updateStyles();\n      this.updateContentStyles();\n    }\n  }\n\n  private orderedItemSizesChanged(): void {\n    this.updateContentStyles();\n  }\n\n  private updateStyles(): void {\n    const styles = ['preview-clipboard-card-layout-container'];\n\n    if(this.layoutContainer != null) {\n      this.mode = this.layoutContainer.type === LayoutContainerType.Block ? Mode.Block : Mode.Children;\n      styles.push(`preview-clipboard-card-layout-container--content-mode-${this.mode}`);\n\n      const {\n        border,\n        shadow,\n        spacing,\n        corner,\n      } = this.layoutContainer.style;\n      const prefix = 'preview-clipboard-card-layout-container--style';\n\n      if(border) styles.push(`${prefix}-border`);\n      if(shadow) styles.push(`${prefix}-shadow`);\n      if(spacing) styles.push(`${prefix}-spacing`);\n      if(corner === CornerStyle.Rounded) styles.push(`${prefix}-rounded-corners`);\n\n      if(this.domElement.isConnected) {\n        const { backgroundColor } = this.layoutContainer.style;\n        this.domElement.style.setProperty('--preview-clipboard-card-layout-container-background-color', backgroundColor != null\n          ? backgroundColor\n          : 'transparent');\n      }\n    }\n    this.styleClasses = styles.join(' ');\n  }\n\n  private updateContentStyles(): void {\n    if(this.layoutContainer == null || this.orderedItemSizes == null) {\n      this.layoutStyles = null;\n      return;\n    }\n\n    const { blockId, layout: { direction } } = this.layoutContainer;\n\n    if(blockId != null) {\n      this.layoutStyles = null;\n      return;\n    }\n\n    const horizontal = direction === LayoutContainerDirection.Horizontal;\n    const gridValue = this.orderedItemSizes.map(itemSize => `minmax(0, ${Math.abs(itemSize).toFixed(0)}fr)`).join(' ');\n\n    this.layoutStyles = {\n      'grid-template-columns': horizontal ? gridValue : '1fr',\n      'grid-template-rows': horizontal ? '1fr' : gridValue,\n    };\n  }\n}\n","import { autoinject, bindable } from 'aurelia-framework';\nimport { SiteThemer } from 'common/aurelia-classes/SiteThemer';\nimport { StoreService } from 'common/aurelia-services/StoreService';\nimport { ThemeColor } from 'common/enum/theme.enums';\nimport { DomUtils } from 'common/utils/DomUtils';\nimport { IState } from '../../../store/state';\nimport { HEX_COLOR_PATTERN } from '../../../globals/colors';\n\n/**\n * @event {ColorSelectedEvent} color-selected\n */\n@autoinject()\nexport class ContentEditorColorSelect {\n  @bindable() public currentColor: string | null = null;\n  private value: string | null = null;\n  private pickerValue: string | null = null;\n  private lastEmittedValue: string | null = null;\n\n  private domElement: HTMLElement;\n  private colorPickerDomElement: HTMLInputElement | null = null;\n\n  private hexColorPattern = HEX_COLOR_PATTERN;\n  private colors: Array<ThemeColor> = [];\n\n  constructor(\n    private siteThemer: SiteThemer,\n    private storeService: StoreService<IState>,\n    element: Element\n  ) {\n    this.domElement = element as HTMLElement;\n  }\n\n  protected attached(): void {\n    this.storeService.subscribeToDetailedChanges(this, [\n      state => state.contentEditor,\n    ], (_state, contentEditorState) => {\n      this.colors = contentEditorState.themeColors;\n    });\n  }\n\n  protected detached(): void {\n    this.storeService.disposeAllSubscriptions(this);\n  }\n\n  private currentColorChanged(): void {\n    if(this.currentColor) {\n      this.pickerValue = this.currentColor;\n      this.value = this.currentColor;\n    } else {\n      this.pickerValue = null;\n      this.value = null;\n    }\n  }\n\n  private resetColor(): void {\n    this.value = null;\n    this.pickerValue = null;\n    this.fireColorSelectedEvent();\n  }\n\n  private getColorValue(color: ThemeColor): string {\n    return this.siteThemer.getThemeColor(color);\n  }\n\n  private handleColorSelected(color: string): void {\n    this.value = color;\n    this.updatePicker();\n    this.fireColorSelectedEvent();\n  }\n\n  private handleColorPicked(): void {\n    this.value = this.pickerValue;\n    this.updatePicker();\n    this.fireColorSelectedEvent();\n  }\n\n  private fireColorSelectedEvent(): void {\n    const color = this.value || null;\n    if(color === this.lastEmittedValue) return;\n\n    DomUtils.fireEvent<ColorSelectedEvent['detail']>(this.domElement, {\n      name: 'color-selected',\n      bubbles: false,\n      detail: { color }\n    });\n    this.lastEmittedValue = color;\n  }\n\n  private updatePicker(): void {\n    const formattedColor = this.value?.length === 4\n      ? this.value.split('')\n        .map(item => item === '#' ? item : item + item)\n        .join('')\n      : this.value;\n    this.pickerValue = formattedColor;\n    this.fireColorSelectedEvent();\n  }\n\n  private showPicker(): void {\n    this.colorPickerDomElement?.click();\n    this.colorPickerDomElement?.focus();\n  }\n}\n\nexport type ColorSelectedEvent = CustomEvent & { detail: { color: string } };\n","import { FrameworkConfiguration, PLATFORM } from 'aurelia-framework';\n\nexport function configure(config: FrameworkConfiguration): void {\n  config.globalResources(PLATFORM.moduleName('resources/elements/content-editor-color-select/content-editor-color-select'));\n  config.globalResources(PLATFORM.moduleName('resources/elements/content-editor-color-select/content-editor-color-select-preview/content-editor-color-select-preview.html'));\n}\n","import { autoinject, bindable, computedFrom } from 'aurelia-framework';\nimport { IImageCropperData } from 'common/aurelia-components/image-cropper/image-cropper';\nimport { selectState } from 'common/aurelia-decorators/select-state';\nimport { StoreService } from 'common/aurelia-services/StoreService';\nimport { UniversalBlock } from 'common/dto/content-editor/content.editor.interface';\nimport { ContentElementType } from 'common/dto/content-editor/content.editor.types';\nimport { IPictureCropOptionsDto } from 'common/dto/content/pictures/picture.block.render.options.interface';\nimport { BlockType } from 'common/dto/course/content/course.types';\nimport { ILayoutContainerDto, LayoutContainerType } from 'common/dto/course/layout.container.interface';\nimport { PipVideoPosition } from 'common/enum/block.style.enum';\nimport { GalleryMediaType } from 'common/enum/gallery.enum';\nimport * as ContentContextMutations from 'common/store/mutations/content.context.mutations';\nimport { blockByIdSelectorCreator, isPresentationSelectorCreator } from 'common/store/selectors/content.context.selectors';\nimport { isIasSelectorCreator } from 'common/store/selectors/course.context.selectors';\nimport { layoutContainerByIdSelectorCreator } from 'common/store/selectors/presentation.context.selectors';\nimport { BlockUtils } from 'common/utils/BlockUtils';\nimport { assertNotNullOrUndefined } from 'common/utils/assert';\nimport { CustomDialogService } from '../../../services/CustomDialogService';\nimport { DndPayloadUniversal } from '../../../services/DndManagerService';\nimport { ContentEditorApiService } from '../../../services/api/ContentEditorApiService';\nimport * as ContentEditorMutations from '../../../store/content.editor.mutations';\nimport { IState, UceSidebarContent } from '../../../store/state';\nimport { InspectorMode } from './../../../store/state';\n\n@autoinject()\nexport class ContentEditorContainerOptions {\n  @bindable() public layoutContainerId: number | null = null;\n  @bindable() public contextIdentifier: string | null = null;\n  @bindable() public containerMode = false;\n  // used for cards only -> special style and enabling dnd via options menu\n  @bindable() public selected = false;\n  @bindable() public dndPayload: DndPayloadUniversal<ContentElementType> | null = null;\n  @bindable() public dndAllowed = false;\n  @bindable() public dndActive = false;\n  @bindable() public dndContext = false;\n\n  @selectState(\n    ContentEditorContainerOptions,\n    layoutContainerByIdSelectorCreator,\n    ['contextIdentifier', 'layoutContainerId']\n  ) private layoutContainer?: ILayoutContainerDto | null;\n  @selectState(\n    ContentEditorContainerOptions,\n    isIasSelectorCreator,\n    ['contextIdentifier'],\n  ) private isIas?: boolean = false;\n  @selectState(\n    ContentEditorContainerOptions,\n    isPresentationSelectorCreator,\n    ['contextIdentifier']\n  ) private isPresentation?: boolean | null;\n\n  private inspectorMode: InspectorMode | null = null;\n  private containerSelectedInInspector = false;\n  private disableInspector = false;\n  private block: UniversalBlock | null = null;\n  private isDualVideo = false;\n  private isVideo = false;\n  private BlockType = BlockType;\n  private oldBlockId?: number | null = null;\n  private element: HTMLElement;\n\n  constructor(\n    element: Element,\n    private storeService: StoreService<IState>,\n    private contentEditorApi: ContentEditorApiService,\n    private customDialogService: CustomDialogService,\n  ) {\n    this.element = element as HTMLElement;\n  }\n\n  protected attached(): void {\n    this.subscribeToState();\n  }\n\n  protected detached(): void {\n    this.storeService.disposeAllSubscriptions(this);\n  }\n\n  private contextIdentifierChanged(): void {\n    this.subscribeToState();\n  }\n\n  private layoutContainerChanged(): void {\n    if(this.oldBlockId !== this.layoutContainer?.blockId) {\n      this.oldBlockId = this.layoutContainer?.blockId;\n      this.subscribeToState();\n    }\n  }\n\n  private subscribeToState(): void {\n    if(!this.element.isConnected) return;\n    this.storeService.disposeAllSubscriptions(this);\n\n    const { contextIdentifier } = this;\n    if(contextIdentifier == null) {\n      this.block = null;\n      return;\n    }\n\n    this.storeService.subscribeToDetailedChanges(this, [\n      state => state.contentEditor.inspector.mode,\n    ], (_state, inspectorMode) => {\n      this.inspectorMode = inspectorMode;\n    });\n\n    if(this.layoutContainer?.blockId == null) {\n      /**\n       * an old block reference could still be lingering, which won't be updated\n       * for root layout-containers. this would result in a misfitting options menu.\n       */\n      this.block = null;\n      return;\n    }\n\n    this.storeService.subscribeMemoized(\n      this,\n      blockByIdSelectorCreator,\n      block => {\n        this.block = block;\n        this.isDualVideo = !!block && BlockUtils.isDualVideoBlock(block);\n        this.isVideo = !!block && BlockUtils.isVideoBlock(block);\n        this.disableInspector = !!block\n          && [\n            BlockType.MP_FLIPPING_CARD,\n            BlockType.MP_HOT_SPOT,\n            BlockType.MP_INTERACTIVE_TEXT,\n            BlockType.MP_RFG,\n            BlockType.MP_RISI,\n            BlockType.MP_SCORM,\n          ].includes(block.type);\n      }, { contextIdentifier, blockId: this.layoutContainer.blockId },\n    );\n  }\n\n  @computedFrom('layoutContainer.blockId')\n  protected get blockId(): number | null {\n    return this.layoutContainer?.blockId ?? null;\n  }\n\n  @computedFrom('layoutContainer')\n  protected get displayCardOptions(): boolean {\n    return this.layoutContainer != null\n      ? this.layoutContainer.type === LayoutContainerType.Card\n      : false;\n  }\n\n  private openInspectorForLayoutContainer(): void {\n    if(this.inspectorMode === InspectorMode.Inactive) {\n      this.storeService.dispatch(\n        ContentEditorMutations.openSidebarRight,\n        UceSidebarContent.Inspector,\n      );\n    }\n    assertNotNullOrUndefined(this.layoutContainer?.id, 'layoutContainer.id cannot be null or undefined');\n    this.storeService.dispatch(\n      ContentEditorMutations.updateInspector,\n      this.layoutContainer.id,\n      this.layoutContainer.type === LayoutContainerType.Layout ? InspectorMode.Container : InspectorMode.Element,\n    );\n  }\n\n  private async removeContainer(): Promise<void> {\n    assertNotNullOrUndefined(this.contextIdentifier, 'contextIdentifier cannot be null or undefined');\n    assertNotNullOrUndefined(this.layoutContainer?.id, 'layoutContainer.id cannot be null or undefined');\n    if(this.containerSelectedInInspector) {\n      await this.storeService.dispatch(ContentEditorMutations.updateInspector, null);\n    }\n    const changes = await this.contentEditorApi.removeLayoutContainer(this.layoutContainer.id);\n    await this.storeService\n      .pipe(ContentContextMutations.applyLayoutChanges, this.contextIdentifier, changes)\n      .pipe(ContentEditorMutations.updateContainerStructure, this.contextIdentifier)\n      .pipe(ContentEditorMutations.resetContainerHoverState)\n      .dispatch();\n  }\n\n  // handles changing picture, file, video, question, formula\n  private async changeContent(): Promise<void> {\n    assertNotNullOrUndefined(this.block, 'block cannot be null or undefined');\n    assertNotNullOrUndefined(this.contextIdentifier, 'contextIdentifier cannot be null or undefined');\n\n    await this.storeService.dispatch(ContentEditorMutations.updateEditBlockId, null);\n    let questionIds: number[] = [];\n    if('questions' in this.block) {\n      questionIds = this.block.questions?.map(q => q.id) ?? [];\n    }\n    if('questionIds' in this.block) {\n      ({ questionIds } = this.block);\n    }\n    const updateBlockDto = await this.customDialogService.showContentEditorBlockEditorDialog({\n      contextIdentifier: this.contextIdentifier,\n      blockId: this.block.id,\n      block: {\n        ...this.block,\n        questionIds\n      },\n    });\n\n    if(updateBlockDto == null) return;\n\n    const updatedBlock = await this.contentEditorApi.updateBlock<UniversalBlock>(this.block.id, {\n      ...updateBlockDto\n    });\n    await this.storeService.dispatch(ContentContextMutations.updateBlock, this.contextIdentifier, updatedBlock);\n  }\n\n  private async removeImage(): Promise<void> {\n    assertNotNullOrUndefined(this.contextIdentifier, 'contextIdentifier cannot be null or undefined');\n    assertNotNullOrUndefined(this.block, 'block cannot be null or undefined');\n\n    const updatedBlock = await this.contentEditorApi\n      .updateBlock<UniversalBlock>(this.block.id, { pictureId: null });\n    await this.storeService.dispatch(ContentContextMutations.updateBlock, this.contextIdentifier, updatedBlock);\n  }\n\n  private async handlePictureCrop(): Promise<void> {\n    assertNotNullOrUndefined(this.contextIdentifier, 'contextIdentifier cannot be null or undefined');\n    assertNotNullOrUndefined(this.block?.picture?.url, 'block.picture.url cannot be null or undefined');\n    assertNotNullOrUndefined(this.block?.picture.width, 'block.picture.width cannot be null or undefined');\n    assertNotNullOrUndefined(this.block?.picture.height, 'block.picture.height cannot be null or undefined');\n\n    const initialData: IImageCropperData | undefined = this.block?.pictureBlockRenderOptions ? {\n      top: this.block.pictureBlockRenderOptions.top,\n      bottom: this.block.pictureBlockRenderOptions.bottom,\n      left: this.block.pictureBlockRenderOptions.left,\n      right: this.block.pictureBlockRenderOptions.right,\n      angle: this.block.pictureBlockRenderOptions.orientation,\n      flipped: this.block.pictureBlockRenderOptions.flipped\n    } : undefined;\n    const url = this.block?.originalPictureUrl ?? this.block?.picture.url;\n    const cropperData = await this.customDialogService.showCropImageDialog({ initialData, imageUrl: url });\n    if(!cropperData) return;\n\n    const dto: IPictureCropOptionsDto = {\n      top: cropperData.top,\n      bottom: cropperData.bottom,\n      left: cropperData.left,\n      right: cropperData.right,\n      orientation: cropperData.angle,\n      flipped: cropperData.flipped\n    };\n    const updatedBlock = await this.contentEditorApi.updatePictureBlockRenderOptions<UniversalBlock>(this.block.id, dto);\n    await this.storeService.dispatch(ContentContextMutations.updateBlock, this.contextIdentifier, updatedBlock);\n  }\n\n  private async handleVideoPip(): Promise<void> {\n    assertNotNullOrUndefined(this.contextIdentifier, 'contextIdentifier cannot be null or undefined');\n    assertNotNullOrUndefined(this.block, 'block cannot be null or undefined');\n\n    const pip = await this.customDialogService.showMediaSelect({\n      selectedMediaType: GalleryMediaType.Video,\n      preselectedMediaType: GalleryMediaType.Video,\n      showMediaTypeFilter: false,\n      preselectedMediaId: this.block.pipVideoId\n    });\n\n    const updatedBlock = await this.contentEditorApi.updateBlock<UniversalBlock>(this.block.id, {\n      pipVideoId: pip?.value.id,\n    });\n\n    await this.storeService.dispatch(ContentContextMutations.updateBlock, this.contextIdentifier, updatedBlock);\n  }\n\n  private async handleVideoPipSide(): Promise<void> {\n    assertNotNullOrUndefined(this.contextIdentifier, 'contextIdentifier cannot be null or undefined');\n    assertNotNullOrUndefined(this.block, 'block cannot be null or undefined');\n\n    const updatedBlock = await this.contentEditorApi.updateBlock<UniversalBlock>(this.block.id, {\n      pipVideoPosition: this.block.pipVideoPosition === PipVideoPosition.TopRight ? PipVideoPosition.TopLeft : PipVideoPosition.TopRight,\n    });\n\n    await this.storeService.dispatch(ContentContextMutations.updateBlock, this.contextIdentifier, updatedBlock);\n  }\n\n  private async handleVideoPipOff(): Promise<void> {\n    assertNotNullOrUndefined(this.contextIdentifier, 'contextIdentifier cannot be null or undefined');\n    assertNotNullOrUndefined(this.block, 'block cannot be null or undefined');\n\n    const updatedBlock = await this.contentEditorApi.updateBlock<UniversalBlock>(this.block.id, {\n      pipVideoId: null,\n    });\n\n    await this.storeService.dispatch(ContentContextMutations.updateBlock, this.contextIdentifier, updatedBlock);\n  }\n\n  private async copyContent(): Promise<void> {\n    assertNotNullOrUndefined(this.contextIdentifier, 'contextIdentifier cannot be null or undefined');\n    assertNotNullOrUndefined(this.layoutContainer?.id, 'layoutContainer.id cannot be null or undefined');\n\n    const changes = await this.contentEditorApi.copyElement(this.layoutContainer.id);\n    await this.storeService\n      .pipe(ContentContextMutations.applyLayoutChanges, this.contextIdentifier, changes)\n      .pipe(ContentEditorMutations.updateContainerStructure, this.contextIdentifier)\n      .pipe(ContentEditorMutations.resetContainerHoverState)\n      .dispatch();\n  }\n}\n","import { bindable } from 'aurelia-framework';\n\nexport class ContentEditorDraggedBlock {\n  @bindable() public iconName: string | null = null;\n  @bindable() public modifierIconName: string | null = null;\n}\n","import { autoinject, bindable } from 'aurelia-framework';\nimport { SubscriptionManager, SubscriptionManagerService } from 'common/aurelia-services/SubscriptionManagerService';\nimport { DomUtils } from 'common/utils/DomUtils';\nimport { ButtonSize } from '../button-standard/button-standard';\n\n/**\n * @event SelectedEnumOptionChangedEvent with name 'selected-enum-option-changed'\n */\n@autoinject()\nexport class ContentEditorEnumOptions<TEnum> {\n  @bindable() public items: Array<IEnumOptionItem<TEnum>> = [];\n  @bindable() public selectedOptionUpdate: TEnum | null = null;\n  @bindable() public tooltipTk: string | null = null;\n  @bindable() public btnSize: ButtonSize = ButtonSize.Icon;\n\n  private selectedOption: TEnum | null = null;\n  private selectedOptionIcon: string | null = null;\n  private subscriptionManager: SubscriptionManager;\n  private domElement: HTMLElement;\n  private showMenu = false;\n\n  constructor(\n    element: Element,\n    subscriptionManagerService: SubscriptionManagerService,\n  ) {\n    this.domElement = element as HTMLElement;\n    this.subscriptionManager = subscriptionManagerService.createSubscriptionManager();\n  }\n\n  protected attached(): void {\n    this.updateSelectedOption(this.selectedOptionUpdate);\n\n    this.subscriptionManager.subscribeToClickOutside(\n      this.domElement,\n      () => { this.showMenu = false; },\n    );\n  }\n\n  protected detached(): void {\n    this.subscriptionManager.disposeSubscriptions();\n  }\n\n  private selectedOptionUpdateChanged(): void {\n    this.updateSelectedOption(this.selectedOptionUpdate);\n  }\n\n  private handleOptionSelected(selectedOption: TEnum): void {\n    if(selectedOption === this.selectedOption) return;\n    this.updateSelectedOption(selectedOption);\n\n    DomUtils.fireEvent(this.domElement, {\n      name: 'selected-enum-option-changed',\n      bubbles: true,\n      detail: { option: selectedOption },\n    });\n    this.showMenu = false;\n  }\n\n  private updateSelectedOption(selectedOption: TEnum | null): void {\n    this.selectedOption = selectedOption;\n    this.selectedOptionIcon = this.items.find(item => item.option === this.selectedOption)?.icon ?? '';\n  }\n}\n\nexport interface IEnumOptionItem<TEnum> {\n  option: TEnum;\n  icon: string;\n  textTk: string;\n}\n\nexport type SelectedEnumOptionChangedEvent<TEnum> = Event & { detail: { option: TEnum } };\n","import { autoinject, bindable, computedFrom, observable } from 'aurelia-framework';\nimport { Router } from 'aurelia-router';\nimport { ButtonLightswitchValueChangedEvent } from 'common/aurelia-components/button-lightswitch/button-lightswitch';\nimport { selectState } from 'common/aurelia-decorators/select-state';\nimport { StoreService } from 'common/aurelia-services/StoreService';\nimport { IRoleAssignment } from 'common/dto/auth/auth.interface';\nimport { ContentElementType } from 'common/dto/content-editor/content.editor.types';\nimport { BlockType } from 'common/dto/course/content/course.types';\nimport { ErrorType } from 'common/enum/errortype.enum';\nimport { RoleName } from 'common/enum/role.enums';\nimport * as ContentContextMutations from 'common/store/mutations/content.context.mutations';\nimport { courseContentSelectorCreator, isIasSelectorCreator, isInspectorDisabledSelectorCreator } from 'common/store/selectors/course.context.selectors';\nimport { presentationContentSelectorCreator } from 'common/store/selectors/presentation.context.selectors';\nimport { assertNotNullOrUndefined } from 'common/utils/assert';\nimport { BlockUtils } from 'common/utils/BlockUtils';\nimport { LogUtils } from 'common/utils/LogUtils';\nimport { ContentEditorApiService } from '../../../services/api/ContentEditorApiService';\nimport { PresentationManagementApiService } from '../../../services/api/PresentationManagementApiService';\nimport {\n  DndContext,\n  DndManager,\n  DndManagerService,\n  DndPayloadUniversal,\n  DndSubContext,\n} from '../../../services/DndManagerService';\nimport { IndexedDbChangedMessage, SeparateWindowService, SeparateWindowType } from '../../../services/SeparateWindowService';\nimport { ToastService } from '../../../services/ToastService';\nimport * as ContentEditorMutations from '../../../store/content.editor.mutations';\nimport { updateContainerStylesState } from '../../../store/content.editor.mutations';\nimport { InspectorMode, IState } from '../../../store/state';\nimport { ContentEditorMode } from '../../pages/content-editor/content-editor';\nimport { InlineEditField, InlineEditSaveEvent, InlineEditValidationFailedEvent } from '../inline-edit-field/inline-edit-field';\nimport { UceSidebarContent } from './../../../store/state';\n\n@autoinject()\nexport class ContentEditorHeaderBar {\n  @bindable() public contextIdentifier: string | null = null;\n\n  @selectState(ContentEditorHeaderBar, isIasSelectorCreator, ['contextIdentifier']) private isIas?: boolean = false;\n  @selectState(\n    ContentEditorHeaderBar,\n    isInspectorDisabledSelectorCreator,\n    ['contextIdentifier'],\n  ) private isInspectorDisabled?: boolean = false;\n\n  private courseId: number | null = null;\n  private presentationId: number | null = null;\n  private title: string | null = null;\n  private isShared: boolean = false;\n\n  private currentRole: IRoleAssignment<string> | null = null;\n\n  private ContentEditorMode = ContentEditorMode;\n  private dndActive = false;\n  private dndContext = DndContext.ContentEditorLayout;\n\n  private editorMode: ContentEditorMode = ContentEditorMode.PRESENTATION;\n  private domElement: HTMLElement;\n  private titleInlineEditField: InlineEditField | null = null;\n  private draggedContentElements: HTMLElement[] = [];\n  private dndPayload: DndPayloadUniversal<ContentElementType> = null;\n  private dndManager: DndManager<ContentElementType> | null = null;\n  private DndPayloadSource = DndSubContext;\n\n  @observable() private inspectorMode: InspectorMode | null = null;\n  private InspectorMode = InspectorMode;\n  private sidebarRightContent: UceSidebarContent | null = null;\n  private sidebarRightOpen = false;\n  private containerMode = false;\n  private ignoreContainerModeOffByApplication = false;\n\n  constructor(\n    element: Element,\n    private storeService: StoreService<IState>,\n    private router: Router,\n    private dndManagerService: DndManagerService,\n    private toastService: ToastService,\n    private separateWindowService: SeparateWindowService,\n    private contentEditorApi: ContentEditorApiService,\n    private presentationManagementApi: PresentationManagementApiService,\n  ) {\n    this.domElement = element as HTMLElement;\n  }\n\n  protected attached(): void {\n    this.dndManager = this.dndManagerService.getDndManager<ContentElementType>(this.dndContext);\n    this.dndManager.subscribePayloadChanged(this, this.dndPayloadChangedHandler.bind(this));\n    this.storeService.subscribeToDetailedChanges(this, [\n      state => state.contentEditor.dragAndDrop.active,\n      state => state.contentEditor.mode\n    ], (_state, active, editorMode) => {\n      this.dndActive = active;\n      this.editorMode = editorMode;\n    });\n    this.subscribeToState();\n  }\n\n  protected detached(): void {\n    this.storeService.disposeAllSubscriptions(this);\n    this.dndManager?.disposeSubscriptions(this);\n  }\n\n  private subscribeToState(): void {\n    this.storeService.disposeAllSubscriptions(this);\n\n    const { contextIdentifier } = this;\n    if(contextIdentifier == null) return;\n\n    this.storeService.subscribeToDetailedChanges(this, [\n      state => state.currentRole,\n    ], (_state, currentRole) => {\n      this.currentRole = currentRole;\n    });\n\n    this.storeService.subscribeMemoized(\n      this,\n      presentationContentSelectorCreator,\n      content => {\n        this.title = content?.title ?? null;\n        this.presentationId = content?.id ?? null;\n      },\n      { contextIdentifier },\n    );\n\n    this.storeService.subscribeMemoized(\n      this,\n      courseContentSelectorCreator,\n      content => {\n        this.title = content?.title ?? null;\n        this.courseId = content?.id ?? null;\n      },\n      { contextIdentifier },\n    );\n\n\n    this.storeService.subscribeToDetailedChanges(this, [\n      state => state.contentContexts,\n      state => state.courseContentById,\n    ], () => {\n      this.separateWindowService.emitCrossTabMessage<IndexedDbChangedMessage>({ type: 'indexeddb-changed', detail: undefined, notifySelf: false });\n    });\n\n    this.storeService.subscribeToDetailedChanges(this, [\n      state => state.contentEditor.sidebarRight,\n      state => state.contentEditor.inspector.mode,\n      state => state.contentEditor.isPresentationShared\n    ], (_state, sidebarRight, inspectorMode, isPresentationShared) => {\n      this.sidebarRightContent = sidebarRight.content;\n      this.sidebarRightOpen = sidebarRight.open;\n      this.inspectorMode = inspectorMode;\n      this.isShared = isPresentationShared;\n    });\n  }\n\n  @computedFrom('sidebarRightContent', 'sidebarRightOpen')\n  private get isSidebarBlocksActive(): boolean | null {\n    return this.sidebarRightContent === UceSidebarContent.Blocks && this.sidebarRightOpen;\n  }\n\n  @computedFrom('sidebarRightContent', 'sidebarRightOpen')\n  private get isSidebarTemplatesActive(): boolean | null {\n    return this.sidebarRightContent === UceSidebarContent.Templates && this.sidebarRightOpen;\n  }\n\n  @computedFrom('sidebarRightContent', 'sidebarRightOpen')\n  private get isSidebarInspectorActive(): boolean | null {\n    return this.sidebarRightContent === UceSidebarContent.Inspector && this.sidebarRightOpen;\n  }\n\n  private inspectorModeChanged(): void {\n    if(this.inspectorMode === InspectorMode.Inactive) {\n      this.ensureContainerModeDisabled();\n    }\n  }\n\n  private isInspectorDisabledChanged(): void {\n    this.closeInspectorIfNecessary();\n  }\n\n  private isIasChanged(): void {\n    this.closeInspectorIfNecessary();\n  }\n\n  private closeInspectorIfNecessary(): void {\n    if((this.isInspectorDisabled || this.isIas) && this.inspectorMode !== InspectorMode.Inactive) {\n      this.ensureContainerModeDisabled(this.inspectorMode === InspectorMode.Container);\n      this.storeService.dispatch(ContentEditorMutations.closeSidebarRight);\n      this.storeService.dispatch(ContentEditorMutations.updateInspector);\n    }\n  }\n\n  private dndPayloadChangedHandler(payload: DndPayloadUniversal<ContentElementType>): void {\n    this.dndPayload = payload;\n  }\n\n  private ensureContainerModeDisabled(condition?: boolean): void {\n    const additionalCondition = condition === undefined ? true : condition;\n    if(this.containerMode && additionalCondition) {\n      this.storeService.dispatch(updateContainerStylesState, { showExtraContainerSpace: false });\n      this.ignoreContainerModeOffByApplication = true;\n      this.containerMode = false;\n    }\n  }\n\n  private ensureInspectorClosed(): void {\n    if(this.inspectorMode !== InspectorMode.Inactive) {\n      this.ensureContainerModeDisabled(this.inspectorMode === InspectorMode.Container);\n      this.storeService.dispatch(ContentEditorMutations.updateInspector);\n    }\n  }\n\n  private toggleSidebarTemplates(): void {\n    this.ensureInspectorClosed();\n    this.storeService.dispatch(\n      ContentEditorMutations.setSidebarRight,\n      UceSidebarContent.Templates,\n    );\n  }\n\n  private toggleSidebarBlocks(): void {\n    this.ensureInspectorClosed();\n    this.storeService.dispatch(\n      ContentEditorMutations.setSidebarRight,\n      UceSidebarContent.Blocks,\n    );\n  }\n\n  private toggleSidebarInspector(): void {\n    assertNotNullOrUndefined(this.contextIdentifier, 'contextIdentifier cannot be null or undefined');\n    const currentSidebarContentInspector = this.sidebarRightContent === UceSidebarContent.Inspector;\n    const showInspector = currentSidebarContentInspector && this.sidebarRightOpen ? false : true;\n\n    this.ensureContainerModeDisabled(!showInspector);\n    this.storeService.dispatch(\n      ContentEditorMutations.setSidebarRight,\n      UceSidebarContent.Inspector,\n    );\n    if(currentSidebarContentInspector) {\n      this.storeService.dispatch(ContentEditorMutations.updateInspector);\n    } else {\n      this.storeService.dispatch(ContentEditorMutations.updateInspector, null, InspectorMode.Element);\n    }\n  }\n\n  private toggleContainerMode(event: ButtonLightswitchValueChangedEvent): void {\n    // only react to user input\n    if(this.ignoreContainerModeOffByApplication) {\n      this.ignoreContainerModeOffByApplication = false;\n      return;\n    }\n    this.containerMode = event.detail.value;\n    /**\n     * Cases:\n     * * Inspector is open, mode is block, this.containerMode is true -> set container mode\n     * * Inspector is open, mode is container, this.containerMode is false -> change inspector mode\n     * * Inspector is closed, this.containerMode is true -> open inspector and set container mode\n     * * Inspector is closed, this.containerMode is false -> do nothing\n     */\n    switch(this.inspectorMode) {\n      case InspectorMode.Element:\n        if(this.containerMode) {\n          this.storeService.dispatch(updateContainerStylesState, { showExtraContainerSpace: true });\n          this.storeService.dispatch(ContentEditorMutations.updateInspector, null, InspectorMode.Container);\n        }\n        break;\n      case InspectorMode.Container:\n        if(!this.containerMode) {\n          this.storeService.dispatch(updateContainerStylesState, { showExtraContainerSpace: false });\n          this.storeService.dispatch(ContentEditorMutations.updateInspector, null, InspectorMode.Element);\n        }\n        break;\n      case InspectorMode.Inactive:\n        if(this.containerMode) {\n          this.storeService.dispatch(\n            ContentEditorMutations.openSidebarRight,\n            UceSidebarContent.Inspector,\n          );\n          this.storeService.dispatch(updateContainerStylesState, { showExtraContainerSpace: true });\n          this.storeService.dispatch(ContentEditorMutations.updateInspector, null, InspectorMode.Container);\n        }\n    }\n  }\n\n  private cleanupSidebarState(): void {\n    if(this.sidebarRightOpen) {\n      this.ensureInspectorClosed();\n      this.storeService.dispatch(ContentEditorMutations.closeSidebarRight);\n    }\n  }\n\n  private navigateBack(): void {\n    this.cleanupSidebarState();\n    const routeName = this.editorMode === ContentEditorMode.PRESENTATION ? 'presentation-overview' : 'courses/id';\n    this.router.navigateToRoute(routeName, { id: this.courseId });\n  }\n\n  private async onSaveTitle(event: InlineEditSaveEvent): Promise<void> {\n    assertNotNullOrUndefined(this.contextIdentifier, 'contextIdentifier cannot be null or undefined');\n    const newTitle = event.detail.value || null;\n\n    if(!newTitle) {\n      const message = this.editorMode === ContentEditorMode.COURSE\n        ? 'pages.content-editor.noTitleErrorCourse'\n        : 'pages.content-editor.noTitleError';\n      this.toastService.error(message);\n      return;\n    }\n\n    try {\n      if(this.editorMode === ContentEditorMode.COURSE) {\n        assertNotNullOrUndefined(this.courseId, 'courseId cannot be null or undefined');\n        await this.contentEditorApi.updateCourse(this.courseId, { title: newTitle });\n      } else {\n        assertNotNullOrUndefined(this.presentationId, 'presentationId cannot be null or undefined');\n        await this.contentEditorApi.updatePresentation(this.presentationId, { title: newTitle });\n      }\n    } catch(e) {\n      if(e.message === ErrorType.COURSE_TITLE_ALREADY_IN_USE) {\n        const message = this.editorMode === ContentEditorMode.COURSE\n          ? 'pages.content-editor.titleExistsErrorCourse'\n          : 'pages.content-editor.titleExistsError';\n        this.toastService.error(message);\n      } else {\n        LogUtils.exception(e);\n      }\n    }\n\n    await this.storeService.dispatch(ContentContextMutations.setTitle, this.contextIdentifier, newTitle);\n  }\n\n  private onTitleValidationFailed(event: InlineEditValidationFailedEvent): void {\n    if(!event.detail.value) {\n      const message = this.editorMode === ContentEditorMode.COURSE\n        ? 'pages.content-editor.noTitleErrorCourse'\n        : 'pages.content-editor.noTitleError';\n      this.toastService.error(message);\n    }\n  }\n\n  @computedFrom('BlockType', 'NonBlockElementType', 'isIas')\n  private get mostUsedContentElementTypes(): BlockType[] {\n    return [\n      BlockType.TEXT,\n      BlockType.PICTURE,\n      BlockType.VIDEO,\n      ...(this.isIas ? [] : [BlockType.SPACER])\n    ];\n  }\n\n  @computedFrom('editorMode', 'currentRole.role')\n  private get showShareWithTenant(): boolean {\n    return this.editorMode === ContentEditorMode.PRESENTATION\n      && this.currentRole != null\n      && this.currentRole.role !== RoleName.Provider;\n  }\n\n  @computedFrom('editorMode')\n  private get deleteTk(): string {\n    return this.editorMode === ContentEditorMode.COURSE\n      ? 'pages.content-editor.deleteCourse'\n      : 'pages.content-editor.deletePresentation';\n  }\n\n  private getIconName(type: ContentElementType): string {\n    return BlockUtils.getIconName(type);\n  }\n\n  private getModifierIconName(type: ContentElementType): string | null{\n    return BlockUtils.getModifierIconName(type);\n  }\n\n  private showPreview(): void {\n    this.separateWindowService.open(SeparateWindowType.ContentEditorPreviewWindow);\n  }\n\n  private async onSharedWithTenantChanged(event: ButtonLightswitchValueChangedEvent): Promise<void> {\n    assertNotNullOrUndefined(this.presentationId, 'presentationId cannot be null or undefined');\n    assertNotNullOrUndefined(this.currentRole?.tenantId, 'currentRole.tenantId cannot be null or undefined');\n\n    if(event.detail.value === this.isShared) return;\n\n    if(event.detail.value) {\n      await this.contentEditorApi.shareWithTenant(this.presentationId, this.currentRole.tenantId);\n    } else {\n      await this.contentEditorApi.unshareWithTenant(this.presentationId, this.currentRole.tenantId);\n    }\n    await this.updateTenantShares();\n  }\n\n  private async onDeletePresentation(): Promise<void> {\n    if(this.editorMode === ContentEditorMode.PRESENTATION) {\n      assertNotNullOrUndefined(this.presentationId, 'presentationId cannot be null or undefined');\n      await this.contentEditorApi.deletePresentation(this.presentationId);\n      this.navigateBack();\n    }\n  }\n\n  private async updateTenantShares(): Promise<void> {\n    if(!this.presentationId || !this.currentRole?.tenantId) return;\n    const isShared = await this.presentationManagementApi.getIsPresentationShared(this.presentationId, this.currentRole.tenantId);\n    await this.storeService.dispatch(ContentEditorMutations.updateIsPresentationShared, isShared);\n  }\n}\n","import { autoinject, bindable } from 'aurelia-framework';\n\n@autoinject()\nexport class ContentEditorIconButton {\n  @bindable() icon = '';\n  @bindable() active = false;\n}\n","import { autoinject, bindable } from 'aurelia-framework';\n\n@autoinject()\nexport class ContentEditorInspectorAttribute {\n  @bindable() public textTk = '';\n  @bindable() public asButton = false;\n}\n","import { autoinject, bindable } from 'aurelia-framework';\nimport { selectState } from 'common/aurelia-decorators/select-state';\nimport { StoreService } from 'common/aurelia-services/StoreService';\nimport {\n  ILayoutContainerDto,\n  LayoutContainerHAlignment,\n  LayoutContainerVAlignment,\n} from 'common/dto/course/layout.container.interface';\nimport * as ContentContextMutations from 'common/store/mutations/content.context.mutations';\nimport { layoutContainerByIdSelectorCreator } from 'common/store/selectors/presentation.context.selectors';\nimport { assertNotNullOrUndefined } from 'common/utils/assert';\nimport { ContentEditorApiService } from 'services/api/ContentEditorApiService';\nimport { IState } from 'store/state';\n\n@autoinject()\nexport class ContentEditorInspectorSectionAlignment {\n  @bindable() public contextIdentifier: string | null = null;\n  @bindable() public layoutContainerId: number | null = null;\n  private LayoutContainerHAlignment = LayoutContainerHAlignment;\n  private LayoutContainerVAlignment = LayoutContainerVAlignment;\n\n  @selectState(\n    ContentEditorInspectorSectionAlignment,\n    layoutContainerByIdSelectorCreator,\n    ['contextIdentifier', 'layoutContainerId']\n  ) private layoutContainer?: ILayoutContainerDto | null;\n\n  constructor(\n    private storeService: StoreService<IState>,\n    private contentEditorApi: ContentEditorApiService,\n  ) { }\n\n  private async setHAlign(align: LayoutContainerHAlignment): Promise<void> {\n    assertNotNullOrUndefined(this.contextIdentifier, 'contextIdentifier cannot be null or undefined');\n    assertNotNullOrUndefined(this.layoutContainerId, 'layoutContainerId cannot be null or undefined');\n    await this.contentEditorApi.updateLayoutContainer(this.layoutContainerId, { styleHorizontalAlignment: align });\n    await this.storeService.dispatch(ContentContextMutations.setLayoutContainerStyle, this.contextIdentifier, this.layoutContainerId, { horizontalAlignment: align });\n  }\n\n  private async setVAlign(align: LayoutContainerVAlignment): Promise<void> {\n    assertNotNullOrUndefined(this.contextIdentifier, 'contextIdentifier cannot be null or undefined');\n    assertNotNullOrUndefined(this.layoutContainerId, 'layoutContainerId cannot be null or undefined');\n    await this.contentEditorApi.updateLayoutContainer(this.layoutContainerId, { styleVerticalAlignment: align });\n    await this.storeService.dispatch(ContentContextMutations.setLayoutContainerStyle, this.contextIdentifier, this.layoutContainerId, { verticalAlignment: align });\n  }\n}\n","import { autoinject, bindable } from 'aurelia-framework';\nimport { selectState } from 'common/aurelia-decorators/select-state';\nimport { StoreService } from 'common/aurelia-services/StoreService';\nimport { UniversalBlock } from 'common/dto/content-editor/content.editor.interface';\nimport { BlockType } from 'common/dto/course/content/course.types';\nimport {\n  CornerStyle,\n  ILayoutContainerDto,\n  LayoutContainerBlockSize,\n  LayoutContainerDirection,\n  LayoutContainerType\n} from 'common/dto/course/layout.container.interface';\nimport { GenericFitAndFill } from 'common/enum/content.enum';\nimport { GalleryMediaType } from 'common/enum/gallery.enum';\nimport * as ContentContextMutations from 'common/store/mutations/content.context.mutations';\nimport { blockByIdSelectorCreator } from 'common/store/selectors/content.context.selectors';\nimport { layoutContainerByIdSelectorCreator } from 'common/store/selectors/presentation.context.selectors';\nimport { assertNotNullOrUndefined } from 'common/utils/assert';\nimport { BlockUtils } from 'common/utils/BlockUtils';\nimport { ContentEditorApiService } from '../../../../services/api/ContentEditorApiService';\nimport { CustomDialogService } from '../../../../services/CustomDialogService';\nimport { IState } from '../../../../store/state';\nimport { ColorSelectedEvent } from '../../../elements/content-editor-color-select/content-editor-color-select';\n\n@autoinject()\nexport class ContentEditorInspectorSectionAttributes {\n  @bindable() public contextIdentifier: string | null = null;\n  @bindable() public layoutContainerId: number | null = null;\n  @bindable() public containerMode = false;\n  @bindable() public sizingAvailable = false;\n  @bindable() public spacingAvailable = false;\n  private LayoutContainerBlockSize = LayoutContainerBlockSize;\n  private LayoutContainerDirection = LayoutContainerDirection;\n  private LayoutContainerType = LayoutContainerType;\n  private CornerStyle = CornerStyle;\n  private block: UniversalBlock | null = null;\n  private showColorSelect = false;\n\n  @selectState(\n    ContentEditorInspectorSectionAttributes,\n    layoutContainerByIdSelectorCreator,\n    ['contextIdentifier', 'layoutContainerId'],\n  ) private layoutContainer?: ILayoutContainerDto | null;\n\n  constructor(\n    private storeService: StoreService<IState>,\n    private contentEditorApi: ContentEditorApiService,\n    private customDialogService: CustomDialogService,\n  ) { }\n\n  protected detached(): void {\n    this.sizingAvailable = false;\n    this.showColorSelect = false;\n    this.storeService.disposeAllSubscriptions(this);\n  }\n\n  private layoutContainerChanged(): void {\n    this.storeService.disposeAllSubscriptions(this);\n    if(this.contextIdentifier == null || this.layoutContainer?.blockId == null) {\n      this.sizingAvailable = false;\n      return;\n    }\n\n    this.storeService.subscribeMemoized(\n      this,\n      blockByIdSelectorCreator,\n      block => {\n        this.block = block;\n        this.sizingAvailable = !!block && BlockUtils.blockAllowsSizing(block);\n        this.spacingAvailable = block?.type === BlockType.TEXT;\n      },\n      {\n        contextIdentifier: this.contextIdentifier,\n        blockId: this.layoutContainer.blockId,\n      },\n    );\n  }\n\n  private async toggleSpacing(): Promise<void> {\n    assertNotNullOrUndefined(this.contextIdentifier, 'contextIdentifier cannot be null or undefined');\n    assertNotNullOrUndefined(this.layoutContainer?.id, 'layoutContainer.id cannot be null or undefined');\n    const styleSpacing = !this.layoutContainer.style.spacing;\n\n    await this.contentEditorApi.updateLayoutContainer(this.layoutContainer.id, { styleSpacing });\n    await this.storeService.dispatch(\n      ContentContextMutations.setLayoutContainerStyle,\n      this.contextIdentifier,\n      this.layoutContainer.id,\n      { spacing: styleSpacing },\n    );\n  }\n\n  private async setBlockSize(size: LayoutContainerBlockSize): Promise<void> {\n    assertNotNullOrUndefined(this.contextIdentifier, 'contextIdentifier cannot be null or undefined');\n    assertNotNullOrUndefined(this.layoutContainerId, 'layoutContainerId cannot be null or undefined');\n    assertNotNullOrUndefined(this.block, 'block cannot be null or undefined');\n\n    if(size === LayoutContainerBlockSize.Full || this.block.styleFillMode === GenericFitAndFill.Fill) {\n      const updatedBlock = await this.contentEditorApi.updateBlock<UniversalBlock>(this.block.id, {\n        styleFillMode: size === LayoutContainerBlockSize.Full ? GenericFitAndFill.Fill : GenericFitAndFill.Original,\n      });\n      await this.storeService.dispatch(\n        ContentContextMutations.updateBlock,\n        this.contextIdentifier,\n        updatedBlock,\n      );\n    }\n\n    await this.contentEditorApi.updateLayoutContainer(this.layoutContainerId, { styleBlockSize: size });\n    await this.storeService.dispatch(\n      ContentContextMutations.setLayoutContainerStyle,\n      this.contextIdentifier,\n      this.layoutContainerId,\n      { blockSize: size },\n    );\n  }\n\n  private toggleColorSelect(): void {\n    this.showColorSelect = !this.showColorSelect;\n  }\n\n  private async handleColorSelected(event: ColorSelectedEvent): Promise<void> {\n    assertNotNullOrUndefined(this.contextIdentifier, 'contextIdentifier cannot be null or undefined');\n    assertNotNullOrUndefined(this.layoutContainer?.id, 'layoutContainer.id cannot be null or undefined');\n    await this.contentEditorApi.updateLayoutContainer(\n      this.layoutContainer.id,\n      { styleBackgroundColor: event.detail.color },\n    );\n    await this.storeService.dispatch(\n      ContentContextMutations.setLayoutContainerStyle,\n      this.contextIdentifier,\n      this.layoutContainer.id,\n      { backgroundColor: event.detail.color },\n    );\n    this.showColorSelect = false;\n  }\n\n  private async setBackgroundImage(): Promise<void> {\n    assertNotNullOrUndefined(this.contextIdentifier, 'contextIdentifier cannot be null or undefined');\n    assertNotNullOrUndefined(this.layoutContainer?.id, 'layoutContainer.id cannot be null or undefined');\n\n    const item = await this.customDialogService.showMediaSelect({\n      selectedMediaType: GalleryMediaType.Picture\n    });\n    if(item == null || item.type !== GalleryMediaType.Picture) return;\n\n    const { blurHash, height, id, url, width } = item.value;\n    await this.contentEditorApi.updateLayoutContainer(\n      this.layoutContainer.id,\n      { styleBackgroundImageId: id },\n    );\n    await this.storeService.dispatch(\n      ContentContextMutations.setLayoutContainerStyle,\n      this.contextIdentifier,\n      this.layoutContainer.id,\n      {\n        backgroundImage: {\n          blurHash,\n          height,\n          id,\n          url,\n          width,\n        },\n      },\n    );\n  }\n\n  private async removeBackgroundImage(): Promise<void> {\n    assertNotNullOrUndefined(this.contextIdentifier, 'contextIdentifier cannot be null or undefined');\n    assertNotNullOrUndefined(this.layoutContainer?.id, 'layoutContainer.id cannot be null or undefined');\n\n    await this.contentEditorApi.updateLayoutContainer(\n      this.layoutContainer.id,\n      { styleBackgroundImageId: null },\n    );\n    await this.storeService.dispatch(\n      ContentContextMutations.setLayoutContainerStyle,\n      this.contextIdentifier,\n      this.layoutContainer.id,\n      { backgroundImage: null },\n    );\n  }\n\n  private async setCornerStyle(styleCorner: CornerStyle): Promise<void> {\n    assertNotNullOrUndefined(this.contextIdentifier, 'contextIdentifier cannot be null or undefined');\n    assertNotNullOrUndefined(this.layoutContainer?.id, 'layoutContainer.id cannot be null or undefined');\n\n    await this.contentEditorApi.updateLayoutContainer(this.layoutContainer.id, { styleCorner });\n    await this.storeService.dispatch(\n      ContentContextMutations.setLayoutContainerStyle,\n      this.contextIdentifier,\n      this.layoutContainer.id,\n      { corner: styleCorner },\n    );\n  }\n\n  private async toggleSeparators(): Promise<void> {\n    assertNotNullOrUndefined(this.contextIdentifier, 'contextIdentifier cannot be null or undefined');\n    assertNotNullOrUndefined(this.layoutContainer?.id, 'layoutContainer.id cannot be null or undefined');\n    const styleSeparator = !this.layoutContainer.style.separator;\n\n    const responseContainer = await this.contentEditorApi.updateLayoutContainer(this.layoutContainer.id, { styleSeparator });\n    await this.storeService.dispatch(\n      ContentContextMutations.setLayoutContainerStyle,\n      this.contextIdentifier,\n      this.layoutContainer.id,\n      { separator: responseContainer.style.separator },\n    );\n  }\n\n  private async setDirection(layoutDirection: LayoutContainerDirection): Promise<void> {\n    assertNotNullOrUndefined(this.contextIdentifier, 'contextIdentifier cannot be null or undefined');\n    assertNotNullOrUndefined(this.layoutContainer?.id, 'layoutContainer.id cannot be null or undefined');\n\n    const responseContainer = await this.contentEditorApi.updateLayoutContainer(this.layoutContainer.id, { layoutDirection });\n    await this.storeService.dispatch(\n      ContentContextMutations.setLayoutContainerLayout,\n      this.contextIdentifier,\n      this.layoutContainer.id,\n      { direction: responseContainer.layout.direction },\n    );\n  }\n}\n","import { autoinject, bindable } from 'aurelia-framework';\nimport { UniversalBlock } from 'common/dto/content-editor/content.editor.interface';\nimport { IBlockSpacingOptionsDto } from 'common/dto/course/content/block.interface';\nimport { BlockStyleSizingDefault } from 'common/enum/block.style.enum';\nimport { assertNotNullOrUndefined } from 'common/utils/assert';\nimport { DomUtils } from 'common/utils/DomUtils';\nimport { TBlockSizeSide } from '../content-editor-inspector-section-sizing/content-editor-inspector-section-sizing';\n\n/**\n * @event { UpdateBlockSpacingEvent } update-block-sizing\n */\n@autoinject()\nexport class ContentEditorInspectorSectionSizingSide {\n  @bindable() public side: TBlockSizeSide | null = null;\n  @bindable() public block: UniversalBlock | null = null;\n  private domElement: HTMLElement;\n  private customBlockSizeError: boolean = false;\n  private customBlockSize: string = '0';\n  private BlockStyleSizingDefault = BlockStyleSizingDefault;\n\n  constructor(element: Element) {\n    this.domElement = element as HTMLElement;\n  }\n\n  private blockChanged(): void {\n    this.updateCustomBlockSize();\n  }\n\n  private sideChanged(): void {\n    this.updateCustomBlockSize();\n  }\n\n  private updateCustomBlockSize(): void {\n    if(this.side && this.block?.styleSpacingOptions) {\n      this.customBlockSize = `${this.block.styleSpacingOptions[this.side]}`;\n    } else {\n      this.customBlockSize = '0';\n    }\n  }\n\n  private setDefaultBlockSize(size: BlockStyleSizingDefault): void {\n    assertNotNullOrUndefined(this.side, 'side cannot be null or undefined');\n    const dto: IBlockSpacingOptionsDto = {\n      [this.side]: size\n    };\n    this.fireEvent(dto);\n  }\n\n  private async onSaveCustomBlockSize(): Promise<void> {\n    assertNotNullOrUndefined(this.side, 'side cannot be null or undefined');\n\n    const value = parseInt(this.customBlockSize);\n    if(value > 100 || value < -100) {\n      this.customBlockSizeError = true;\n      return;\n    }\n    const dto: IBlockSpacingOptionsDto = {\n      [this.side]: value\n    };\n    this.fireEvent(dto);\n  }\n\n  private unsetBlockSize(): void {\n    assertNotNullOrUndefined(this.side, 'side cannot be null or undefined');\n\n    const dto: IBlockSpacingOptionsDto = {\n      [this.side]: 0\n    };\n    this.fireEvent(dto);\n  }\n\n  private fireEvent(dto: IBlockSpacingOptionsDto): void {\n    this.customBlockSizeError = false;\n    DomUtils.fireEvent<UpdateBlockSpacingEvent['detail']>(this.domElement, {\n      name: 'update-block-sizing',\n      bubbles: false,\n      detail: { dto },\n    });\n  }\n}\n\nexport type UpdateBlockSpacingEvent = CustomEvent<{ dto: IBlockSpacingOptionsDto }>;\n","import { autoinject, bindable, ObserverLocator, Parser } from 'aurelia-framework';\nimport { selectState, SelectStateObservableComponent } from 'common/aurelia-decorators/select-state';\nimport { StoreService } from 'common/aurelia-services/StoreService';\nimport { UniversalBlock } from 'common/dto/content-editor/content.editor.interface';\nimport { IBlockSpacingOptionsDto } from 'common/dto/course/content/block.interface';\nimport { ILayoutContainerDto } from 'common/dto/course/layout.container.interface';\nimport * as ContentContextMutations from 'common/store/mutations/content.context.mutations';\nimport { blockByIdSelectorCreator } from 'common/store/selectors/content.context.selectors';\nimport { layoutContainerByIdSelectorCreator } from 'common/store/selectors/presentation.context.selectors';\nimport { assertNotNullOrUndefined } from 'common/utils/assert';\nimport { FunctionUtils } from 'common/utils/FunctionUtils';\nimport { ContentEditorApiService } from '../../../../services/api/ContentEditorApiService';\nimport * as ContentEditorMutations from '../../../../store/content.editor.mutations';\nimport { IState } from '../../../../store/state';\nimport { UpdateBlockSpacingEvent } from '../content-editor-inspector-section-sizing-side/content-editor-inspector-section-sizing-side';\n\nexport type TBlockSizeSide = 'right' | 'left';\n\n@autoinject()\nexport class ContentEditorInspectorSectionSizing extends SelectStateObservableComponent {\n  @bindable() public contextIdentifier: string | null = null;\n  @bindable() public layoutContainerId: number | null = null;\n\n  private block: UniversalBlock | null = null;\n  private updateInProgress: boolean = false;\n  private debouncedSaveBlock = FunctionUtils.debounce(() => { this.saveBlock(); }, 500);\n  private dto: IBlockSpacingOptionsDto | null = null;\n\n  @selectState(\n    ContentEditorInspectorSectionSizing,\n    layoutContainerByIdSelectorCreator,\n    ['contextIdentifier', 'layoutContainerId'],\n  ) private layoutContainer?: ILayoutContainerDto | null;\n\n  constructor(\n    private storeService: StoreService<IState>,\n    private contentEditorApi: ContentEditorApiService,\n    observerLocator: ObserverLocator,\n    parser: Parser,\n  ) {\n    super(parser, observerLocator);\n  }\n\n  protected detached(): void {\n    this.storeService.disposeAllSubscriptions(this);\n    this.debouncedSaveBlock?.cancel();\n  }\n\n  private layoutContainerChanged(): void {\n    this.storeService.disposeAllSubscriptions(this);\n    if(this.contextIdentifier == null || this.layoutContainer?.blockId == null) {\n      return;\n    }\n\n    this.storeService.subscribeMemoized(\n      this,\n      blockByIdSelectorCreator,\n      block => {\n        this.block = block;\n      },\n      {\n        contextIdentifier: this.contextIdentifier,\n        blockId: this.layoutContainer.blockId,\n      },\n    );\n  }\n\n  private async saveBlockSize(event: UpdateBlockSpacingEvent): Promise<void> {\n    assertNotNullOrUndefined(this.contextIdentifier, 'contextIdentifier cannot be null or undefined');\n    assertNotNullOrUndefined(this.block, 'block cannot be null or undefined');\n    this.dto = event.detail.dto;\n    this.block.styleSpacingOptions = {\n      ... this.block.styleSpacingOptions,\n      ...this.dto\n    };\n    const updatedBlock = this.block;\n    this.updateInProgress = true;\n    await this.storeService\n      .pipe(ContentEditorMutations.updateEditBlockId, null)\n      .pipe(ContentContextMutations.updateBlock, this.contextIdentifier, updatedBlock)\n      .dispatch();\n    this.updateInProgress = false;\n    // for a smoother experience, we update the actual block after a delay\n    this.debouncedSaveBlock();\n  }\n\n  private async saveBlock(): Promise<void> {\n    assertNotNullOrUndefined(this.block, 'block cannot be null or undefined');\n    assertNotNullOrUndefined(this.contextIdentifier, 'contextIdentifier cannot be null or undefined');\n\n    if(this.dto && !this.updateInProgress) {\n      const updatedBlock = await this.contentEditorApi.updateBlockStyleSpacingOptions<UniversalBlock>(this.block.id, this.dto);\n      await this.storeService.dispatch(ContentContextMutations.updateBlock, this.contextIdentifier, updatedBlock);\n    }\n  }\n}","import { autoinject, bindable } from 'aurelia-framework';\nimport { selectState } from 'common/aurelia-decorators/select-state';\nimport { StoreService } from 'common/aurelia-services/StoreService';\nimport { ILayoutContainerDto } from 'common/dto/course/layout.container.interface';\nimport * as ContentContextMutations from 'common/store/mutations/content.context.mutations';\nimport { layoutContainerByIdSelectorCreator } from 'common/store/selectors/presentation.context.selectors';\nimport { assertNotNullOrUndefined } from 'common/utils/assert';\nimport { ContentEditorApiService } from 'services/api/ContentEditorApiService';\nimport { IState } from 'store/state';\n\nenum SelectedStyle {\n  Plain = 'plain',\n  Border = 'border',\n  Shadow = 'shadow',\n  BorderAndShadow = 'border-and-shadow',\n}\n\n@autoinject()\nexport class ContentEditorInspectorSectionStyles {\n  @bindable() public contextIdentifier: string | null = null;\n  @bindable() public layoutContainerId: number | null = null;\n  private selectedStyle = SelectedStyle.Plain;\n  private SelectedStyle = SelectedStyle;\n\n  @selectState(\n    ContentEditorInspectorSectionStyles,\n    layoutContainerByIdSelectorCreator,\n    ['contextIdentifier', 'layoutContainerId']\n  ) private layoutContainer?: ILayoutContainerDto | null;\n\n  constructor(\n    private storeService: StoreService<IState>,\n    private contentEditorApi: ContentEditorApiService,\n  ) { }\n\n  private layoutContainerChanged(): void {\n    if(this.layoutContainer == null) return;\n\n    if(this.layoutContainer.style.border) {\n      this.selectedStyle = this.layoutContainer.style.shadow ? SelectedStyle.BorderAndShadow : SelectedStyle.Border;\n    } else {\n      this.selectedStyle = this.layoutContainer.style.shadow ? SelectedStyle.Shadow : SelectedStyle.Plain;\n    }\n  }\n\n  private async setStyle(shadow: boolean, border: boolean): Promise<void> {\n    assertNotNullOrUndefined(this.contextIdentifier, 'contextIdentifier cannot be null or undefined');\n    assertNotNullOrUndefined(this.layoutContainer?.id, 'layoutContainer.id cannot be null or undefined');\n\n    await this.contentEditorApi.updateLayoutContainer(\n      this.layoutContainer.id,\n      {\n        styleShadow: shadow,\n        styleBorder: border,\n      });\n    await this.storeService.dispatch(\n      ContentContextMutations.setLayoutContainerStyle,\n      this.contextIdentifier,\n      this.layoutContainer.id,\n      { shadow, border },\n    );\n  }\n}\n","import { autoinject, bindable } from 'aurelia-framework';\n\n@autoinject()\nexport class ContentEditorInspectorSection {\n  @bindable() public titleTk = '';\n  private collapsed = false;\n}\n","import { autoinject, bindable } from 'aurelia-framework';\nimport { selectState } from 'common/aurelia-decorators/select-state';\nimport { StoreService } from 'common/aurelia-services/StoreService';\nimport { ILayoutContainerDto, LayoutContainerType } from 'common/dto/course/layout.container.interface';\nimport * as ContentContextMutations from 'common/store/mutations/content.context.mutations';\nimport { layoutContainerByIdSelectorCreator } from 'common/store/selectors/presentation.context.selectors';\nimport { assertNotNullOrUndefined } from 'common/utils/assert';\nimport { ContentEditorApiService } from '../../../services/api/ContentEditorApiService';\nimport * as ContentEditorMutations from '../../../store/content.editor.mutations';\nimport { updateContainerStylesState } from '../../../store/content.editor.mutations';\nimport { InspectorMode, IState } from '../../../store/state';\n\n@autoinject()\nexport class ContentEditorInspector {\n  @bindable() public contextIdentifier: string | null = null;\n  public sizingAvailable = false;\n  public spacingAvailable = false;\n  public layoutContainerId: number | null = null;\n  private inspectorMode: InspectorMode | null = null;\n  private modeTk = 'inspector.element';\n  private selectMessageTk = 'Element';\n  private styleTk = '';\n  private InspectorMode = InspectorMode;\n  private cardSelected = false;\n\n  @selectState(\n    ContentEditorInspector,\n    layoutContainerByIdSelectorCreator,\n    ['contextIdentifier', 'layoutContainerId'],\n  ) private layoutContainer?: ILayoutContainerDto | null;\n\n  constructor(\n    private storeService: StoreService<IState>,\n    private contentEditorApi: ContentEditorApiService,\n  ) { }\n\n  protected attached(): void {\n    this.storeService.subscribeToDetailedChanges(this, [\n      state => state.contentEditor.inspector.currentLayoutContainerId,\n      state => state.contentEditor.inspector.mode\n    ], (_state, currentLayoutContainerId, inspectorMode) => {\n      this.layoutContainerId = currentLayoutContainerId;\n      this.inspectorMode = inspectorMode;\n      if(inspectorMode !== InspectorMode.Inactive) {\n        this.setTexts();\n        this.selectMessageTk = inspectorMode === InspectorMode.Element\n          ? 'Element' : 'Container';\n      }\n    });\n  }\n\n  protected detached(): void {\n    this.storeService.disposeAllSubscriptions(this);\n  }\n\n  private layoutContainerChanged(): void {\n    this.setTexts();\n  }\n\n  private setTexts(): void {\n    if(this.layoutContainer == null) {\n      this.modeTk = this.inspectorMode === InspectorMode.Element\n        ? 'inspector.element' : 'container';\n      return;\n    }\n\n    switch(this.layoutContainer?.type) {\n      case LayoutContainerType.Block:\n        this.cardSelected = false;\n        this.styleTk = 'Block';\n        this.modeTk = 'inspector.block';\n        break;\n      case LayoutContainerType.Card:\n        this.cardSelected = true;\n        this.styleTk = 'Card';\n        this.modeTk = 'inspector.card';\n        break;\n      case LayoutContainerType.Layout:\n        this.cardSelected = false;\n        this.styleTk = 'Container';\n        this.modeTk = 'container';\n        break;\n    }\n  }\n\n  private handleClose(): void {\n    if(this.inspectorMode === InspectorMode.Container) {\n      this.storeService.dispatch(updateContainerStylesState, {\n        showExtraContainerSpace: false,\n      });\n    }\n    this.storeService\n      .pipe(ContentEditorMutations.closeSidebarRight)\n      .pipe(ContentEditorMutations.updateInspector)\n      .dispatch();\n  }\n\n  private async redistributeChildren(): Promise<void> {\n    assertNotNullOrUndefined(this.contextIdentifier, 'contextIdentifier cannot be null or undefined');\n    assertNotNullOrUndefined(this.layoutContainer?.id, 'layoutContainer.id cannot be null or undefined');\n    const changes = await this.contentEditorApi.redistributeLayoutContainerChildren(this.layoutContainer.id);\n    await this.storeService.dispatch(ContentContextMutations.applyLayoutChanges, this.contextIdentifier, changes);\n  }\n\n  private async deleteContainer(): Promise<void> {\n    assertNotNullOrUndefined(this.contextIdentifier, 'contextIdentifier cannot be null or undefined');\n    assertNotNullOrUndefined(this.layoutContainer?.id, 'layoutContainer.id cannot be null or undefined');\n    const changes = await this.contentEditorApi.removeLayoutContainer(this.layoutContainer.id);\n    await this.storeService\n      .pipe(ContentContextMutations.applyLayoutChanges, this.contextIdentifier, changes)\n      .pipe(ContentEditorMutations.updateContainerStructure, this.contextIdentifier)\n      .pipe(ContentEditorMutations.resetContainerHoverState)\n      .pipe(ContentEditorMutations.updateInspector, null)\n      .dispatch();\n  }\n}\n","import { PLATFORM } from 'aurelia-pal';\nimport { FrameworkConfiguration } from 'aurelia-framework';\n\nexport function configure(config: FrameworkConfiguration): void {\n  config.globalResources(PLATFORM.moduleName('resources/elements/content-editor-inspector/content-editor-inspector'));\n  config.globalResources(PLATFORM.moduleName('resources/elements/content-editor-inspector/content-editor-inspector-attribute/content-editor-inspector-attribute'));\n  config.globalResources(PLATFORM.moduleName('resources/elements/content-editor-inspector/content-editor-inspector-section/content-editor-inspector-section'));\n  config.globalResources(PLATFORM.moduleName('resources/elements/content-editor-inspector/content-editor-inspector-section-alignment/content-editor-inspector-section-alignment'));\n  config.globalResources(PLATFORM.moduleName('resources/elements/content-editor-inspector/content-editor-inspector-section-attributes/content-editor-inspector-section-attributes'));\n  config.globalResources(PLATFORM.moduleName('resources/elements/content-editor-inspector/content-editor-inspector-section-sizing/content-editor-inspector-section-sizing'));\n  config.globalResources(PLATFORM.moduleName('resources/elements/content-editor-inspector/content-editor-inspector-section-sizing-side/content-editor-inspector-section-sizing-side'));\n  config.globalResources(PLATFORM.moduleName('resources/elements/content-editor-inspector/content-editor-inspector-section-styles/content-editor-inspector-section-styles'));\n}\n"],"names":[],"sourceRoot":""}