diff --git a/docs/guides/admin/docs/changelog.md b/docs/guides/admin/docs/changelog.md
index 7a45d13d5d..d44bc8c0aa 100644
--- a/docs/guides/admin/docs/changelog.md
+++ b/docs/guides/admin/docs/changelog.md
@@ -1,9 +1,1278 @@
Changelog
=========
+Opencast 13
+-----------
+
+### Opencast 13.1
+
+*Released on January 18th, 2023*
+
+- [[#4608](https://github.com/opencast/opencast/pull/4608)] -
+ Bump paella-core from 1.11.3 to 1.14.2 in /modules/engage-paella-player-7
+- [[#4607](https://github.com/opencast/opencast/pull/4607)] -
+ Add Opencast 13.1 release notes
+- [[#4604](https://github.com/opencast/opencast/pull/4604)] -
+ Bump eslint from 8.30.0 to 8.32.0 in /modules/engage-paella-player-7
+- [[#4603](https://github.com/opencast/opencast/pull/4603)] -
+ Bump html-validate from 7.11.1 to 7.13.1 in /modules/engage-paella-player-7
+- [[#4599](https://github.com/opencast/opencast/pull/4599)] -
+ Fix Syntax Error
+- [[#4584](https://github.com/opencast/opencast/pull/4584)] -
+ Bump @babel/core from 7.20.5 to 7.20.12 in /modules/engage-paella-player-7
+- [[#4582](https://github.com/opencast/opencast/pull/4582)] -
+ Bump babel-loader from 9.1.0 to 9.1.2 in /modules/engage-paella-player-7
+- [[#4578](https://github.com/opencast/opencast/pull/4578)] -
+ Bump paella-basic-plugins from 1.8.1 to 1.8.4 in /modules/engage-paella-player-7
+- [[#4558](https://github.com/opencast/opencast/pull/4558)] -
+ Bump html-validate from 7.11.0 to 7.11.1 in /modules/engage-paella-player-7
+- [[#4548](https://github.com/opencast/opencast/pull/4548)] -
+ Mark OC13 RPMs as Stable
+- [[#4547](https://github.com/opencast/opencast/pull/4547)] -
+ Bump eslint from 8.29.0 to 8.30.0 in /modules/engage-paella-player-7
+- [[#4546](https://github.com/opencast/opencast/pull/4546)] -
+ Bump html-validate from 7.10.1 to 7.11.0 in /modules/engage-paella-player-7
+- [[#4541](https://github.com/opencast/opencast/pull/4541)] -
+ Bump paella-core from 1.11.1 to 1.11.3 in /modules/engage-paella-player-7
+- [[#4540](https://github.com/opencast/opencast/pull/4540)] -
+ Bump css-loader from 6.7.2 to 6.7.3 in /modules/engage-paella-player-7
+- [[#4536](https://github.com/opencast/opencast/pull/4536)] -
+ Avoid using jobs in SeriesUpdatedEventHandler
+- [[#4516](https://github.com/opencast/opencast/pull/4516)] -
+ Change default hotkeys for create dialogs in admin UI
+- [[#4512](https://github.com/opencast/opencast/pull/4512)] -
+ Bump webpack-cli from 5.0.0 to 5.0.1 in /modules/engage-paella-player-7
+- [[#4502](https://github.com/opencast/opencast/pull/4502)] -
+ Fix: series deleted from search index cannot be re-added
+- [[#4484](https://github.com/opencast/opencast/pull/4484)] -
+ Prepare release notes for Opencast 13
+- [[#4482](https://github.com/opencast/opencast/pull/4482)] -
+ Add silient detection based on subtitles (webvtt-to-cutmarks woh)
+- [[#4478](https://github.com/opencast/opencast/pull/4478)] -
+ Bug fix: publish engage woh with merge SKIP the operation if media package not in search index
+
+### Opencast 13.0
+
+*Released on December 14th, 2022*
+
+- [[#4529](https://github.com/opencast/opencast/pull/4529)] -
+ Fix parent POM version of redirect module in r/13.x
+- [[#4519](https://github.com/opencast/opencast/pull/4519)] -
+ Reduce number of snapshots taken in the new editor backend
+- [[#4513](https://github.com/opencast/opencast/pull/4513)] -
+ Adds Whisper STT to SpeechToText WoH
+- [[#4510](https://github.com/opencast/opencast/pull/4510)] -
+ Bump html-validate from 7.10.0 to 7.10.1 in /modules/engage-paella-player-7
+- [[#4505](https://github.com/opencast/opencast/pull/4505)] -
+ Bump eslint from 8.28.0 to 8.29.0 in /modules/engage-paella-player-7
+- [[#4495](https://github.com/opencast/opencast/pull/4495)] -
+ Bump @babel/core from 7.20.2 to 7.20.5 in /modules/engage-paella-player-7
+- [[#4492](https://github.com/opencast/opencast/pull/4492)] -
+ Bump paella-core from 1.8.9 to 1.11.1 in /modules/engage-paella-player-7
+- [[#4490](https://github.com/opencast/opencast/pull/4490)] -
+ Add rules for merging pull requests to the docs
+- [[#4480](https://github.com/opencast/opencast/pull/4480)] -
+ Bump eslint from 8.27.0 to 8.28.0 in /modules/engage-paella-player-7
+- [[#4476](https://github.com/opencast/opencast/pull/4476)] -
+ Bump html-validate from 7.8.0 to 7.10.0 in /modules/engage-paella-player-7
+- [[#4471](https://github.com/opencast/opencast/pull/4471)] -
+ Bump @babel/preset-env from 7.19.4 to 7.20.2 in /modules/engage-paella-player-7
+- [[#4470](https://github.com/opencast/opencast/pull/4470)] -
+ Bump webpack-cli from 4.10.0 to 5.0.0 in /modules/engage-paella-player-7
+- [[#4456](https://github.com/opencast/opencast/pull/4456)] -
+ New workflow implementation and migration fixes (OC 13)
+- [[#4451](https://github.com/opencast/opencast/pull/4451)] -
+ Bump html-validate from 7.8.0 to 7.9.0 in /modules/admin-ui-frontend
+- [[#4450](https://github.com/opencast/opencast/pull/4450)] -
+ Add index for oc_job_argument table (OC 13)
+- [[#4445](https://github.com/opencast/opencast/pull/4445)] -
+ Update to eclipselink 2.7.8
+- [[#4442](https://github.com/opencast/opencast/pull/4442)] -
+ Update Karaf to 4.2.16
+- [[#4440](https://github.com/opencast/opencast/pull/4440)] -
+ Enrich LDAP users with name and mail address
+- [[#4425](https://github.com/opencast/opencast/pull/4425)] -
+ Bump eslint from 8.26.0 to 8.27.0 in /modules/runtime-info-ui
+- [[#4424](https://github.com/opencast/opencast/pull/4424)] -
+ Bump eslint from 8.26.0 to 8.27.0 in /modules/runtime-info-ui-ng
+- [[#4422](https://github.com/opencast/opencast/pull/4422)] -
+ More ESLint Auto-Updates
+- [[#4421](https://github.com/opencast/opencast/pull/4421)] -
+ Fix Auto-update Tests
+- [[#4420](https://github.com/opencast/opencast/pull/4420)] -
+ Bump eslint from 8.26.0 to 8.27.0 in /modules/admin-ui-frontend
+- [[#4419](https://github.com/opencast/opencast/pull/4419)] -
+ Bump eslint from 8.26.0 to 8.27.0 in /modules/engage-paella-player
+- [[#4418](https://github.com/opencast/opencast/pull/4418)] -
+ Opencast 13 release schedule
+- [[#4415](https://github.com/opencast/opencast/pull/4415)] -
+ Publish Captions by Default
+- [[#4413](https://github.com/opencast/opencast/pull/4413)] -
+ Bump chromedriver from 107.0.2 to 107.0.3 in /modules/admin-ui-frontend
+- [[#4408](https://github.com/opencast/opencast/pull/4408)] -
+ Add support for multipart mails using text and HTML
+- [[#4403](https://github.com/opencast/opencast/pull/4403)] -
+ Bump @types/node from 18.8.3 to 18.11.8 in /modules/lti
+- [[#4401](https://github.com/opencast/opencast/pull/4401)] -
+ Bump react-select from 5.4.0 to 5.5.9 in /modules/lti
+- [[#4399](https://github.com/opencast/opencast/pull/4399)] -
+ Bump @types/jest from 29.1.2 to 29.2.1 in /modules/lti
+- [[#4398](https://github.com/opencast/opencast/pull/4398)] -
+ Bump i18next from 21.10.0 to 22.0.4 in /modules/lti
+- [[#4397](https://github.com/opencast/opencast/pull/4397)] -
+ Bump i18next-browser-languagedetector from 6.1.8 to 7.0.0 in /modules/lti
+- [[#4396](https://github.com/opencast/opencast/pull/4396)] -
+ Bump react-i18next from 11.18.6 to 12.0.0 in /modules/lti
+- [[#4395](https://github.com/opencast/opencast/pull/4395)] -
+ Bump @types/react-dom from 18.0.6 to 18.0.8 in /modules/lti
+- [[#4394](https://github.com/opencast/opencast/pull/4394)] -
+ Bump html-validate from 7.7.1 to 7.8.0 in /modules/admin-ui-frontend
+- [[#4390](https://github.com/opencast/opencast/pull/4390)] -
+ Bump chromedriver from 107.0.1 to 107.0.2 in /modules/admin-ui-frontend
+- [[#4389](https://github.com/opencast/opencast/pull/4389)] -
+ Bump jasmine-core from 4.4.0 to 4.5.0 in /modules/admin-ui-frontend
+- [[#4388](https://github.com/opencast/opencast/pull/4388)] -
+ Use valid URL for admin interface mock data
+- [[#4384](https://github.com/opencast/opencast/pull/4384)] -
+ Bump chromedriver from 107.0.0 to 107.0.1 in /modules/admin-ui-frontend
+- [[#4383](https://github.com/opencast/opencast/pull/4383)] -
+ Simplify ldap user directory implementation
+- [[#4380](https://github.com/opencast/opencast/pull/4380)] -
+ Add organization properties to mail template data
+- [[#4379](https://github.com/opencast/opencast/pull/4379)] -
+ Bump chromedriver from 106.0.1 to 107.0.0 in /modules/admin-ui-frontend
+- [[#4376](https://github.com/opencast/opencast/pull/4376)] -
+ Allow use of extended metadata in send-email WOH
+- [[#4372](https://github.com/opencast/opencast/pull/4372)] -
+ Bump html-validate from 7.7.0 to 7.7.1 in /modules/admin-ui-frontend
+- [[#4364](https://github.com/opencast/opencast/pull/4364)] -
+ Bump eslint from 8.25.0 to 8.26.0 in /modules/runtime-info-ui-ng
+- [[#4363](https://github.com/opencast/opencast/pull/4363)] -
+ Bump eslint from 8.25.0 to 8.26.0 in /modules/runtime-info-ui
+- [[#4362](https://github.com/opencast/opencast/pull/4362)] -
+ Bump eslint from 8.25.0 to 8.26.0 in /modules/admin-ui-frontend
+- [[#4361](https://github.com/opencast/opencast/pull/4361)] -
+ Bump html-validate from 7.6.0 to 7.7.0 in /modules/admin-ui-frontend
+- [[#4360](https://github.com/opencast/opencast/pull/4360)] -
+ Bump eslint from 8.25.0 to 8.26.0 in /modules/engage-paella-player
+- [[#4359](https://github.com/opencast/opencast/pull/4359)] -
+ Make PostgreSQL no longer experimental
+- [[#4358](https://github.com/opencast/opencast/pull/4358)] -
+ Add assert workflow operation
+- [[#4357](https://github.com/opencast/opencast/pull/4357)] -
+ Deprecated junit import
+- [[#4351](https://github.com/opencast/opencast/pull/4351)] -
+ Extract workflow filename filter
+- [[#4349](https://github.com/opencast/opencast/pull/4349)] -
+ Replace fallback element identifiers with UUIDs
+- [[#4348](https://github.com/opencast/opencast/pull/4348)] -
+ Use System cURL for Tests
+- [[#4335](https://github.com/opencast/opencast/pull/4335)] -
+ Bump jettison from 1.4.1 to 1.5.1
+- [[#4330](https://github.com/opencast/opencast/pull/4330)] -
+ Enforce Workflow Operation Documentation Style
+- [[#4319](https://github.com/opencast/opencast/pull/4319)] -
+ Remove unused class "DispatchableComparator"
+- [[#4301](https://github.com/opencast/opencast/pull/4301)] -
+ Bump eslint from 8.24.0 to 8.25.0 in /modules/runtime-info-ui-ng
+- [[#4300](https://github.com/opencast/opencast/pull/4300)] -
+ Bump eslint from 8.24.0 to 8.25.0 in /modules/runtime-info-ui
+- [[#4299](https://github.com/opencast/opencast/pull/4299)] -
+ Bump html-validate from 7.5.0 to 7.6.0 in /modules/admin-ui-frontend
+- [[#4298](https://github.com/opencast/opencast/pull/4298)] -
+ Bump eslint from 8.24.0 to 8.25.0 in /modules/admin-ui-frontend
+- [[#4297](https://github.com/opencast/opencast/pull/4297)] -
+ Bump eslint from 8.24.0 to 8.25.0 in /modules/engage-paella-player
+- [[#4296](https://github.com/opencast/opencast/pull/4296)] -
+ Bump express from 4.18.1 to 4.18.2 in /modules/engage-paella-player
+- [[#4292](https://github.com/opencast/opencast/pull/4292)] -
+ Bump @types/node from 18.7.23 to 18.8.3 in /modules/lti
+- [[#4290](https://github.com/opencast/opencast/pull/4290)] -
+ Bump i18next-browser-languagedetector from 6.1.5 to 6.1.8 in /modules/lti
+- [[#4286](https://github.com/opencast/opencast/pull/4286)] -
+ Bump bootstrap from 5.2.1 to 5.2.2 in /modules/lti
+- [[#4285](https://github.com/opencast/opencast/pull/4285)] -
+ Bump i18next from 21.9.2 to 21.10.0 in /modules/lti
+- [[#4284](https://github.com/opencast/opencast/pull/4284)] -
+ Bump @types/jest from 29.1.1 to 29.1.2 in /modules/lti
+- [[#4280](https://github.com/opencast/opencast/pull/4280)] -
+ ADD support for f4v file type
+- [[#4272](https://github.com/opencast/opencast/pull/4272)] -
+ Bump checker-qual from 3.25.0 to 3.26.0 in /modules/db
+- [[#4264](https://github.com/opencast/opencast/pull/4264)] -
+ Bump @types/jest from 29.0.0 to 29.1.1 in /modules/lti
+- [[#4263](https://github.com/opencast/opencast/pull/4263)] -
+ Bump @types/node from 18.7.15 to 18.7.23 in /modules/lti
+- [[#4262](https://github.com/opencast/opencast/pull/4262)] -
+ Bump react-i18next from 11.18.5 to 11.18.6 in /modules/lti
+- [[#4260](https://github.com/opencast/opencast/pull/4260)] -
+ Bump i18next from 21.9.1 to 21.9.2 in /modules/lti
+- [[#4259](https://github.com/opencast/opencast/pull/4259)] -
+ Bump typescript from 4.8.2 to 4.8.4 in /modules/lti
+- [[#4258](https://github.com/opencast/opencast/pull/4258)] -
+ Bump bootstrap from 5.2.0 to 5.2.1 in /modules/lti
+- [[#4256](https://github.com/opencast/opencast/pull/4256)] -
+ Bump chromedriver from 105.0.1 to 106.0.1 in /modules/admin-ui-frontend
+- [[#4246](https://github.com/opencast/opencast/pull/4246)] -
+ Bump underscore from 1.13.4 to 1.13.6 in /modules/engage-ui
+- [[#4245](https://github.com/opencast/opencast/pull/4245)] -
+ Bump eslint from 8.23.1 to 8.24.0 in /modules/runtime-info-ui
+- [[#4244](https://github.com/opencast/opencast/pull/4244)] -
+ Bump eslint from 8.23.1 to 8.24.0 in /modules/runtime-info-ui-ng
+- [[#4243](https://github.com/opencast/opencast/pull/4243)] -
+ Bump eslint from 8.23.1 to 8.24.0 in /modules/admin-ui-frontend
+- [[#4236](https://github.com/opencast/opencast/pull/4236)] -
+ Add equals() for AccessControlList
+- [[#4234](https://github.com/opencast/opencast/pull/4234)] -
+ Bump sass from 1.54.9 to 1.55.0 in /modules/admin-ui-frontend
+- [[#4232](https://github.com/opencast/opencast/pull/4232)] -
+ Do not update default player components on legacy branches
+- [[#4225](https://github.com/opencast/opencast/pull/4225)] -
+ PoC: Karaf shell opencast:plugin* commands
+- [[#4223](https://github.com/opencast/opencast/pull/4223)] -
+ Bump chromedriver from 105.0.0 to 105.0.1 in /modules/admin-ui-frontend
+- [[#4222](https://github.com/opencast/opencast/pull/4222)] -
+ Bump karma from 6.4.0 to 6.4.1 in /modules/admin-ui-frontend
+- [[#4216](https://github.com/opencast/opencast/pull/4216)] -
+ Bump html-validate from 7.4.1 to 7.5.0 in /modules/admin-ui-frontend
+- [[#4202](https://github.com/opencast/opencast/pull/4202)] -
+ Add index on object_key field (needed when deleting assets).
+- [[#4201](https://github.com/opencast/opencast/pull/4201)] -
+ When archiving version 0 to store properties, include metadata from dc catalog
+- [[#4194](https://github.com/opencast/opencast/pull/4194)] -
+ Bump eslint from 8.23.0 to 8.23.1 in /modules/runtime-info-ui
+- [[#4193](https://github.com/opencast/opencast/pull/4193)] -
+ Bump eslint from 8.23.0 to 8.23.1 in /modules/runtime-info-ui-ng
+- [[#4190](https://github.com/opencast/opencast/pull/4190)] -
+ Bump eslint from 8.23.0 to 8.23.1 in /modules/admin-ui-frontend
+- [[#4189](https://github.com/opencast/opencast/pull/4189)] -
+ Bump html-validate from 7.3.3 to 7.4.1 in /modules/admin-ui-frontend
+- [[#4186](https://github.com/opencast/opencast/pull/4186)] -
+ Added correct type of keyword.
+- [[#4181](https://github.com/opencast/opencast/pull/4181)] -
+ Add support for multiple common metadata catalogs
+- [[#4180](https://github.com/opencast/opencast/pull/4180)] -
+ Add basic auth support ingest download
+- [[#4176](https://github.com/opencast/opencast/pull/4176)] -
+ Bump sass from 1.54.4 to 1.54.9 in /modules/admin-ui-frontend
+- [[#4166](https://github.com/opencast/opencast/pull/4166)] -
+ Bump @types/node from 18.7.14 to 18.7.15 in /modules/lti
+- [[#4160](https://github.com/opencast/opencast/pull/4160)] -
+ Bump jasmine-core from 4.3.0 to 4.4.0 in /modules/admin-ui-frontend
+- [[#4157](https://github.com/opencast/opencast/pull/4157)] -
+ Allow setting explicit id for themes
+- [[#4156](https://github.com/opencast/opencast/pull/4156)] -
+ Allow tags for ingesting attachments or catalogs via URL
+- [[#4152](https://github.com/opencast/opencast/pull/4152)] -
+ Bump checker-qual from 3.24.0 to 3.25.0 in /modules/db
+- [[#4149](https://github.com/opencast/opencast/pull/4149)] -
+ Bump @types/jest from 28.1.6 to 29.0.0 in /modules/lti
+- [[#4148](https://github.com/opencast/opencast/pull/4148)] -
+ Bump @fortawesome/fontawesome-svg-core from 6.1.2 to 6.2.0 in /modules/lti
+- [[#4147](https://github.com/opencast/opencast/pull/4147)] -
+ Bump react-i18next from 11.18.3 to 11.18.5 in /modules/lti
+- [[#4146](https://github.com/opencast/opencast/pull/4146)] -
+ Bump typescript from 4.7.4 to 4.8.2 in /modules/lti
+- [[#4145](https://github.com/opencast/opencast/pull/4145)] -
+ Bump i18next-browser-languagedetector from 6.1.4 to 6.1.5 in /modules/lti
+- [[#4144](https://github.com/opencast/opencast/pull/4144)] -
+ Bump @types/node from 18.6.3 to 18.7.14 in /modules/lti
+- [[#4143](https://github.com/opencast/opencast/pull/4143)] -
+ Bump @fortawesome/free-solid-svg-icons from 6.1.2 to 6.2.0 in /modules/lti
+- [[#4141](https://github.com/opencast/opencast/pull/4141)] -
+ Bump i18next from 21.8.16 to 21.9.1 in /modules/lti
+- [[#4140](https://github.com/opencast/opencast/pull/4140)] -
+ Bump chromedriver from 104.0.0 to 105.0.0 in /modules/admin-ui-frontend
+- [[#4139](https://github.com/opencast/opencast/pull/4139)] -
+ Bump react-bootstrap from 2.4.0 to 2.5.0 in /modules/lti
+- [[#4128](https://github.com/opencast/opencast/pull/4128)] -
+ Bump eslint from 8.22.0 to 8.23.0 in /modules/engage-paella-player-7
+- [[#4127](https://github.com/opencast/opencast/pull/4127)] -
+ Bump jquery from 3.6.0 to 3.6.1 in /modules/runtime-info-ui-ng
+- [[#4126](https://github.com/opencast/opencast/pull/4126)] -
+ Bump eslint from 8.22.0 to 8.23.0 in /modules/runtime-info-ui
+- [[#4125](https://github.com/opencast/opencast/pull/4125)] -
+ Bump eslint from 8.22.0 to 8.23.0 in /modules/runtime-info-ui-ng
+- [[#4124](https://github.com/opencast/opencast/pull/4124)] -
+ Bump jquery from 3.6.0 to 3.6.1 in /modules/engage-ui
+- [[#4123](https://github.com/opencast/opencast/pull/4123)] -
+ Bump jquery from 3.6.0 to 3.6.1 in /modules/runtime-info-ui
+- [[#4122](https://github.com/opencast/opencast/pull/4122)] -
+ Bump eslint from 8.22.0 to 8.23.0 in /modules/admin-ui-frontend
+- [[#4121](https://github.com/opencast/opencast/pull/4121)] -
+ Bump eslint from 8.22.0 to 8.23.0 in /modules/engage-paella-player
+- [[#4120](https://github.com/opencast/opencast/pull/4120)] -
+ Use bulk inserts for all services during index rebuild
+- [[#4116](https://github.com/opencast/opencast/pull/4116)] -
+ Remove Entwine Functional Library from Execute Service
+- [[#4115](https://github.com/opencast/opencast/pull/4115)] -
+ Bump html-validate from 7.3.2 to 7.3.3 in /modules/engage-paella-player-7
+- [[#4114](https://github.com/opencast/opencast/pull/4114)] -
+ Bump html-validate from 7.3.2 to 7.3.3 in /modules/admin-ui-frontend
+- [[#4112](https://github.com/opencast/opencast/pull/4112)] -
+ Bump postgresql from 42.4.1 to 42.5.0 in /modules/db
+- [[#4109](https://github.com/opencast/opencast/pull/4109)] -
+ Remove Entwine Functional Library from Userdirectory
+- [[#4108](https://github.com/opencast/opencast/pull/4108)] -
+ Remove code which is not loading any roles
+- [[#4106](https://github.com/opencast/opencast/pull/4106)] -
+ Bump html-validate from 7.3.1 to 7.3.2 in /modules/engage-paella-player-7
+- [[#4105](https://github.com/opencast/opencast/pull/4105)] -
+ Bump html-validate from 7.3.0 to 7.3.2 in /modules/admin-ui-frontend
+- [[#4102](https://github.com/opencast/opencast/pull/4102)] -
+ Move thumbnail preview generation to the client
+- [[#4099](https://github.com/opencast/opencast/pull/4099)] -
+ Bump html-validate from 7.3.0 to 7.3.1 in /modules/engage-paella-player-7
+- [[#4098](https://github.com/opencast/opencast/pull/4098)] -
+ Change default resolution of live schedule impl to standard 16:9
+- [[#4095](https://github.com/opencast/opencast/pull/4095)] -
+ Bump markdownlint-cli from 0.32.1 to 0.32.2 in /docs/guides
+- [[#4091](https://github.com/opencast/opencast/pull/4091)] -
+ Generate more of the release notes
+- [[#4082](https://github.com/opencast/opencast/pull/4082)] -
+ named the correct directory - Update workflow.md
+- [[#4081](https://github.com/opencast/opencast/pull/4081)] -
+ Bump eslint from 8.21.0 to 8.22.0 in /modules/engage-paella-player-7
+- [[#4080](https://github.com/opencast/opencast/pull/4080)] -
+ Bump eslint from 8.21.0 to 8.22.0 in /modules/runtime-info-ui-ng
+- [[#4079](https://github.com/opencast/opencast/pull/4079)] -
+ Bump eslint from 8.21.0 to 8.22.0 in /modules/runtime-info-ui
+- [[#4078](https://github.com/opencast/opencast/pull/4078)] -
+ Bump eslint from 8.21.0 to 8.22.0 in /modules/admin-ui-frontend
+- [[#4077](https://github.com/opencast/opencast/pull/4077)] -
+ Bump eslint from 8.21.0 to 8.22.0 in /modules/engage-paella-player
+- [[#4071](https://github.com/opencast/opencast/pull/4071)] -
+ Bump html-validate from 7.2.0 to 7.3.0 in /modules/engage-paella-player-7
+- [[#4070](https://github.com/opencast/opencast/pull/4070)] -
+ Bump html-validate from 7.2.0 to 7.3.0 in /modules/admin-ui-frontend
+- [[#4069](https://github.com/opencast/opencast/pull/4069)] -
+ Bump sass from 1.54.3 to 1.54.4 in /modules/admin-ui-frontend
+- [[#4061](https://github.com/opencast/opencast/pull/4061)] -
+ Update List of Committers
+- [[#4060](https://github.com/opencast/opencast/pull/4060)] -
+ Bump eslint from 8.20.0 to 8.21.0 in /modules/engage-paella-player-7
+- [[#4058](https://github.com/opencast/opencast/pull/4058)] -
+ Bump sass from 1.53.0 to 1.54.3 in /modules/admin-ui-frontend
+- [[#4056](https://github.com/opencast/opencast/pull/4056)] -
+ Bump html-validate from 7.1.2 to 7.2.0 in /modules/engage-paella-player-7
+- [[#4055](https://github.com/opencast/opencast/pull/4055)] -
+ Bump postgresql from 42.4.0 to 42.4.1 in /modules/db
+- [[#4054](https://github.com/opencast/opencast/pull/4054)] -
+ Bump checker-qual from 3.23.0 to 3.24.0 in /modules/db
+- [[#4052](https://github.com/opencast/opencast/pull/4052)] -
+ Bump chromedriver from 103.0.0 to 104.0.0 in /modules/admin-ui-frontend
+- [[#4051](https://github.com/opencast/opencast/pull/4051)] -
+ Bump html-validate from 7.1.2 to 7.2.0 in /modules/admin-ui-frontend
+- [[#4046](https://github.com/opencast/opencast/pull/4046)] -
+ Bump @babel/preset-env from 7.18.6 to 7.18.10 in /modules/engage-paella-player-7
+- [[#4045](https://github.com/opencast/opencast/pull/4045)] -
+ Bump @babel/core from 7.18.6 to 7.18.10 in /modules/engage-paella-player-7
+- [[#4044](https://github.com/opencast/opencast/pull/4044)] -
+ Target to released branches Paella 6 and 7 updates
+- [[#4042](https://github.com/opencast/opencast/pull/4042)] -
+ Bump eslint from 8.20.0 to 8.21.0 in /modules/runtime-info-ui-ng
+- [[#4043](https://github.com/opencast/opencast/pull/4043)] -
+ Bump eslint from 8.20.0 to 8.21.0 in /modules/runtime-info-ui
+- [[#4041](https://github.com/opencast/opencast/pull/4041)] -
+ Bump i18next from 21.8.14 to 21.8.16 in /modules/lti
+- [[#4040](https://github.com/opencast/opencast/pull/4040)] -
+ Bump @fortawesome/free-solid-svg-icons from 6.1.1 to 6.1.2 in /modules/lti
+- [[#4039](https://github.com/opencast/opencast/pull/4039)] -
+ Bump @types/node from 18.0.6 to 18.6.3 in /modules/lti
+- [[#4038](https://github.com/opencast/opencast/pull/4038)] -
+ Bump react-i18next from 11.18.1 to 11.18.3 in /modules/lti
+- [[#4037](https://github.com/opencast/opencast/pull/4037)] -
+ Bump @fortawesome/fontawesome-svg-core from 6.1.1 to 6.1.2 in /modules/lti
+- [[#4036](https://github.com/opencast/opencast/pull/4036)] -
+ Bump eslint from 8.20.0 to 8.21.0 in /modules/admin-ui-frontend
+- [[#4035](https://github.com/opencast/opencast/pull/4035)] -
+ Bump eslint from 8.20.0 to 8.21.0 in /modules/engage-paella-player
+- [[#4029](https://github.com/opencast/opencast/pull/4029)] -
+ Add comments in the event index
+- [[#4021](https://github.com/opencast/opencast/pull/4021)] -
+ Bump paella-core from 1.1.5 to 1.2.4 in /modules/engage-paella-player-7
+- [[#4020](https://github.com/opencast/opencast/pull/4020)] -
+ Bump markdownlint-cli from 0.31.1 to 0.32.1 in /docs/guides
+- [[#4019](https://github.com/opencast/opencast/pull/4019)] -
+ Bump webpack from 5.73.0 to 5.74.0 in /modules/engage-paella-player-7
+- [[#4018](https://github.com/opencast/opencast/pull/4018)] -
+ Bump jasmine-core from 4.2.0 to 4.3.0 in /modules/admin-ui-frontend
+- [[#4014](https://github.com/opencast/opencast/pull/4014)] -
+ Fail on configuration error
+- [[#4013](https://github.com/opencast/opencast/pull/4013)] -
+ Faster Blend Effects on Cuts
+- [[#4010](https://github.com/opencast/opencast/pull/4010)] -
+ Bump paella-zoom-plugin from 1.0.11 to 1.2.0 in /modules/engage-paella-player-7
+- [[#4009](https://github.com/opencast/opencast/pull/4009)] -
+ Bump terser from 5.14.1 to 5.14.2 in /modules/lti
+- [[#4008](https://github.com/opencast/opencast/pull/4008)] -
+ Fix Pom Version of Azure Transcription Service
+- [[#4002](https://github.com/opencast/opencast/pull/4002)] -
+ Bump paella-slide-plugins from 1.0.11 to 1.2.1 in /modules/engage-paella-player-7
+- [[#4001](https://github.com/opencast/opencast/pull/4001)] -
+ Bump @types/jest from 27.5.1 to 28.1.6 in /modules/lti
+- [[#4000](https://github.com/opencast/opencast/pull/4000)] -
+ Bump react-i18next from 11.18.0 to 11.18.1 in /modules/lti
+- [[#3999](https://github.com/opencast/opencast/pull/3999)] -
+ Bump bootstrap from 5.1.3 to 5.2.0 in /modules/lti
+- [[#3998](https://github.com/opencast/opencast/pull/3998)] -
+ Add navigation shortcuts in admin ui modals
+- [[#3997](https://github.com/opencast/opencast/pull/3997)] -
+ Bump @types/node from 18.0.1 to 18.0.6 in /modules/lti
+- [[#3996](https://github.com/opencast/opencast/pull/3996)] -
+ Bump i18next from 21.8.12 to 21.8.14 in /modules/lti
+- [[#3992](https://github.com/opencast/opencast/pull/3992)] -
+ Bump @babel/eslint-parser from 7.18.2 to 7.18.9 in /modules/engage-paella-player-7
+- [[#3989](https://github.com/opencast/opencast/pull/3989)] -
+ Bump paella-basic-plugins from 1.0.16 to 1.2.0 in /modules/engage-paella-player-7
+- [[#3988](https://github.com/opencast/opencast/pull/3988)] -
+ Bump eslint from 8.19.0 to 8.20.0 in /modules/engage-paella-player-7
+- [[#3987](https://github.com/opencast/opencast/pull/3987)] -
+ Bump eslint from 8.19.0 to 8.20.0 in /modules/runtime-info-ui-ng
+- [[#3986](https://github.com/opencast/opencast/pull/3986)] -
+ Bump eslint from 8.19.0 to 8.20.0 in /modules/runtime-info-ui
+- [[#3985](https://github.com/opencast/opencast/pull/3985)] -
+ Bump eslint from 8.19.0 to 8.20.0 in /modules/admin-ui-frontend
+- [[#3984](https://github.com/opencast/opencast/pull/3984)] -
+ Bump eslint from 8.19.0 to 8.20.0 in /modules/engage-paella-player
+- [[#3980](https://github.com/opencast/opencast/pull/3980)] -
+ Bump checker-qual from 3.22.2 to 3.23.0 in /modules/db
+- [[#3950](https://github.com/opencast/opencast/pull/3950)] -
+ Bump @types/react-dom from 18.0.5 to 18.0.6 in /modules/lti
+- [[#3949](https://github.com/opencast/opencast/pull/3949)] -
+ Bump react-i18next from 11.17.4 to 11.18.0 in /modules/lti
+- [[#3945](https://github.com/opencast/opencast/pull/3945)] -
+ Bump html-validate from 7.1.1 to 7.1.2 in /modules/engage-paella-player-7
+- [[#3944](https://github.com/opencast/opencast/pull/3944)] -
+ Bump html-validate from 7.1.1 to 7.1.2 in /modules/admin-ui-frontend
+- [[#3942](https://github.com/opencast/opencast/pull/3942)] -
+ Bump @types/node from 17.0.38 to 18.0.1 in /modules/lti
+- [[#3940](https://github.com/opencast/opencast/pull/3940)] -
+ Remove Helmet LTI Dependency
+- [[#3939](https://github.com/opencast/opencast/pull/3939)] -
+ Bump eslint from 8.18.0 to 8.19.0 in /modules/engage-paella-player-7
+- [[#3938](https://github.com/opencast/opencast/pull/3938)] -
+ Bump eslint from 8.18.0 to 8.19.0 in /modules/runtime-info-ui-ng
+- [[#3937](https://github.com/opencast/opencast/pull/3937)] -
+ Bump eslint from 8.18.0 to 8.19.0 in /modules/runtime-info-ui
+- [[#3936](https://github.com/opencast/opencast/pull/3936)] -
+ Bump eslint from 8.18.0 to 8.19.0 in /modules/admin-ui-frontend
+- [[#3935](https://github.com/opencast/opencast/pull/3935)] -
+ Bump eslint from 8.18.0 to 8.19.0 in /modules/engage-paella-player
+- [[#3933](https://github.com/opencast/opencast/pull/3933)] -
+ Updates karma-jasmine to 5.1.0
+- [[#3918](https://github.com/opencast/opencast/pull/3918)] -
+ Bump webpack-dev-server from 4.9.2 to 4.9.3 in /modules/engage-paella-player-7
+- [[#3917](https://github.com/opencast/opencast/pull/3917)] -
+ Bump jna from 5.11.0 to 5.12.1 in /modules/db
+- [[#3916](https://github.com/opencast/opencast/pull/3916)] -
+ Bump mariadb-java-client from 3.0.5 to 3.0.6 in /modules/db
+- [[#3903](https://github.com/opencast/opencast/pull/3903)] -
+ Common persistence util classes that also implement transaction retries
+- [[#3900](https://github.com/opencast/opencast/pull/3900)] -
+ Bump sass from 1.52.3 to 1.53.0 in /modules/admin-ui-frontend
+- [[#3899](https://github.com/opencast/opencast/pull/3899)] -
+ Bump chromedriver from 102.0.0 to 103.0.0 in /modules/admin-ui-frontend
+- [[#3897](https://github.com/opencast/opencast/pull/3897)] -
+ Bump grunt-contrib-uglify from 5.2.1 to 5.2.2 in /modules/admin-ui-frontend
+- [[#3893](https://github.com/opencast/opencast/pull/3893)] -
+ Rerun Failed Tests
+- [[#3892](https://github.com/opencast/opencast/pull/3892)] -
+ Corrects return value documentation for ingest endpoint
+- [[#3889](https://github.com/opencast/opencast/pull/3889)] -
+ Bump eslint from 8.17.0 to 8.18.0 in /modules/engage-paella-player-7
+- [[#3888](https://github.com/opencast/opencast/pull/3888)] -
+ Bump eslint from 8.17.0 to 8.18.0 in /modules/runtime-info-ui-ng
+- [[#3887](https://github.com/opencast/opencast/pull/3887)] -
+ Bump eslint from 8.17.0 to 8.18.0 in /modules/runtime-info-ui
+- [[#3886](https://github.com/opencast/opencast/pull/3886)] -
+ Bump eslint from 8.17.0 to 8.18.0 in /modules/admin-ui-frontend
+- [[#3885](https://github.com/opencast/opencast/pull/3885)] -
+ Bump eslint from 8.17.0 to 8.18.0 in /modules/engage-paella-player
+- [[#3880](https://github.com/opencast/opencast/pull/3880)] -
+ Update adopter deletion copy
+- [[#3878](https://github.com/opencast/opencast/pull/3878)] -
+ Bump prometheus.version from 0.15.0 to 0.16.0 in /modules/metrics-exporter
+- [[#3868](https://github.com/opencast/opencast/pull/3868)] -
+ Bump checker-qual from 3.22.1 to 3.22.2 in /modules/db
+- [[#3863](https://github.com/opencast/opencast/pull/3863)] -
+ Bump karma from 6.3.20 to 6.4.0 in /modules/admin-ui-frontend
+- [[#3859](https://github.com/opencast/opencast/pull/3859)] -
+ Bump webpack-cli from 4.9.2 to 4.10.0 in /modules/engage-paella-player-7
+- [[#3858](https://github.com/opencast/opencast/pull/3858)] -
+ Bump @babel/core from 7.18.2 to 7.18.5 in /modules/engage-paella-player-7
+- [[#3856](https://github.com/opencast/opencast/pull/3856)] -
+ Bump source-map-loader from 3.0.1 to 4.0.0 in /modules/engage-paella-player-7
+- [[#3854](https://github.com/opencast/opencast/pull/3854)] -
+ Bump paella-basic-plugins from 1.0.15 to 1.0.16 in /modules/engage-paella-player-7
+- [[#3852](https://github.com/opencast/opencast/pull/3852)] -
+ Bump postgresql from 42.3.6 to 42.4.0 in /modules/db
+- [[#3850](https://github.com/opencast/opencast/pull/3850)] -
+ Bump jasmine-core from 4.1.1 to 4.2.0 in /modules/admin-ui-frontend
+- [[#3849](https://github.com/opencast/opencast/pull/3849)] -
+ Amberscript configuration fix
+- [[#3846](https://github.com/opencast/opencast/pull/3846)] -
+ Bump sass from 1.52.1 to 1.52.3 in /modules/admin-ui-frontend
+- [[#3843](https://github.com/opencast/opencast/pull/3843)] -
+ Bump webpack-dev-server from 4.9.1 to 4.9.2 in /modules/engage-paella-player-7
+- [[#3842](https://github.com/opencast/opencast/pull/3842)] -
+ Bump chromedriver from 101.0.0 to 102.0.0 in /modules/admin-ui-frontend
+- [[#3840](https://github.com/opencast/opencast/pull/3840)] -
+ Bump eslint from 8.16.0 to 8.17.0 in /modules/engage-paella-player-7
+- [[#3839](https://github.com/opencast/opencast/pull/3839)] -
+ Bump eslint from 8.16.0 to 8.17.0 in /modules/runtime-info-ui
+- [[#3838](https://github.com/opencast/opencast/pull/3838)] -
+ Bump eslint from 8.16.0 to 8.17.0 in /modules/runtime-info-ui-ng
+- [[#3836](https://github.com/opencast/opencast/pull/3836)] -
+ Bump eslint from 8.16.0 to 8.17.0 in /modules/admin-ui-frontend
+- [[#3837](https://github.com/opencast/opencast/pull/3837)] -
+ Bump eslint from 8.16.0 to 8.17.0 in /modules/engage-paella-player
+- [[#3834](https://github.com/opencast/opencast/pull/3834)] -
+ Bump underscore from 1.13.3 to 1.13.4 in /modules/engage-ui
+- [[#3829](https://github.com/opencast/opencast/pull/3829)] -
+ Bump checker-qual from 3.22.0 to 3.22.1 in /modules/db
+- [[#3827](https://github.com/opencast/opencast/pull/3827)] -
+ Missing setting track logical name when serverless HLS in process-smil
+- [[#3826](https://github.com/opencast/opencast/pull/3826)] -
+ Bump webpack-dev-server from 4.9.0 to 4.9.1 in /modules/engage-paella-player-7
+- [[#3825](https://github.com/opencast/opencast/pull/3825)] -
+ Bump @types/node from 17.0.33 to 17.0.38 in /modules/lti
+- [[#3824](https://github.com/opencast/opencast/pull/3824)] -
+ Bump @types/react-dom from 18.0.4 to 18.0.5 in /modules/lti
+- [[#3823](https://github.com/opencast/opencast/pull/3823)] -
+ Bump i18next from 21.8.1 to 21.8.5 in /modules/lti
+- [[#3822](https://github.com/opencast/opencast/pull/3822)] -
+ Bump react-bootstrap from 2.3.1 to 2.4.0 in /modules/lti
+- [[#3821](https://github.com/opencast/opencast/pull/3821)] -
+ Bump typescript from 4.6.4 to 4.7.2 in /modules/lti
+- [[#3815](https://github.com/opencast/opencast/pull/3815)] -
+ Bump paella-user-tracking from 1.0.13 to 1.0.14 in /modules/engage-paella-player-7
+- [[#3804](https://github.com/opencast/opencast/pull/3804)] -
+ Bump @babel/eslint-parser from 7.17.0 to 7.18.2 in /modules/engage-paella-player-7
+- [[#3801](https://github.com/opencast/opencast/pull/3801)] -
+ Bump mariadb-java-client from 3.0.4 to 3.0.5 in /modules/db
+- [[#3799](https://github.com/opencast/opencast/pull/3799)] -
+ Update maven documentation
+- [[#3796](https://github.com/opencast/opencast/pull/3796)] -
+ Bump postgresql from 42.3.5 to 42.3.6 in /modules/db
+- [[#3794](https://github.com/opencast/opencast/pull/3794)] -
+ Replace Deprecated Code
+- [[#3793](https://github.com/opencast/opencast/pull/3793)] -
+ Bump eslint from 8.15.0 to 8.16.0 in /modules/engage-paella-player-7
+- [[#3792](https://github.com/opencast/opencast/pull/3792)] -
+ Bump html-validate from 7.1.0 to 7.1.1 in /modules/engage-paella-player-7
+- [[#3791](https://github.com/opencast/opencast/pull/3791)] -
+ Bump eslint from 8.15.0 to 8.16.0 in /modules/runtime-info-ui
+- [[#3790](https://github.com/opencast/opencast/pull/3790)] -
+ Bump eslint from 8.15.0 to 8.16.0 in /modules/runtime-info-ui-ng
+- [[#3789](https://github.com/opencast/opencast/pull/3789)] -
+ Bump html-validate from 7.1.0 to 7.1.1 in /modules/admin-ui-frontend
+- [[#3788](https://github.com/opencast/opencast/pull/3788)] -
+ Bump eslint from 8.15.0 to 8.16.0 in /modules/admin-ui-frontend
+- [[#3787](https://github.com/opencast/opencast/pull/3787)] -
+ Bump sass from 1.50.1 to 1.52.1 in /modules/admin-ui-frontend
+- [[#3786](https://github.com/opencast/opencast/pull/3786)] -
+ Bump eslint from 8.15.0 to 8.16.0 in /modules/engage-paella-player
+- [[#3784](https://github.com/opencast/opencast/pull/3784)] -
+ Bump @babel/core from 7.17.10 to 7.18.0 in /modules/engage-paella-player-7
+- [[#3783](https://github.com/opencast/opencast/pull/3783)] -
+ Bump @babel/preset-env from 7.17.10 to 7.18.0 in /modules/engage-paella-player-7
+- [[#3778](https://github.com/opencast/opencast/pull/3778)] -
+ Update Branch Cut Announcement
+- [[#3776](https://github.com/opencast/opencast/pull/3776)] -
+ Bump copy-webpack-plugin from 10.2.4 to 11.0.0 in /modules/engage-paella-player-7
+- [[#3771](https://github.com/opencast/opencast/pull/3771)] -
+ Bump paella-core from 1.0.49 to 1.0.51 in /modules/engage-paella-player-7
+- [[#3767](https://github.com/opencast/opencast/pull/3767)] -
+ Patch for admin-ui-frontend Gruntfile.js when developing locally and using a remote proxy.
+- [[#3757](https://github.com/opencast/opencast/pull/3757)] -
+ Bump webpack from 5.72.0 to 5.72.1 in /modules/engage-paella-player-7
+- [[#3741](https://github.com/opencast/opencast/pull/3741)] -
+ ADD specialist worker nodes
+- [[#3730](https://github.com/opencast/opencast/pull/3730)] -
+ Bump express from 4.17.3 to 4.18.1 in /modules/engage-paella-player
+- [[#3714](https://github.com/opencast/opencast/pull/3714)] -
+ Bump esapi from 2.1.0.1 to 2.3.0.0
+- [[#3713](https://github.com/opencast/opencast/pull/3713)] -
+ Add catalog ui adapter organization wildcard support
+- [[#3670](https://github.com/opencast/opencast/pull/3670)] -
+ Added track upload endpoint the External Events Api
+- [[#3607](https://github.com/opencast/opencast/pull/3607)] -
+ Extract JobDispatcher into its own class
+- [[#3274](https://github.com/opencast/opencast/pull/3274)] -
+ Index Extended Metadata
+- [[#3218](https://github.com/opencast/opencast/pull/3218)] -
+ Opencast Plugin Manager
+
+Opencast 12
+-----------
+
+### Opencast 12.7
+
+*Released on January 18th, 2023*
+
+- [[#4590](https://github.com/opencast/opencast/pull/4590)] -
+ Add Tag-Engage Workflow Operation Handler
+- [[#4563](https://github.com/opencast/opencast/pull/4563)] -
+ Fix Wowza signing time scale
+- [[#4550](https://github.com/opencast/opencast/pull/4550)] -
+ Ensure segments.segment is array
+- [[#4549](https://github.com/opencast/opencast/pull/4549)] -
+ Sync login script of paella-6 and paella-7
+- [[#4539](https://github.com/opencast/opencast/pull/4539)] -
+ Make event updating faster after changes to series metadata/ACL
+
+### Opencast 12.6
+
+*Released on December 14th, 2022*
+
+- [[#4528](https://github.com/opencast/opencast/pull/4528)] -
+ Allow creating releases manually
+- [[#4523](https://github.com/opencast/opencast/pull/4523)] -
+ Allow `ROLE_ADMIN_UI` to run index.js
+- [[#4518](https://github.com/opencast/opencast/pull/4518)] -
+ Remove braces from error message
+- [[#4496](https://github.com/opencast/opencast/pull/4496)] -
+ Fix Firefox install for admin ui tests in GHA
+- [[#4494](https://github.com/opencast/opencast/pull/4494)] -
+ Decode URL before parsing in PaellaPlayer 6
+- [[#4486](https://github.com/opencast/opencast/pull/4486)] -
+ Do not forget videos detected previously in Paella
+- [[#4459](https://github.com/opencast/opencast/pull/4459)] -
+ Update Release Assemblies
+
+### Opencast 12.5
+
+*Released on November 16th, 2022*
+
+- [[#4441](https://github.com/opencast/opencast/pull/4441)] -
+ Azure transcription service improvements
+- [[#4439](https://github.com/opencast/opencast/pull/4439)] -
+ Fix Tobira API version
+- [[#4436](https://github.com/opencast/opencast/pull/4436)] -
+ Batch Dependabot Updates for Paella 7
+- [[#4416](https://github.com/opencast/opencast/pull/4416)] -
+ Allow dots in template file names
+- [[#4411](https://github.com/opencast/opencast/pull/4411)] -
+ Let Editor know if files are available locally
+- [[#4410](https://github.com/opencast/opencast/pull/4410)] -
+ Replace Entwine Functional Library in Editor
+- [[#4406](https://github.com/opencast/opencast/pull/4406)] -
+ Batch Dependabot Updates for Paella 7
+- [[#4392](https://github.com/opencast/opencast/pull/4392)] -
+ Batch Dependabot Updates for Paella 7
+- [[#4391](https://github.com/opencast/opencast/pull/4391)] -
+ Batch Dependabot Updates for Paella 7
+- [[#4381](https://github.com/opencast/opencast/pull/4381)] -
+ Fix workflow typo in docs
+- [[#4378](https://github.com/opencast/opencast/pull/4378)] -
+ Drop Hold State Test
+- [[#4377](https://github.com/opencast/opencast/pull/4377)] -
+ Do not add roleprefix to extra roles
+- [[#4375](https://github.com/opencast/opencast/pull/4375)] -
+ Use UTF-8 as charset for HTML mails
+- [[#4373](https://github.com/opencast/opencast/pull/4373)] -
+ Bump html-validate from 7.6.0 to 7.7.1 in /modules/engage-paella-player-7
+- [[#4370](https://github.com/opencast/opencast/pull/4370)] -
+ Correctly identify the master playlist in the Tobira harvest
+- [[#4367](https://github.com/opencast/opencast/pull/4367)] -
+ Bump eslint from 8.25.0 to 8.26.0 in /modules/engage-paella-player-7
+- [[#4353](https://github.com/opencast/opencast/pull/4353)] -
+ Fully Automate GitHub Release
+- [[#4352](https://github.com/opencast/opencast/pull/4352)] -
+ Automate Release Process
+- [[#4350](https://github.com/opencast/opencast/pull/4350)] -
+ Lower JWT error logging to debug level
+
+### Opencast 12.4
+
+*Released on October 19th, 2022*
+
+- [[#4346](https://github.com/opencast/opencast/pull/4346)] -
+ Generate more of the release notes
+- [[#4345](https://github.com/opencast/opencast/pull/4345)] -
+ Add Opencast 12.4 release notes
+- [[#4340](https://github.com/opencast/opencast/pull/4340)] -
+ Fix saving thumbnails if no previous ones existed
+- [[#4337](https://github.com/opencast/opencast/pull/4337)] -
+ Bump paella-core from 1.7.0 to 1.8.1 in /modules/engage-paella-player-7
+- [[#4329](https://github.com/opencast/opencast/pull/4329)] -
+ Make Workflow Operation Docs Look Alike
+- [[#4328](https://github.com/opencast/opencast/pull/4328)] -
+ Specify Units in Video Clips
+- [[#4324](https://github.com/opencast/opencast/pull/4324)] -
+ Update hostname to use server url in adopter registration information
+- [[#4322](https://github.com/opencast/opencast/pull/4322)] -
+ Make Workflow Operation Docs Look Alike
+- [[#4317](https://github.com/opencast/opencast/pull/4317)] -
+ Fix NullPointerException when editor does not send subtitles
+- [[#4314](https://github.com/opencast/opencast/pull/4314)] -
+ Reuse mediapackage object from workflow instance where possible
+- [[#4313](https://github.com/opencast/opencast/pull/4313)] -
+ Skip check if user has global admin role
+- [[#4311](https://github.com/opencast/opencast/pull/4311)] -
+ Bump @babel/preset-env from 7.19.3 to 7.19.4 in /modules/engage-paella-player-7
+- [[#4308](https://github.com/opencast/opencast/pull/4308)] -
+ Save button for event/series "Access policy"-tab
+- [[#4307](https://github.com/opencast/opencast/pull/4307)] -
+ Publish Captions by Default
+- [[#4306](https://github.com/opencast/opencast/pull/4306)] -
+ Bump source-map-loader from 4.0.0 to 4.0.1 in /modules/engage-paella-player-7
+- [[#4305](https://github.com/opencast/opencast/pull/4305)] -
+ Bump html-validate from 7.5.0 to 7.6.0 in /modules/engage-paella-player-7
+- [[#4304](https://github.com/opencast/opencast/pull/4304)] -
+ Bump express from 4.18.1 to 4.18.2 in /modules/engage-paella-player-7
+- [[#4303](https://github.com/opencast/opencast/pull/4303)] -
+ Bump eslint from 8.24.0 to 8.25.0 in /modules/engage-paella-player-7
+- [[#4302](https://github.com/opencast/opencast/pull/4302)] -
+ Bump paella-slide-plugins from 1.2.1 to 1.7.1 in /modules/engage-paella-player-7
+- [[#4294](https://github.com/opencast/opencast/pull/4294)] -
+ Batch Dependabot Updates for Paella 7
+- [[#4287](https://github.com/opencast/opencast/pull/4287)] -
+ Update editor release 2022-10-19
+- [[#4276](https://github.com/opencast/opencast/pull/4276)] -
+ Batch Dependabot Updates for Paella 7
+- [[#4274](https://github.com/opencast/opencast/pull/4274)] -
+ Fix single radio button in new-task UI
+- [[#4270](https://github.com/opencast/opencast/pull/4270)] -
+ Add back workflow API documentation
+- [[#4269](https://github.com/opencast/opencast/pull/4269)] -
+ Fix snapshot moving
+- [[#4247](https://github.com/opencast/opencast/pull/4247)] -
+ Bump eslint from 8.23.1 to 8.24.0 in /modules/engage-paella-player-7
+- [[#4240](https://github.com/opencast/opencast/pull/4240)] -
+ Group dependabot Paella 7 commits
+- [[#4238](https://github.com/opencast/opencast/pull/4238)] -
+ Fixed azure transcription error message in case of Error
+- [[#4229](https://github.com/opencast/opencast/pull/4229)] -
+ Make busy waiting explicit during InboxScannerService config update
+- [[#4227](https://github.com/opencast/opencast/pull/4227)] -
+ Bump mariadb-java-client from 3.0.7 to 3.0.8 in /modules/db
+
+
+### Opencast 12.3
+
+*Released on September 21th, 2022*
+
+- [[#4220](https://github.com/opencast/opencast/pull/4220)] -
+ Remove unused configuration
+- [[#4219](https://github.com/opencast/opencast/pull/4219)] -
+ Ignore NoSuchFileException when cleaning directories
+- [[#4213](https://github.com/opencast/opencast/pull/4213)] -
+ Fix check if all workflows were loaded when using YAML
+- [[#4207](https://github.com/opencast/opencast/pull/4207)] -
+ Do not run dependabot pushes multiple times
+- [[#4197](https://github.com/opencast/opencast/pull/4197)] -
+ Bump eslint from 8.23.0 to 8.23.1 in /modules/engage-paella-player-7
+- [[#4187](https://github.com/opencast/opencast/pull/4187)] -
+ Dont run gh actions on dbot multiple times
+- [[#4178](https://github.com/opencast/opencast/pull/4178)] -
+ Fix filename dependency on locale
+- [[#4177](https://github.com/opencast/opencast/pull/4177)] -
+ Bump webpack-dev-server from 4.9.3 to 4.11.0 in /modules/engage-paella-player-7
+- [[#4168](https://github.com/opencast/opencast/pull/4168)] -
+ Bump html-validate from 7.2.0 to 7.3.3 in /modules/engage-paella-player-7
+- [[#4165](https://github.com/opencast/opencast/pull/4165)] -
+ Bump eslint from 8.21.0 to 8.23.0 in /modules/engage-paella-player-7
+- [[#4151](https://github.com/opencast/opencast/pull/4151)] -
+ Allow global admins to always get workflow instances for a media package
+- [[#4137](https://github.com/opencast/opencast/pull/4137)] -
+ Delete scheduled events fixed (fixes #4084)
+- [[#4134](https://github.com/opencast/opencast/pull/4134)] -
+ Update CentOS Stream/RHEL documentation
+- [[#4129](https://github.com/opencast/opencast/pull/4129)] -
+ Add Tobira module for Synchronization with an external Tobira application
+- [[#4113](https://github.com/opencast/opencast/pull/4113)] -
+ Add Dummy capture agent documentation
+- [[#4111](https://github.com/opencast/opencast/pull/4111)] -
+ add missing reference target
+- [[#4107](https://github.com/opencast/opencast/pull/4107)] -
+ Fix Publication to Workspace Operation Documentation
+- [[#4104](https://github.com/opencast/opencast/pull/4104)] -
+ Document broken MariaDB upgrade script
+- [[#4103](https://github.com/opencast/opencast/pull/4103)] -
+ Revert try-catch in 12.x MariaDB upgrade script
+- [[#4101](https://github.com/opencast/opencast/pull/4101)] -
+ Fixes mysql upgrade script stop error
+- [[#4094](https://github.com/opencast/opencast/pull/4094)] -
+ Replace DownloadDistributionService target filter with aws version
+
+
+### Opencast 12.2
+
+*Released on August 17th, 2022*
+
+- [[#4087](https://github.com/opencast/opencast/pull/4087)] -
+ Link the docs for the publication to workspace WOH
+- [[#4064](https://github.com/opencast/opencast/pull/4064)] -
+ Fallback for Event Title in Publication
+- [[#4063](https://github.com/opencast/opencast/pull/4063)] -
+ Warn About Removed Workflow Endpoint
+- [[#4059](https://github.com/opencast/opencast/pull/4059)] -
+ Bump mariadb-java-client from 3.0.6 to 3.0.7 in /modules/db
+- [[#4057](https://github.com/opencast/opencast/pull/4057)] -
+ Fixed OSGI annotation for OaiPmhServer
+- [[#4049](https://github.com/opencast/opencast/pull/4049)] -
+ Update Opencast Studio to 2022-08-03
+- [[#4048](https://github.com/opencast/opencast/pull/4048)] -
+ Don't Fail on Missing Jobs
+- [[#4032](https://github.com/opencast/opencast/pull/4032)] -
+ Clarify migration script dependencies and make aware of the mysql_connector_python error
+- [[#4031](https://github.com/opencast/opencast/pull/4031)] -
+ Remove ManagedService from LtiServiceImpl
+- [[#4030](https://github.com/opencast/opencast/pull/4030)] -
+ Removing remaining activemq docs
+- [[#4027](https://github.com/opencast/opencast/pull/4027)] -
+ Add new config `list-all-jobs-in-series` to LtiServiceImpl
+- [[#4025](https://github.com/opencast/opencast/pull/4025)] -
+ Update CAS docs
+- [[#4016](https://github.com/opencast/opencast/pull/4016)] -
+ Force inject ChainingMediaPackageSerializer as MediaPackageSeriailzer
+- [[#4015](https://github.com/opencast/opencast/pull/4015)] -
+ Remove ActiveMQ related steps from doc
+- [[#4012](https://github.com/opencast/opencast/pull/4012)] -
+ Prevent Redirect When Going to Studio
+- [[#4005](https://github.com/opencast/opencast/pull/4005)] -
+ Allow Admins Access to Editor Interface
+- [[#4004](https://github.com/opencast/opencast/pull/4004)] -
+ MariaDB Connector Bugfix Update
+- [[#3995](https://github.com/opencast/opencast/pull/3995)] -
+ Avoid GitHub Actions Scheduling Conflicts
+
+
+### Opencast 12.1
+
+*Released on July 20th, 2022*
+
+- [[#3966](https://github.com/opencast/opencast/pull/3966)] -
+ Mark Opencast 12 RPMs as ready
+- [[#3965](https://github.com/opencast/opencast/pull/3965)] -
+ Update Editor to Version 2022-07-08
+- [[#3964](https://github.com/opencast/opencast/pull/3964)] -
+ Backport Paella 7 updates from develop
+- [[#3958](https://github.com/opencast/opencast/pull/3958)] -
+ Fail early on missing encoding profile
+- [[#3957](https://github.com/opencast/opencast/pull/3957)] -
+ Fix sendmail UnsupportedDataType exception
+- [[#3954](https://github.com/opencast/opencast/pull/3954)] -
+ Handle process stdout and stderr
+- [[#3951](https://github.com/opencast/opencast/pull/3951)] -
+ Allow for more diverse exception throwing WorkflowService.start()
+- [[#3941](https://github.com/opencast/opencast/pull/3941)] -
+ Fix MariaDB Database Driver
+- [[#3920](https://github.com/opencast/opencast/pull/3920)] -
+ Automate the language selection in the transcription workflow of amberscript
+- [[#3913](https://github.com/opencast/opencast/pull/3913)] -
+ Allow Inbox Scanner to parse date formats
+- [[#3912](https://github.com/opencast/opencast/pull/3912)] -
+ Always store ACE entries in JSON as array
+- [[#3908](https://github.com/opencast/opencast/pull/3908)] -
+ Add authentication entry point with redirect query parameter support
+- [[#3906](https://github.com/opencast/opencast/pull/3906)] -
+ Add "Create new event with metadata from another event" button to Admin UI
+- [[#3901](https://github.com/opencast/opencast/pull/3901)] -
+ Paella 7: Use master tracks in HLS serverless mode
+- [[#3896](https://github.com/opencast/opencast/pull/3896)] -
+ Add Azure Transcription Integration
+- [[#3890](https://github.com/opencast/opencast/pull/3890)] -
+ fix brightspace api with large datasets
+- [[#3883](https://github.com/opencast/opencast/pull/3883)] -
+ Add formal Opensearch support
+- [[#3876](https://github.com/opencast/opencast/pull/3876)] -
+ Remove Solr from Admin Node
+- [[#3874](https://github.com/opencast/opencast/pull/3874)] -
+ Update Changelog
+- [[#3873](https://github.com/opencast/opencast/pull/3873)] -
+ Finish the Opencast 12 release notes
+- [[#3872](https://github.com/opencast/opencast/pull/3872)] -
+ Opencast 12 Upgrade Guide
+
+
+### Opencast 12.0
+
+Dependabot's changes are excluded from this log.
+
+*Released on June 15th, 2022*
+
+- [[#3870](https://github.com/opencast/opencast/pull/3870)] -
+ Update Editor to Version 2022-06-15
+- [[#3867](https://github.com/opencast/opencast/pull/3867)] -
+ Update Opencast Studio to 2022-06-15
+- [[#3866](https://github.com/opencast/opencast/pull/3866)] -
+ Add description to publish workflow
+- [[#3865](https://github.com/opencast/opencast/pull/3865)] -
+ Rename yaml workflow title
+- [[#3864](https://github.com/opencast/opencast/pull/3864)] -
+ Fix duplicate dependency declaration
+- [[#3862](https://github.com/opencast/opencast/pull/3862)] -
+ Make Delete Dialog Look Alike
+- [[#3851](https://github.com/opencast/opencast/pull/3851)] -
+ Fix submitter not being displayed in the event workflow details
+- [[#3830](https://github.com/opencast/opencast/pull/3830)] -
+ Paella7 fix usertracking
+- [[#3828](https://github.com/opencast/opencast/pull/3828)] -
+ Further workflow test race fixes
+- [[#3819](https://github.com/opencast/opencast/pull/3819)] -
+ Update paella7 configuration
+- [[#3818](https://github.com/opencast/opencast/pull/3818)] -
+ Workflow tests should no longer race
+- [[#3816](https://github.com/opencast/opencast/pull/3816)] -
+ Removing unnecessary workflow index data from rebuild
+- [[#3813](https://github.com/opencast/opencast/pull/3813)] -
+ Properly unregister OAI-PMH servlet
+- [[#3812](https://github.com/opencast/opencast/pull/3812)] -
+ Fix rest services are unavailable under certain circumstances
+- [[#3811](https://github.com/opencast/opencast/pull/3811)] -
+ Remove red check mark when editing metadata
+- [[#3810](https://github.com/opencast/opencast/pull/3810)] -
+ No Elasticsearch Use In Ingest
+- [[#3806](https://github.com/opencast/opencast/pull/3806)] -
+ Speech to text language fallback and placeholder
+- [[#3780](https://github.com/opencast/opencast/pull/3780)] -
+ Send waveform URIs to new editor
+- [[#3775](https://github.com/opencast/opencast/pull/3775)] -
+ Indexing only latest workflows for all events
+- [[#3554](https://github.com/opencast/opencast/pull/3554)] -
+ Copy Mediapackage elements from the publication to mediapackage
+- [[#1370](https://github.com/opencast/opencast/pull/1370)] -
+ Fix Conflict Detection
+- [[#3766](https://github.com/opencast/opencast/pull/3766)] -
+ Fix Conductor OSGi Bindings
+- [[#3751](https://github.com/opencast/opencast/pull/3751)] -
+ Update paella 7 dependencies
+- [[#3749](https://github.com/opencast/opencast/pull/3749)] -
+ Explore H2 Database
+- [[#3718](https://github.com/opencast/opencast/pull/3718)] -
+ fix transcription workflowoperation dependency
+- [[#3696](https://github.com/opencast/opencast/pull/3696)] -
+ Remove Entwine Library from Media Inspector
+- [[#3695](https://github.com/opencast/opencast/pull/3695)] -
+ Remove Unused Code
+- [[#3693](https://github.com/opencast/opencast/pull/3693)] -
+ fix cover-image-remote package import
+- [[#3691](https://github.com/opencast/opencast/pull/3691)] -
+ Deprecate Media Package Internal Metadata
+- [[#3689](https://github.com/opencast/opencast/pull/3689)] -
+ Less Entwine Functional Library
+- [[#3687](https://github.com/opencast/opencast/pull/3687)] -
+ Changed inbox behaviour for additional files for scheduled events
+- [[#3685](https://github.com/opencast/opencast/pull/3685)] -
+ Silence npm autoupdate
+- [[#3671](https://github.com/opencast/opencast/pull/3671)] -
+ Fix Misspelled Variable
+- [[#3659](https://github.com/opencast/opencast/pull/3659)] -
+ Fix Merge of JavaScript Auto-Updates
+- [[#3658](https://github.com/opencast/opencast/pull/3658)] -
+ Fix list formatting in developer guide
+- [[#3632](https://github.com/opencast/opencast/pull/3632)] -
+ Fix build of Paella Player 7 when local npm is being used (mvn install -Pfrontend-no-prebuilt)
+- [[#3628](https://github.com/opencast/opencast/pull/3628)] -
+ Sort Modules Alphabetically
+- [[#3627](https://github.com/opencast/opencast/pull/3627)] -
+ Fix missing OSGI annotation for Caption service converters
+- [[#3620](https://github.com/opencast/opencast/pull/3620)] -
+ Update link to the annotion-tool list in the docs
+- [[#3601](https://github.com/opencast/opencast/pull/3601)] -
+ Fix smil marshalling for mediapackage tracks typed as SmilMediaReferenceImpl
+- [[#3584](https://github.com/opencast/opencast/pull/3584)] -
+ Updated the list of mailinglists on the docs landing page
+- [[#3566](https://github.com/opencast/opencast/pull/3566)] -
+ Auto update engage-ui test libraries
+- [[#3552](https://github.com/opencast/opencast/pull/3552)] -
+ Fix version sorting in Matrix room bot
+- [[#3551](https://github.com/opencast/opencast/pull/3551)] -
+ Silence npm auto update in the case where no updates are needed
+- [[#3549](https://github.com/opencast/opencast/pull/3549)] -
+ Auto-update all Theodul JavaScript Test libraries
+- [[#3542](https://github.com/opencast/opencast/pull/3542)] -
+ Upgrade Karaf and CXF
+- [[#3521](https://github.com/opencast/opencast/pull/3521)] -
+ Support yaml workflow definition
+- [[#3516](https://github.com/opencast/opencast/pull/3516)] -
+ Keyboard shortcut permission
+- [[#3507](https://github.com/opencast/opencast/pull/3507)] -
+ Auto-update JavaScript Test libraries
+- [[#3506](https://github.com/opencast/opencast/pull/3506)] -
+ Admin UI Node Version
+- [[#3500](https://github.com/opencast/opencast/pull/3500)] -
+ Code Cleanup
+- [[#3471](https://github.com/opencast/opencast/pull/3471)] -
+ Matrix room description update fix
+- [[#3461](https://github.com/opencast/opencast/pull/3461)] -
+ Fix meeting time
+- [[#3443](https://github.com/opencast/opencast/pull/3443)] -
+ Regenerate `package-lock.json`
+- [[#3441](https://github.com/opencast/opencast/pull/3441)] -
+ Update EasyMock to 4.3
+- [[#3440](https://github.com/opencast/opencast/pull/3440)] -
+ Update Jackson Libraries to 2.13.1
+- [[#3439](https://github.com/opencast/opencast/pull/3439)] -
+ Update PostegreSQL Driver
+- [[#3438](https://github.com/opencast/opencast/pull/3438)] -
+ Update MariaDB Driver
+- [[#3431](https://github.com/opencast/opencast/pull/3431)] -
+ Remove ManagedService from OaiPmhServer
+- [[#3424](https://github.com/opencast/opencast/pull/3424)] -
+ Remove reference annotation name attribute if possible
+- [[#3422](https://github.com/opencast/opencast/pull/3422)] -
+ Refactor XACMLAuthorizationService
+- [[#3385](https://github.com/opencast/opencast/pull/3385)] -
+ Migrate to annotations cleanup
+- [[#3377](https://github.com/opencast/opencast/pull/3377)] -
+ Remove Solr from WorkflowService
+- [[#3376](https://github.com/opencast/opencast/pull/3376)] -
+ Change the way workflows are stored in the database from XML to tables
+- [[#3366](https://github.com/opencast/opencast/pull/3366)] -
+ Update pom version for develop
+- [[#3326](https://github.com/opencast/opencast/pull/3326)] -
+ Add recommended practices for Release manager
+- [[#3323](https://github.com/opencast/opencast/pull/3323)] -
+ Fix branches on docs.opencast.org
+- [[#3296](https://github.com/opencast/opencast/pull/3296)] -
+ Added missing endpoint to documentation of base api.
+- [[#3262](https://github.com/opencast/opencast/pull/3262)] -
+ Modernize Code
+- [[#3255](https://github.com/opencast/opencast/pull/3255)] -
+ Migrate to declarative services
+- [[#3250](https://github.com/opencast/opencast/pull/3250)] -
+ Improve deleting events from index
+- [[#3204](https://github.com/opencast/opencast/pull/3204)] -
+ Remove Solr from series service
+- [[#3187](https://github.com/opencast/opencast/pull/3187)] -
+ Mediapackage directory cleanup
+- [[#3167](https://github.com/opencast/opencast/pull/3167)] -
+ Fix#3164 assetmanager move to s3
+- [[#3162](https://github.com/opencast/opencast/pull/3162)] -
+ Paella player 7
+- [[#3161](https://github.com/opencast/opencast/pull/3161)] -
+ Removed Solr from Series Service
+- [[#3159](https://github.com/opencast/opencast/pull/3159)] -
+ Remove check for tracks for OAI-PMH
+- [[#3100](https://github.com/opencast/opencast/pull/3100)] -
+ Remove ActiveMQ dependencies
+
Opencast 11
----------
+### Opencast 11.12
+
+*Released on November 16th, 2022*
+
+- [[#4382](https://github.com/opencast/opencast/pull/4382)] -
+ Fix Encoding Profile Type Handling in Encode WOH
+- [[#4332](https://github.com/opencast/opencast/pull/4332)] -
+ CVE-2022-42889 library upgrade
+- [[#4316](https://github.com/opencast/opencast/pull/4316)] -
+ Update Live Publication in Archive on Capture Agent Change
+- [[#4250](https://github.com/opencast/opencast/pull/4250)] -
+ Actually Retract Live Publication
+- [[#4249](https://github.com/opencast/opencast/pull/4249)] -
+ Make initialization of new event ACL with series ACL in the Admin UI configurable
+- [[#4242](https://github.com/opencast/opencast/pull/4242)] -
+ Bump eslint from 8.23.1 to 8.24.0 in /modules/engage-paella-player
+- [[#4230](https://github.com/opencast/opencast/pull/4230)] -
+ Opencast 11.11 release notes
+- [[#4208](https://github.com/opencast/opencast/pull/4208)] -
+ Fix composer incident codes and messages for process-smil and multiencode.
+- [[#4169](https://github.com/opencast/opencast/pull/4169)] -
+ Bump express from 4.17.3 to 4.18.1 in /modules/engage-paella-player
+
+### Opencast 11.11
+
+*Released on September 21th, 2022*
+
+- [[#4200](https://github.com/opencast/opencast/pull/4200)] -
+ Add size to term aggregation in order to return more than 10 terms
+- [[#4185](https://github.com/opencast/opencast/pull/4185)] -
+ Fix for S3 asset storage not releasing http connections
+- [[#4182](https://github.com/opencast/opencast/pull/4182)] -
+ Fix race condition when loading workflow definitions
+- [[#4172](https://github.com/opencast/opencast/pull/4172)] -
+ Allow upload of multiple assets with the same flavor (based on config)
+- [[#4164](https://github.com/opencast/opencast/pull/4164)] -
+ Use getObjectMetadata to get object version when uploading file to S3 archive (fixes #4161)
+- [[#4159](https://github.com/opencast/opencast/pull/4159)] -
+ Fix search service limit - update more than 10 events for a series change
+- [[#4155](https://github.com/opencast/opencast/pull/4155)] -
+ Fix ingest of series catalog via external URL
+- [[#4155](https://github.com/opencast/opencast/pull/4155)] -
+ Fix workflow config handover from ingest to scheduler service
+- [[#4119](https://github.com/opencast/opencast/pull/4119)] -
+ Respect system settings when sending adopter data
+- [[#3681](https://github.com/opencast/opencast/pull/3681)] -
+ Make deletion of live publication in case of capture errors configurable
+
+### Opencast 11.10
+
+*Released on August 17th, 2022*
+
+- [[#4068](https://github.com/opencast/opencast/pull/4068)] -
+ Fix CreatorDate Filter in GET api/series/
+- [[#3990](https://github.com/opencast/opencast/pull/3990)] -
+ Remove Graphviz from Documentation
+- [[#3952](https://github.com/opencast/opencast/pull/3952)] -
+ Add changelog and release notes for OC 11.9
+- [[#3923](https://github.com/opencast/opencast/pull/3923)] -
+ Handle tracks with multiple videos in engage player
+
+### Opencast 11.9
+
+*Released on July 6th, 2022*
+
+- [[#3915](https://github.com/opencast/opencast/pull/3915)] -
+ Fix Ingest Service Download Feature
+- [[#3907](https://github.com/opencast/opencast/pull/3907)] -
+ Split url parameter on first equal sign
+- [[#3902](https://github.com/opencast/opencast/pull/3902)] -
+ Fix seriesname solver when ID is shorter than 7 characters
+- [[#3882](https://github.com/opencast/opencast/pull/3882)] -
+ Adopter wizard botton text repair
+- [[#3881](https://github.com/opencast/opencast/pull/3881)] -
+ Fix admin ui proxy
+- [[#3871](https://github.com/opencast/opencast/pull/3871)] -
+ Add changelog and release notes for OC 11.8
+- [[#3805](https://github.com/opencast/opencast/pull/3805)] -
+ Set Title and start date and time for duplicate events using duplicate WFH
+
+### Opencast 11.8
+
+*Released on June 15th, 2022*
+
+- [[#3808](https://github.com/opencast/opencast/pull/3808)] -
+ Add missing PRs to OC11 changelog
+- [[#3785](https://github.com/opencast/opencast/pull/3785)] -
+ Clarify that #3715 was a fix in the release notes
+- [[#3777](https://github.com/opencast/opencast/pull/3777)] -
+ Add changelog and release notes for OC 11.7
+- [[#3672](https://github.com/opencast/opencast/pull/3672)] -
+ Disable group removement upon missing group roles
+
+### Opencast 11.7
+
+*Released on May 18th, 2022*
+
+- [[#3716](https://github.com/opencast/opencast/pull/3716)] -
+ Add missing tags in encode WOH
+- [[#3715](https://github.com/opencast/opencast/pull/3715)] -
+ Unbreak the metadata editor included with the video editor and save events as
+ well as the video editor state when save is pressed
+- [[#3708](https://github.com/opencast/opencast/pull/3708)] -
+ partial-publish workflow fix
+- [[#3707](https://github.com/opencast/opencast/pull/3707)] -
+ Out of video image extraction should not fail
+- [[#3688](https://github.com/opencast/opencast/pull/3688)] -
+ Add release notes and changelog for OC 11.6
+- [[#3682](https://github.com/opencast/opencast/pull/3682)] -
+ Make creation of default External API group configurable
+- [[#3680](https://github.com/opencast/opencast/pull/3680)] -
+ Acl null-checks for `/api/series/{seriesId}/acl` endpoint
+- [[#3679](https://github.com/opencast/opencast/pull/3679)] -
+ Don't store invalid ACLs submitted to api-endpoint
+- [[#3661](https://github.com/opencast/opencast/pull/3661)] -
+ Check if user can be loaded before starting the workflow
+- [[#3635](https://github.com/opencast/opencast/pull/3635)] -
+ Fix bug with adding a series when a deleted one still lingers
+
+### Opencast 11.6
+
+*Released on April 20th, 2022*
+
+- [[#3638](https://github.com/opencast/opencast/pull/3638)] -
+ Fix add punctuation and models support to google transcription
+- [[#3633](https://github.com/opencast/opencast/pull/3633)] -
+ allow admin user for node to node communication #3556
+- [[#3631](https://github.com/opencast/opencast/pull/3631)] -
+ Error handling in Vosk module
+- [[#3630](https://github.com/opencast/opencast/pull/3630)] -
+ Fix Vosk Concurrency Problem
+- [[#3605](https://github.com/opencast/opencast/pull/3605)] -
+ fix #3602, Terminate state service, check that host is not in maintenance
+- [[#3586](https://github.com/opencast/opencast/pull/3586)] -
+ Auto-generated series for Capture Agents
+- [[#3567](https://github.com/opencast/opencast/pull/3567)] -
+ Fix workflow definition installation
+- [[#3555](https://github.com/opencast/opencast/pull/3555)] -
+ Rework the userdirectory-brightspace module
+- [[#3550](https://github.com/opencast/opencast/pull/3550)] -
+ Add release notes and changelog for OC 11.5
+- [[#3330](https://github.com/opencast/opencast/pull/3330)] -
+ Removed ManagedService from MediaInspectionService
+
+### Opencast 11.5
+
+*Released on March 23rd, 2022*
+
+- [[#3544](https://github.com/opencast/opencast/pull/3544)] -
+ Fix bug: Editor sometimes doesn't skip deactivated sections on Safari Browser
+- [[#3547](https://github.com/opencast/opencast/pull/3547)] -
+ Redowngrade Paella to 6.4.4
+- [[#3546](https://github.com/opencast/opencast/pull/3546)] -
+ Update Editor to 2022-03-22
+- [[#3545](https://github.com/opencast/opencast/pull/3545)] -
+ Update 11.x translations, restore zh_TW translations
+- [[#3541](https://github.com/opencast/opencast/pull/3541)] -
+ Downgrade commons-io
+- [[#3540](https://github.com/opencast/opencast/pull/3540)] -
+ Fix NPE when signing publication URLs
+- [[#3534](https://github.com/opencast/opencast/pull/3534)] -
+ Fix Admin UI builds due to missing SASS
+- [[#3532](https://github.com/opencast/opencast/pull/3532)] -
+ Fix wrong name of admin UI configuration file
+- [[#3520](https://github.com/opencast/opencast/pull/3520)] -
+ Docs: Force same sample rate for audio files in PartialImport WOH encoding
+- [[#3474](https://github.com/opencast/opencast/pull/3474)] -
+ Fix OC 11.4 release notes layout issues
+- [[#3466](https://github.com/opencast/opencast/pull/3466)] -
+ Check if encoding profile exist for imageToVideo Operation
+- [[#3460](https://github.com/opencast/opencast/pull/3460)] -
+ fix admin-ui endpoint crash, when a series without title exists
+- [[#3459](https://github.com/opencast/opencast/pull/3459)] -
+ Add release notes and changelog for OC 11.4
+- [[#3343](https://github.com/opencast/opencast/pull/3343)] -
+ Password strength indicator
+- [[#3197](https://github.com/opencast/opencast/pull/3197)] -
+ Elasticsearch Retry Config
+
+### Opencast 11.4
+
+*Released on February 16th, 2022*
+
+- [[#3457](https://github.com/opencast/opencast/pull/3457)] -
+ Update Opencast Studio to 2022-02-16
+- [[#3444](https://github.com/opencast/opencast/pull/3444)] -
+ Fix frontend-no-prebuilt profile
+- [[#3437](https://github.com/opencast/opencast/pull/3437)] -
+ Fix merge conflict
+- [[#3432](https://github.com/opencast/opencast/pull/3432)] -
+ Fix `pom.xml` Version
+- [[#3423](https://github.com/opencast/opencast/pull/3423)] -
+ Fixes OSGi error when shutting down Opencast
+- [[#3416](https://github.com/opencast/opencast/pull/3416)] -
+ Fixed Typo in Logging Statement
+- [[#3384](https://github.com/opencast/opencast/pull/3384)] -
+ Add DublinCore Catalog to Scheduler JSON
+- [[#3369](https://github.com/opencast/opencast/pull/3369)] -
+ Update slf4j
+- [[#3368](https://github.com/opencast/opencast/pull/3368)] -
+ Capture agent calendar as JSON
+- [[#3367](https://github.com/opencast/opencast/pull/3367)] -
+ Add release notes and changelog for OC 11.3
+- [[#3365](https://github.com/opencast/opencast/pull/3365)] -
+ Remove `mvn site` Test
+- [[#3344](https://github.com/opencast/opencast/pull/3344)] -
+ merge the ldap userdirectory behaviour from 9.x into the current module
+- [[#3342](https://github.com/opencast/opencast/pull/3342)] -
+ Allow metadata editting
+- [[#3340](https://github.com/opencast/opencast/pull/3340)] -
+ Match Inbox Events Against Schedule
+- [[#3327](https://github.com/opencast/opencast/pull/3327)] -
+ Extend Metadata Extraction in Inbox
+- [[#3203](https://github.com/opencast/opencast/pull/3203)] -
+ start-workflow-wfh allows to pass mediapackage id from previous WFH
+- [[#3155](https://github.com/opencast/opencast/pull/3155)] -
+ Allow the use of organization properties in workflows
+
+
### Opencast 11.3
*Released on January 19th, 2022*
@@ -70,6 +1339,12 @@ Opencast 11
*Released on December 15th, 2021*
+- [[#2949](https://github.com/opencast/opencast/pull/2949)] -
+ Encode username before useing it in CanvasUserRoleProvider
+- [[#2591](https://github.com/opencast/opencast/pull/2591)] -
+ Remove automatic handling of HLS bitrate ladder
+- [[#2559](https://github.com/opencast/opencast/pull/2559)] -
+ Allow proper mapping of tenant hostnames to URLs
- [[#3263](https://github.com/opencast/opencast/pull/3263)] -
Remove chinese traditional
- [[#3264](https://github.com/opencast/opencast/pull/3264)] -
@@ -694,10 +1969,97 @@ Opencast 11
Opencast 10
----------
+### Opencast 10.14
+
+*Released on June 14th, 2022*
+
+- [[#3634](https://github.com/opencast/opencast/pull/3634)] -
+ Update adopter registration code
+- [[#3781](https://github.com/opencast/opencast/pull/3781)] -
+ Add Placeholders for Video Resolution to Rename-Files
+
+
+### Opencast 10.13
+
+*Released on May 11th, 2022*
+
+- [[#3684](https://github.com/opencast/opencast/pull/3684)] -
+ Backport matrix room title fixes into 10.x
+- [[#3674](https://github.com/opencast/opencast/pull/3674)] -
+ Avoid rewriteUrls being invoked twice while loading mediapackage.
+- [[#3666](https://github.com/opencast/opencast/pull/3666)] -
+ Update Paella 6.5.6 config.json
+
+
+### Opencast 10.12
+
+*Released on Apr 19th, 2022*
+
+- [[#3660](https://github.com/opencast/opencast/pull/3660)] -
+ Update Editor to 2022-03-22 and OC Studio to 2022-02-16 for OC 10.x
+- [[#3650](https://github.com/opencast/opencast/pull/3650)] -
+ Fixes admin-ui repeated series name display #3600
+- [[#3626](https://github.com/opencast/opencast/pull/3626)] -
+ Update paella player to paella 6.5.6
+
+
+### Opencast 10.11
+
+*Released on Mar 22nd, 2022*
+
+- [[#3533](https://github.com/opencast/opencast/pull/3533)] -
+ Add activemq upgrade note to 10.x upgrade guide
+- [[#3531](https://github.com/opencast/opencast/pull/3531)] -
+ Revert "Update paella player to paella 6.5.5 (#3142)" since HLS videos do not load on slow connections
+- [[#3517](https://github.com/opencast/opencast/pull/3517)] -
+ Admin-ui-frontend migrate node-sass to sass
+- [[#3512](https://github.com/opencast/opencast/pull/3512)] -
+ Improve Tooltips in Documentation
+- [[#3490](https://github.com/opencast/opencast/pull/3490)] -
+ Document that you cannot run Opencast in a sub-path
+- [[#3467](https://github.com/opencast/opencast/pull/3467)] -
+ Opencast 10.10 release notes and changelog
+
+
+### Opencast 10.10
+
+*Released on Feb 17th, 2022*
+
+- [[#3427](https://github.com/opencast/opencast/pull/3427)] -
+ Fix Typo in Opencast 10 Upgrade Guide
+- [[#3415](https://github.com/opencast/opencast/pull/3415)] -
+ Update pax logging from version 1.11.13 to 1.11.14
+- [[#3414](https://github.com/opencast/opencast/pull/3414)] -
+ Revert "update karaf from version 4.2.9 to 4.2.15"
+- [[#3390](https://github.com/opencast/opencast/pull/3390)] -
+ Endpoint to Remove Tracked Host Bundles
+- [[#3389](https://github.com/opencast/opencast/pull/3389)] -
+ Rename Files Workflow Operation Handler
+- [[#3386](https://github.com/opencast/opencast/pull/3386)] -
+ update karaf from version 4.2.9 to 4.2.15
+- [[#3373](https://github.com/opencast/opencast/pull/3373)] -
+ Adding Camtasia .trec support.
+- [[#3372](https://github.com/opencast/opencast/pull/3372)] -
+ Fix port checking
+- [[#3364](https://github.com/opencast/opencast/pull/3364)] -
+ Automatically Update Matrix Room
+- [[#3363](https://github.com/opencast/opencast/pull/3363)] -
+ Automated Release Title
+- [[#3362](https://github.com/opencast/opencast/pull/3362)] -
+ ConfigurableRetractWorkflowOperationHandle: fixed exception message
+- [[#3361](https://github.com/opencast/opencast/pull/3361)] -
+ Fix metadata for multitenancy
+- [[#3359](https://github.com/opencast/opencast/pull/3359)] -
+ Document Capture Agent Input Selection
+- [[#3345](https://github.com/opencast/opencast/pull/3345)] -
+ Fix Javadocs
+- [[#2811](https://github.com/opencast/opencast/pull/2811)] -
+ Add download artifacts in engage publication
+
### Opencast 10.9
-*Released on January 18th, 2021*
+*Released on January 18th, 2022*
- [[#3341](https://github.com/opencast/opencast/pull/3341)] -
Update Nexus related documentation
diff --git a/docs/guides/admin/docs/configuration/admin-ui/asset-upload.md b/docs/guides/admin/docs/configuration/admin-ui/asset-upload.md
index 9ee362aaa2..15c16c8c17 100644
--- a/docs/guides/admin/docs/configuration/admin-ui/asset-upload.md
+++ b/docs/guides/admin/docs/configuration/admin-ui/asset-upload.md
@@ -74,12 +74,10 @@ How to Enable Preconfigured Asset Options
Catalogs and attachments can be added to new and existing events. New source tracks can only be defined for the upload of new events. Some
predefined catalog and attachment examples are commented out in the properties file. You can uncomment any of these
-to make them upload options in the Admin UI. The default workflow `publish-uploaded-assets` will automatically distribute,
+to make them upload options in the Admin UI. The sample workflow `publish-uploaded-assets` will automatically distribute,
publish, and archive uploaded assets on existing events.
# Asset upload options are for new and existing events.
- # Only one file can be uploaded for each of these options, the uploaded file replaces existing elements of the same
- # type and flavor in the mediapackage.
# EVENTS.EVENTS.NEW.UPLOAD_ASSET.OPTION.CAPTIONS_DFXP={"id":"catalog_captions_dfxp", "type": "catalog",
# "flavorType": "captions", "flavorSubType": "timedtext", "displayOrder": 2}
# EVENTS.EVENTS.NEW.UPLOAD_ASSET.OPTION.CAPTIONS_WEBVTT={"id":"attachment_captions_webvtt",
@@ -93,7 +91,6 @@ publish, and archive uploaded assets on existing events.
EVENTS.EVENTS.NEW.UPLOAD_ASSET.WORKFLOWDEFID=publish-uploaded-assets
# The video source track upload options are only for new events.
- # Unlike the other assets, multiple source tracks can be uploaded for a single flavor.
# The MULTIPLE_PARTS example shows how to enable choosing multiple source files for a single flavor. In this case,
# a fictional "multipart/part+source".
# EVENTS.EVENTS.NEW.SOURCE.UPLOAD.MULTIPLE_PARTS={"id": "track_parts","type":"track",
@@ -105,6 +102,59 @@ publish, and archive uploaded assets on existing events.
EVENTS.EVENTS.NEW.SOURCE.UPLOAD.SEGMENTABLE={"id": "track_presentation","type":"track",
"flavorType":"presentation", "flavorSubType": "source", "multiple":false, "displayOrder": 13}
+Sample `publish-uploaded-assets` workflow:
+
+```xml
+
+
+ publish-uploaded-assets
+ Publish uploaded assets
+
+ Publish uploaded assets
+
+
+
+
+
+
+
+
+ ${download-source-flavors},dublincore/*,security/*
+ engage-download
+ engage-streaming
+ merge
+ false
+
+
+
+
+
+
+
+ */*
+
+
+
+
+
+
+
+ true
+ security/*
+
+
+
+
+```
+
How to Upload Assets in the Admin UI
------------------------------------
@@ -119,24 +169,23 @@ The manually uploaded assets appear in the Create event summary
To Upload an asset to an existing event, go into the existing event details Assets tab, and click "Add Asset >" link

-The option selection is the same as for Create event, except the "Add Asset" button automatically executes the workflow
+The option selection is the same as when creating an event, except the "Add Asset" button automatically executes the workflow
defined by `EVENTS.EVENTS.NEW.UPLOAD_ASSET.WORKFLOWDEFID`

How to Create a New Asset Option
--------------------------------
-The following steps will assist you in creating a new asset upload option. As mentioned before, only catalog and
-attachments can be added to existing events. New source types can be added to new events.
+The following steps will assist you in creating a new asset upload option. New source types can be added to new events.
Tasks:
- Modify `etc/listproviders/event.upload.asset.options.properties`
- For the title of the options displayed in the admin interface, either:
- add a translation for the new asset name to
- `modules/admin-ui/src/main/resources/public/org/opencastproject/adminui/languages/...`
+ `modules/admin-ui-frontend/resources/public/org/opencastproject/adminui/languages/...`
- or add a `title` field to the upload specification
-- Modify your workflow from `etc/workflows/...`
+- Add a workflow to publish the uploaded assets to `etc/workflows`
- Test your changes
The following steps describe how to change the properties configuration.
@@ -186,7 +235,7 @@ accept | 'video/*,.png' | A list of accepted file formats as taken by the HTML \
The parameter key is internationalized as the display text in the admin UI
-ref: modules/admin-ui/src/main/resources/public/org/opencastproject/adminui/languages/
+ref: modules/admin-ui-frontend/resources/public/org/opencastproject/adminui/languages/
### Step 3. Add translation for the new option
@@ -196,11 +245,11 @@ Add a translation for the option property when adding new option, otherwise the
The translation language files are located:
- modules/admin-ui/src/main/resources/public/org/opencastproject/adminui/languages/...
+ modules/admin-ui-frontend/resources/public/org/opencastproject/adminui/languages/...
Example of US English translation for `EVENTS.EVENTS.NEW.UPLOAD_ASSET.OPTION.CAPTIONS_WEBVTT`:
- modules/admin-ui/src/main/resources/public/org/opencastproject/adminui/languages/lang-en_US.json
+ modules/admin-ui-frontend/resources/public/org/opencastproject/adminui/languages/lang-en_US.json
```json
diff --git a/docs/guides/admin/docs/configuration/admin-ui/statistics.md b/docs/guides/admin/docs/configuration/admin-ui/statistics.md
index f912eb9d1f..c531dca1fc 100644
--- a/docs/guides/admin/docs/configuration/admin-ui/statistics.md
+++ b/docs/guides/admin/docs/configuration/admin-ui/statistics.md
@@ -25,24 +25,9 @@ A complete setup consists of the following components:
For example, using Opencast's [_opencast-influxdb-adapter_](https://github.com/opencast/opencast-influxdb-adapter), your
architecture would look like this:
-```graphviz dot statistics-architecture.png
-
-/**
-Webserver Logs --> opencast-influxdb-adapter --> InfluxDB --> Opencast
-**/
-
-digraph G {
- rankdir="LR";
- bgcolor="transparent";
- node[fontsize=8.0, fontname="sans"];
-
- webserver -> adapter -> influxdb -> opencast;
-
- webserver[label="Webserver Logs"];
- adapter[label="influxdb-adapter"];
- influxdb[label="InfluxDB"];
- opencast[label="Opencast"];
-}
+```mermaid
+graph LR
+ Webserver[Webserver Logs] --> Adapter --> InfluxDB --> Opencast;
```
Precisely, the Opencast bundle `opencast-statistics-provider-influx` is the one that needs to be able to connect to
diff --git a/docs/guides/admin/docs/configuration/basic.md b/docs/guides/admin/docs/configuration/basic.md
index 983c8f4218..28a12c12ba 100644
--- a/docs/guides/admin/docs/configuration/basic.md
+++ b/docs/guides/admin/docs/configuration/basic.md
@@ -18,6 +18,10 @@ The value must be set to the URL from which the server can be accessed later.
org.opencastproject.server.url=https://example.opencast.org
+It is not supported for Opencast to be hosted in a subpath.
+Opencast needs to be served from the root path element.
+The RFC 3986 URI path component needs to be empty.
+
*Note:* This value will be written to all generated media packages and thus cannot be changed easily for already
processed media. Please think about this setting carefully.
@@ -44,16 +48,7 @@ For this, the important keys in the `etc/custom.properties` configuration file a
Make sure that these settings are identical on all nodes of the cluster.
-Step 3: Setting up Apache ActiveMQ Message Broker
--------------------------------------------------
-
-Opencast requires Apache ActiveMQ to relay messages between micro-services.
-For configuration details, please follow the:
-
-- [Apache ActiveMQ configuration guide](message-broker.md)
-
-
-Step 4: Database Configuration
+Step 3: Database Configuration
------------------------------
Opencast uses an integrated H2 database by default, which has certain drawbacks:
@@ -67,14 +62,14 @@ Details about the configuration can be found at:
- [Database Configuration](database.md)
-Step 5: Setting up Elasticsearch
+Step 4: Setting up Elasticsearch
--------------------------------
Opencast requires Elasticsearch. Instructions for installing Elasticsearch can be found in the
[installation documentation](../installation/index.md).
-Step 6: HTTPS Configuration
+Step 5: HTTPS Configuration
---------------------------
This configuration is required in order to:
@@ -87,7 +82,7 @@ For this, follow one of the
- [configuration guides for HTTPS](https/index.md).
-Step 7: Setting the Storage Directory (optional)
+Step 6: Setting the Storage Directory (optional)
------------------------------------------------
If you want to use a specific location for storing media, metadata and other data,
diff --git a/docs/guides/admin/docs/configuration/database.md b/docs/guides/admin/docs/configuration/database.md
index beef2c3e67..4d3a7152e9 100644
--- a/docs/guides/admin/docs/configuration/database.md
+++ b/docs/guides/admin/docs/configuration/database.md
@@ -1,11 +1,17 @@
Database Configuration
======================
-Opencast ships with embedded JDBC drivers for the H2, MySQL, MariaDB and PostgreSQL databases.
+Opencast ships with embedded H2, MariaDB and PostgreSQL JDBC drivers.
The built-in H2 database is used by default and needs no configuration,
but is not suited for production.
-> __H2__ is not supported for updates or distributed systems. Use it for testing only!
+The MariaDB driver also supports connecting to MySQL.
+But this may need additional setting and it not part of Opencast's documentation.
+We also do not test this, and hence do not guarantee that this will work.
+
+
+ __H2__ is not supported for updates or distributed systems. Use it for testing only!
+
### Requirements
@@ -21,13 +27,12 @@ Step 1: Select a Database
The EclipseLink JPA implementation which is used in Opencast supports several different databases, although
some databases might require additional drivers.
-Official support only exists for MariaDB, MySQL, PostgreSQL and H2.
+Official support only exists for MariaDB, PostgreSQL and H2.
Other database engines are not tested and specific issues will likely not be addressed.
- __MariaDB__ is the recommended database engine.
It is used by most adopters and is well tested.
-- __MySQL__ is supported but tested less than MariaDB.
-- __PostgreSQL__ support is experimental.
+- __PostgreSQL__ is fully supported and a production ready alternative.
- __H2__ is not suitable for anything but testing and development.
It cannot be used in distributed environments.
@@ -105,8 +110,6 @@ Finally, leave the client and restart the database server to enable the new user
### PostgreSQL
-Opencast's official PostgreSQL support is still marked as experimental.
-
Install PostgreSQL, create a database and a user.
You may need to enable password authentication in your `pg_hba.conf` first.
Please refer to the PostgreSQL documentation for more details.
@@ -123,20 +126,20 @@ Step 4: Configure Opencast
--------------------------
The following changes must be made in `etc/custom.properties`.
-Examples are provided for MariaDB/MySQL and PostgreSQL.
+Examples are provided for MariaDB and PostgreSQL.
1. Configure Opencast to use the JDBC driver for MariaDB or PostgreSQL.
The MariaDB driver will also work for MySQL.
- # MariaDB/MySQL
+ # MariaDB
org.opencastproject.db.jdbc.driver=org.mariadb.jdbc.Driver
# PostgreSQL
org.opencastproject.db.jdbc.driver=org.postgresql.Driver
2. Configure the host where Opencast will find the database (`127.0.0.1`) and the database name (`opencast`).
- # MariaDB/MySQL
- org.opencastproject.db.jdbc.url=jdbc:mysql://127.0.0.1/opencast?useMysqlMetadata=true
+ # MariaDB
+ org.opencastproject.db.jdbc.url=jdbc:mariadb://127.0.0.1/opencast?useMysqlMetadata=true
# PostgreSQL
org.opencastproject.db.jdbc.url=jdbc:postgresql://127.0.0.1/opencast
@@ -156,7 +159,7 @@ Trying to generate the schema automatically will most likely fail.
If you want to use OAI-PMH, you must create the necessary table manually.
-Use the following code to generate the OAI-PMH database table on MariaDB/MySQL.
+Use the following code to generate the OAI-PMH database table on MariaDB.
PostgreSQL is not yet supported.
```sql
diff --git a/docs/guides/admin/docs/configuration/elasticsearch.md b/docs/guides/admin/docs/configuration/elasticsearch.md
index 035c575a16..05eebabb58 100644
--- a/docs/guides/admin/docs/configuration/elasticsearch.md
+++ b/docs/guides/admin/docs/configuration/elasticsearch.md
@@ -27,13 +27,21 @@ Additionally, the following settings can be configured in
`org.opencastproject.elasticsearch.index.ElasticsearchIndex.cfg`:
* `index.indentifier`
* `index.name`
+* `max.retry.attempts.get`
+* `max.retry.attempts.update`
+* `retry.waiting.period.get`
+* `retry.waiting.period.update`
The identifier defines which index opencast is looking for. This might be interesting if you run an
Elasticsearch cluster and want to follow a naming scheme. But you should be aware that the index actually consists of
multiple subindices whose identifiers will be appended to the base name with an _ (e.g. "opencast_event").
-If an index doesn't exist, Opencast will create it.
+If an index doesn't exist, Opencast will create it. The name is used for logging purposes only.
-The name is used for logging purposes only.
+The max retry attempts and the waiting periods will be used in case of an ElasticsearchStatusException, e.g. if there
+are too many concurrent requests. The retry behavior can be configured differently for get and update/delete requests.
+This way you could set more retry attempts for index updates because of the more serious consequences if those requests
+fail. The waiting period is used to not overwhelm the Elasticsearch with retry requests, making the problem worse. By
+default, no retry will be attempted.
Version
-------
diff --git a/docs/guides/admin/docs/configuration/encoding.md b/docs/guides/admin/docs/configuration/encoding.md
index 35ee1eb7f0..ac4635fcd6 100644
--- a/docs/guides/admin/docs/configuration/encoding.md
+++ b/docs/guides/admin/docs/configuration/encoding.md
@@ -107,7 +107,7 @@ Once defined, use your encoding profile in your workflow by setting the encoding
presenter/deliveryrss, atom, captioningmy-av-profile.http
-
+
Have a look at the [Workflow Configuration section](workflow.md) for more details about workflows and workflow
diff --git a/docs/guides/admin/docs/configuration/firewall.md b/docs/guides/admin/docs/configuration/firewall.md
index f381a6f02b..231fbe062e 100644
--- a/docs/guides/admin/docs/configuration/firewall.md
+++ b/docs/guides/admin/docs/configuration/firewall.md
@@ -12,48 +12,36 @@ General rules are:
- Users communicate with Opencast via HTTP(S)
- Capture agents communicate with Opencast via HTTP(S)
- Opencast nodes communicate among each other via HTTP(S)
-- Often Elasticsearch and ActiveMQ are run on the admin node since this node communicates with these services
- exclusively
+- Often Elasticsearch runs on the admin node since this node communicates with these services exclusively
- All servers should get access to the storage infrastructure
- All Opencast nodes need database access
A visual representation of the communication within a three-node cluster will look like this:
-```graphviz dot network.png
-digraph G {
- user[label = "User"];
- activemq[label = "ActiveMQ"];
- oc1[label = "Opencast Admin"];
- oc2[label = "Opencast Worker"];
- oc3[label = "Opencast Presentation"];
- db[label = "Database"];
- es[label = "Elasticsearch"];
- storage[label = "Storage"];
- ca[label = "Capture Agent"];
-
- user -> oc1 [label = "80, 443"];
- user -> oc2 [style = "dashed", label = "80¹, 443¹"];
- user -> oc3 [label = "80, 443"];
- oc1 -> oc2 [dir = "both", label = "80, 443"];
- oc2 -> oc3 [dir = "both", label = "80, 443"];
- oc3 -> oc1 [dir = "both", label = "80, 443"];
- oc1 -> db [label = "3306²"];
- oc2 -> db [label = "3306²"];
- oc3 -> db [label = "3306²"];
- oc1 -> activemq [label = "61616"];
- oc1 -> es[label = "9300"];
- oc1 -> storage;
- oc2 -> storage;
- oc3 -> storage;
- ca -> oc1[label = "80, 443"];
-}
+```mermaid
+graph LR
+
+ user(User) -->|80, 443| oc1(Opencast Admin)
+ user -.->|80, 443| oc2(Opencast Worker)
+ user -->|80, 443| oc3(Opencast Presentation)
+ oc1 <-->|80, 443| oc2
+ oc2 <-->|80, 443| oc3
+ oc3 <-->|80, 443| oc1
+ oc1 -->|e.g. 3306| db(Database)
+ oc2 -->|e.g. 3306| db
+ oc3 -->|e.g. 3306| db
+ oc1 -->|9200| es(Elasticsearch)
+ oc1 --> storage(Storage)
+ oc2 --> storage
+ oc3 --> storage
+ ca(Capture Agent) -->|80, 443| oc1
```
Notes:
-- _The numbers in the diagram describe TCP ports_
-- _¹) Communication between users and workers is often not necessary_
-- _²) If you use a database other than MariaDB, the port may differ_
+- The numbers in the diagram describe TCP ports
+- Communication between users and workers is often not necessary
+- If you use a database other than MariaDB, the port may differ
Suggested Firewall Configurations
diff --git a/docs/guides/admin/docs/configuration/index.md b/docs/guides/admin/docs/configuration/index.md
index 6849208fc4..5f0285ecca 100644
--- a/docs/guides/admin/docs/configuration/index.md
+++ b/docs/guides/admin/docs/configuration/index.md
@@ -17,7 +17,6 @@ General Configuration
- [Load Configuration](load.md)
- [Log Configuration](log.md)
- [User Statistics and Privacy Configuration](user-statistics.and.privacy.md)
-- [Message Broker Configuration](message-broker.md)
- [Metadata Configuration](metadata.md)
- [Multi Tenancy Configuration](multi.tenancy.md)
- [Trim Segments Configuration](trim-segments.md)
diff --git a/docs/guides/admin/docs/configuration/message-broker.md b/docs/guides/admin/docs/configuration/message-broker.md
deleted file mode 100644
index 46db43da1f..0000000000
--- a/docs/guides/admin/docs/configuration/message-broker.md
+++ /dev/null
@@ -1,182 +0,0 @@
-Message Broker Configuration
-============================
-
-Since version 2, Opencast requires an Apache ActiveMQ message broker as message relay for the administrative user
-interface. ActiveMQ can either be set up to run on its own machine or on one of the existing Opencast nodes (usually the
-admin node).
-
-### Required Version
-
-* ActiveMQ 5.10 or above
-
-
-Installation
-------------
-
-There are multiple options for installing ActiveMQ:
-
-* If you used the Opencast package repository, simply install the `activemq-dist` package.
-* If you are running RHEL, CentOS or Fedora you can use the [ActiveMQ-dist Copr RPM
- repository](https://copr.fedoraproject.org/coprs/lkiesow/apache-activemq-dist/)
-* Newer Debian based operating systems contain a sufficiently new version, however the ActiveMQ configuration file will
- require modification to function correctly.
-* You can download binary distributions from the [Apache ActiveMQ website](http://activemq.apache.org/download.html)
-
-
-Configuration
--------------
-
-What you need to do:
-
-1. Set up the required message queues for Opencast
-2. Point all your Opencast nodes to your message broker.
-3. Configure authentication and access control
-
-The first task is easy. Opencast comes with an ActiveMQ configuration file, located at
-`docs/scripts/activemq/activemq.xml` (RPM repo: `/usr/share/opencast/docs/scripts/activemq/activemq.xml`). This file
-will give you a basic configuration with all queues set-up and accepting connections from the local host over TCP port
-`61616`.
-
-
-Replacing the default ActiveMQ configuration with this file will already give you a fully functional ActiveMQ set-up for
-an all-in-one server. You will find the configuration in the usual locations, e.g. `/etc/activemq/`. On Debian you
-first need to activate or create a new ActiveMQ instance. For more details on that see
-`/usr/share/doc/activemq/README.Debian`.
-
-Note that the default configuration needs to be adjusted for distributed set-ups since:
-
-* ActiveMQ listens to localhost only (`activemq.xml`)
-* Opencast tries to connect to ActiveMQ locally (`custom.properties`)
-* No password is set (`activemq.xml`, `custom.properties`)
-
-
-### 1. Connection
-
-The ActiveMQ connection is configured in Opencast's `custom.properties` file. The default configuration points to a local
-installation of ActiveMQ. You can easily configure this to point somewhere else:
-
- activemq.broker.url = failover://tcp://example.opencast.org:61616
-
-
-### 2. Bind Host
-
-The default configuration tells ActiveMQ to listen to `127.0.0.1` only. On a distributed system, you want to set this to
-`0.0.0.0` to listen to all hosts by changing the `transportConnector`:
-
-
-
-
-### 3. Username and Password
-
-ActiveMQ can secure its message queues by requiring login credentials. This section will go through the steps of setting
-up a username and a password. Have a look at the [ActiveMQ security site](http://activemq.apache.org/security.html) for
-details about using alternative authentication and authorization providers.
-
-#### Step 1: Create ActiveMQ Admin User
-
-First, you need to create a new user that will have access to the queues. This is configured in the `users.properties`
-configuration file in the configuration directory for ActiveMQ. It is a list of the format `username = password` so, for
-example, we could create a new admin user with the following file contents:
-
- admin=password
-
-#### Step 2: Create ActiveMQ Admin Group
-
-The next step is to provide a group that will have our user in it and will secure access to the message queues. This is
-configured in the file `groups.properties` in the configuration directory for ActiveMQ. It is a list of the format
-`group = user1,user2,…`. For example:
-
- groups=user1,user2,user3
-
-To set-up our new user to be a part of the admins group:
-
- admins=admin
-
-#### Step 3: Configure Users and Groups Configuration Files
-
-Next, we need to make sure that ActiveMQ is using our `users.properties` and `groups.properties` files to authenticate
-and authorize users. The `login.config` file should be in the ActiveMQ configuration directory and contain:
-
- activemq {
- org.apache.activemq.jaas.PropertiesLoginModule required
- org.apache.activemq.jaas.properties.user="users.properties"
- org.apache.activemq.jaas.properties.group="groups.properties";
- };
-
-#### Step 4: Configure Message Broker Security
-
-The final step to secure the ActiveMQ queues is to limit access to a specific group. This can be done by editing
-`activemq.xml` in the ActiveMQ configuration directory. In this file, we need to add some XML in between these tags:
-
-
-
-We will add the following plugin configuration:
-
-
-
-
-
-
-
-
-* The `jaasAuthenticationPlugin` configures the broker to use our `login.config` file for the authentication.
-
-
-
-* The property:
-
- configuration=activemq
-
- needs to match the name given for surrounding object in `login.config` i.e. activemq{};
-
-* The `authorizationEntry` restricts read, write and admin access for queues and topics to members of the group admins.
-
-#### Step 5: Configure Opencast to Connect with Username and Password to Message Broker
-
-Now that we have secured the queues, Opencast will complain that it is unable to connect, using the current username and
-password. The username and password used above need to be added to the `custom.properties` file of Opencast. There are
-two properties to set:
-
- activemq.broker.username=admin
- activemq.broker.password=password
-
-
-Firewall
---------
-
-Do not forget that ActiveMQ uses the TCP port 61616 (default configuration) for communication. You probably want to
-allow communication over this port in your firewall on a distributed setup or explicitly forbid public access on an
-all-in-one installation.
-
-
-Memory settings
----------------
-
-When ActiveMQ is under heavy load it may require additional RAM. There are two places to change this:
-
-In `docs/scripts/activemq/activemq.xml`:
-
- ...
-
-
-
-
-
- ...
-
-This controls the allowed memory of ActiveMQ inside of its JVM instance. For more information see [the ActiveMQ
-documentation](http://activemq.apache.org/javalangoutofmemory.html)
-
-In `/usr/share/activemq/bin/env`:
-
- ACTIVEMQ_OPTS_MEMORY="-Xms64M -Xmx4G"
-
-These are the classic JVM minimum and maximum memory flags.
diff --git a/docs/guides/admin/docs/configuration/metadata.md b/docs/guides/admin/docs/configuration/metadata.md
index 56f6b869c5..a4f40e7ad9 100644
--- a/docs/guides/admin/docs/configuration/metadata.md
+++ b/docs/guides/admin/docs/configuration/metadata.md
@@ -50,12 +50,12 @@ The metadata configuration file format can be logically split up into different
### Part 1: General catalog information
-|Configuration key|Example |Description |
-|-----------------|-------------------------|--------------------------------------------------------------------------|
-|type |events |Two different types of catalog UI adapters may be configured, such for events and others for series.|
-|organization |mh_default_org |A custom catalog definition is mapped 1:1 to an organization and is available to this one organization only.|
-|flavor |mycompany/episode |The catalog must be of a certain flavor. For a events catalog, the flavor consists of the form type/subtype whereas for series you only need to define the subtype. Attention: For series catalogs, the type (the part before the slash '/') is used as element type.|
-|title |My Personal Catalog Name |This is the title that is displayed in the UI. It should be something that is readable by humans.|
+|Configuration key|Example | Description |
+|-----------------|-------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+|type |events | Two different types of catalog UI adapters may be configured, such for events and others for series. |
+|organization |mh_default_org | A custom catalog definition is mapped to an organization (1:1) or all organizations (1:n). To map a catalog to all organizations, use a wildcard as the organization name (`organization=*`). Else, the catalog is only available to the specified organization. |
+|flavor |mycompany/episode | The catalog must be of a certain flavor. For a events catalog, the flavor consists of the form type/subtype whereas for series you only need to define the subtype. Attention: For series catalogs, the type (the part before the slash '/') is used as element type. |
+|title |My Personal Catalog Name | This is the title that is displayed in the UI. It should be something that is readable by humans. |
### Part 2: XML serialization information
diff --git a/docs/guides/admin/docs/configuration/multi.tenancy.md b/docs/guides/admin/docs/configuration/multi.tenancy.md
index 5c85da47cd..0e0c028d46 100644
--- a/docs/guides/admin/docs/configuration/multi.tenancy.md
+++ b/docs/guides/admin/docs/configuration/multi.tenancy.md
@@ -80,6 +80,10 @@ do not support multitenancy.
Hosts can have different schemas (http / https) and port numbers, e.g. when you run behind proxy server. Note, that
the combination of hostname and port number is uniquely mapped to an organization.
+It is not supported for Opencast tenants to be hosted in a subpath.
+Opencast tenants needs to be served from the root path element.
+The RFC 3986 URI path component needs to be empty.
+
### Step 2: Security Configuration
Create a file called tenant1.xml in /etc/security. This file specifies access rules for individual URLs that specify
diff --git a/docs/guides/admin/docs/configuration/opensearch.md b/docs/guides/admin/docs/configuration/opensearch.md
new file mode 100644
index 0000000000..e195a0913a
--- /dev/null
+++ b/docs/guides/admin/docs/configuration/opensearch.md
@@ -0,0 +1,50 @@
+Opensearch Configuration
+===========================
+
+Opensearch powers the external API as well as the administrative user interface of Opencast.
+
+Configuring External Nodes
+--------------------------
+
+Opencast's Opensearch settings can be found in the `etc/custom.properties` configuration file.
+
+Relevant configuration keys are:
+
+* `org.opencastproject.elasticsearch.server.hostname`
+* `org.opencastproject.elasticsearch.server.scheme`
+* `org.opencastproject.elasticsearch.server.port`
+* `org.opencastproject.elasticsearch.username`
+* `org.opencastproject.elasticsearch.password`
+
+Therefore only `admin`, `adminpresentation`, and `allinone` need to connect to Opensearch.
+
+`username` and `password` are optional. If configured, requests to Opensearch are secured by
+HTTP basic authentication (which is unsecure without TLS encryption). Refer to [the Opensearch
+documentation](https://opensearch.org/docs/latest/security-plugin/configuration/index/)
+to properly secure Opensearch.
+
+Additionally, the following settings can be configured in
+`org.opencastproject.elasticsearch.index.ElasticsearchIndex.cfg`:
+* `index.indentifier`
+* `index.name`
+* `max.retry.attempts.get`
+* `max.retry.attempts.update`
+* `retry.waiting.period.get`
+* `retry.waiting.period.update`
+
+The identifier defines which index opencast is looking for. This might be interesting if you run an
+Opensearch cluster and want to follow a naming scheme. But you should be aware that the index actually consists of
+multiple subindices whose identifiers will be appended to the base name with an _ (e.g. "opencast_event").
+If an index doesn't exist, Opencast will create it. The name is used for logging purposes only.
+
+The max retry attempts and the waiting periods will be used in case of an ElasticsearchStatusException, e.g. if there
+are too many concurrent requests. The retry behavior can be configured differently for get and update/delete requests.
+This way you could set more retry attempts for index updates because of the more serious consequences if those requests
+fail. The waiting period is used to not overwhelm the Opensearch with retry requests, making the problem worse. By
+default, no retry will be attempted.
+
+Version
+-------
+
+Please confer to the [Linux installation guide](../installation/source-linux.md#install-dependencies)
+for version information.
diff --git a/docs/guides/admin/docs/configuration/security.cas.md b/docs/guides/admin/docs/configuration/security.cas.md
index ededb43f13..153cc9b8f6 100644
--- a/docs/guides/admin/docs/configuration/security.cas.md
+++ b/docs/guides/admin/docs/configuration/security.cas.md
@@ -58,7 +58,7 @@ Authorization
Now the system knows all the information necessary to authenticate users against CAS, but also need some authorization
information, to tell which services the user is allowed to use and which resources is allowed to see and/or modify.
-You will need to configure a [UserProvider](security.md) to look up users as identified by CAS.
+You will need to configure a [UserProvider](security.md#user-and-role-providers) to look up users as identified by CAS.
* LDAP User Provider, described in [LDAP Security and Authorization](security.ldap.md)
* [Sakai User Provider](security.user.sakai.md)
@@ -66,9 +66,8 @@ You will need to configure a [UserProvider](security.md) to look up users as ide
* [Brightspace D2L User Provider](security.user.brightspace.md)
* [Canvas LMS User Provider](security.user.canvas.md)
-Further Information
--------------------
-
-Original documentation from University of Saskatchewan:
-[University of Saskatchewan CAS and LDAP
-integration](https://opencast.jira.com/wiki/display/MH/University+of+Saskatchewan+CAS+and+LDAP+integration)
+
+Working Example
+---------------
+
+A working example of CAS with an LDAP user provider can be found [here](https://github.com/opencast/community-integrations/tree/main/CAS)
diff --git a/docs/guides/admin/docs/configuration/security.jwt.md b/docs/guides/admin/docs/configuration/security.jwt.md
index eec4e4296f..08d5dd7c9e 100644
--- a/docs/guides/admin/docs/configuration/security.jwt.md
+++ b/docs/guides/admin/docs/configuration/security.jwt.md
@@ -12,7 +12,8 @@ on the [OpenID Connect (OIDC)](https://openid.net/connect/) protocol can be conf
Prerequisites
-------------
-This guide assumes that a JWT provider is already setup and Opencast receives the JWT within an HTTP request header.
+This guide assumes that a JWT provider is already setup and Opencast receives the JWT within an HTTP request header,
+or in a request parameter (i.e. a query parameter for `GET`-requests, and a form parameter for `POST`-requests).
In order to integrate Opencast with an OIDC provider you could use the
[oauth2-proxy](https://github.com/oauth2-proxy/oauth2-proxy).
@@ -54,17 +55,15 @@ sections found in `etc/security/mh_default_org.xml`. Some of the options are con
```
-* Enable the JWT header authentication filter.
-```xml
-
-
-```
-* Add the configured `jwtHeaderFilter` to the filters list of the `authenticationFilters` bean.
+* Add the configured `jwtHeaderFilter` and/or `jwtRequestParameterFilter` to the filters list
+ of the `preAuthenticationFilters` bean.
```xml
+
+
```
-* Configure the `jwtHeaderFilter` bean.
+* Configure the `jwtHeaderFilter` and/or `jwtRequestParameterFilter` beans.
```xml
@@ -76,8 +75,16 @@ sections found in `etc/security/mh_default_org.xml`. Some of the options are con
-
-
+
+
+
+
+
+
+
+
+
+
```
* Configure the `jwtLoginHandler`. For the JWT validation, either configure the `secret` property for JWTs signed with
diff --git a/docs/guides/admin/docs/configuration/security.user.brightspace.md b/docs/guides/admin/docs/configuration/security.user.brightspace.md
index 00234a82e6..1e0c47fc76 100644
--- a/docs/guides/admin/docs/configuration/security.user.brightspace.md
+++ b/docs/guides/admin/docs/configuration/security.user.brightspace.md
@@ -1,3 +1,6 @@
+> Using this requires you to turn on an Opencast plugin.
+> Take a look [at the plugin management documentation](../modules/plugin-management.md) to find out how you can do that.
+
### What it does
The [Brightspace](https://www.d2l.com/) User Provider enriches Opencast users with a
diff --git a/docs/guides/admin/docs/configuration/security.user.canvas.md b/docs/guides/admin/docs/configuration/security.user.canvas.md
index 400544fec0..ce727796fe 100644
--- a/docs/guides/admin/docs/configuration/security.user.canvas.md
+++ b/docs/guides/admin/docs/configuration/security.user.canvas.md
@@ -1,3 +1,6 @@
+> Using this requires you to turn on an Opencast plugin.
+> Take a look [at the plugin management documentation](../modules/plugin-management.md) to find out how you can do that.
+
### What it does
The [Canvas LMS](https://www.instructure.com/canvas/) User Provider enriches Opencast users
diff --git a/docs/guides/admin/docs/configuration/security.user.moodle.md b/docs/guides/admin/docs/configuration/security.user.moodle.md
index 160ef18704..d3d429a428 100644
--- a/docs/guides/admin/docs/configuration/security.user.moodle.md
+++ b/docs/guides/admin/docs/configuration/security.user.moodle.md
@@ -1,3 +1,6 @@
+> Using this requires you to turn on an Opencast plugin.
+> Take a look [at the plugin management documentation](../modules/plugin-management.md) to find out how you can do that.
+
### What it does
The [Moodle](https://moodle.org/) User Provider enriches Opencast users with a
diff --git a/docs/guides/admin/docs/configuration/security.user.sakai.md b/docs/guides/admin/docs/configuration/security.user.sakai.md
index be13484c98..f3df2bd4e2 100644
--- a/docs/guides/admin/docs/configuration/security.user.sakai.md
+++ b/docs/guides/admin/docs/configuration/security.user.sakai.md
@@ -1,3 +1,6 @@
+> Using this requires you to turn on an Opencast plugin.
+> Take a look [at the plugin management documentation](../modules/plugin-management.md) to find out how you can do that.
+
### What it does
The [Sakai](https://www.sakaiproject.org/) User Provider enriches Opencast users
diff --git a/docs/guides/admin/docs/configuration/user-statistics.and.privacy.md b/docs/guides/admin/docs/configuration/user-statistics.and.privacy.md
index 4ed2ab62cd..ee700df33f 100644
--- a/docs/guides/admin/docs/configuration/user-statistics.and.privacy.md
+++ b/docs/guides/admin/docs/configuration/user-statistics.and.privacy.md
@@ -1,8 +1,6 @@
User Statistics and Privacy
===========================
-*There exists a newer and more complete tracking service using Matomo included [as a module](../modules/player.matomo.tracking.md).*
-
The Opencast User-Tracking service stores user actions of the Opencast players in the database. This data is used for
the footprint feature of the player and for the optional analytics component.
diff --git a/docs/guides/admin/docs/configuration/workflow.md b/docs/guides/admin/docs/configuration/workflow.md
index 85c3c50a3c..3c2f704c84 100644
--- a/docs/guides/admin/docs/configuration/workflow.md
+++ b/docs/guides/admin/docs/configuration/workflow.md
@@ -23,7 +23,7 @@ values allows workflows to dynamically adapt to a given input or user decision.
### Document
-Opencast workflows are defined in XML. The structure of a Opencast workflow looks like this:
+Opencast workflows are defined in XML, or alternatively in [YAML](workflow.md#using-yaml-files-with-workflows) . The structure of a Opencast workflow looks like this:
@@ -395,5 +395,33 @@ and be consistent to the Admin UI thumbnail configuration (see [Thumbnail Config
## Test the Workflow
-The easiest way to test a workflow is to just put it into the workflow folder where it will be picked up by Opencast
+The easiest way to test a workflow is to just put it into the workflows folder where it will be picked up by Opencast
automatically and will be available in Opencast a few seconds later.
+
+## Using YAML Files with Workflows
+
+As an alternative to XML workflow configuration files, it is possible to use YAML files with the following structure.
+
+### YAML Workflow Definition Structure
+
+ ---
+ id:
+ title:
+ tags: []
+ displayOrder:
+ description:
+ operations: []
+ state-mappings:
+ - state:
+ value:
+
+### YAML Operation Structure
+
+ - id:
+ if:
+ fail-on-error:
+ exception-handler-workflow:
+ description:
+ configurations:
+ - key1: value1
+ - key2: value2
diff --git a/docs/guides/admin/docs/css/extra.css b/docs/guides/admin/docs/css/extra.css
index 023817dca1..5784bfc2a2 100644
--- a/docs/guides/admin/docs/css/extra.css
+++ b/docs/guides/admin/docs/css/extra.css
@@ -178,3 +178,14 @@ div.warn {
padding: 15px;
margin-bottom: 10px;
}
+
+.tippy-box[data-theme~='opencast'] {
+ background-color: #24425c;
+ color: white;
+ line-height: normal;
+ font-size: 12px;
+ font-family: 'Open Sans';
+}
+.tippy-box[data-theme~='opencast'][data-placement^='top'] > .tippy-arrow::before {
+ color: #24425c;
+}
diff --git a/docs/guides/admin/docs/index.md b/docs/guides/admin/docs/index.md
index 3582cd1f0f..a451848d79 100644
--- a/docs/guides/admin/docs/index.md
+++ b/docs/guides/admin/docs/index.md
@@ -21,6 +21,7 @@ The Opencast Release Documentation is the official Opencast documentation for ea
* [Release Notes](releasenotes.md)
* [Upgrade](upgrade.md)
* [Changelog](changelog.md)
+ * [Prerelease Testing](prereleases.md)
* [Installation Guides](installation/index.md)
* [Configuration Guides](configuration/index.md)
* [Basic Configuration](configuration/basic.md)
@@ -30,6 +31,7 @@ The Opencast Release Documentation is the official Opencast documentation for ea
* [Encoding Configuration](configuration/encoding.md)
* [more...](configuration/index.md)
* [Module Documentation](modules/index.md)
+ * [Plugin Management](modules/plugin-management.md)
* [Atom and RSS Feed](modules/atomrss.md)
* [AWS S3 Distribution](modules/awss3distribution.md)
* [Media Module](modules/mediamodule.configuration.md)
diff --git a/docs/guides/admin/docs/installation/debs.md b/docs/guides/admin/docs/installation/debs.md
index b33c7d66d1..7db7fd1487 100644
--- a/docs/guides/admin/docs/installation/debs.md
+++ b/docs/guides/admin/docs/installation/debs.md
@@ -58,31 +58,6 @@ First you have to install the necessary repositories so that your package manage
apt-get update
-Install Apache ActiveMQ
------------------------
-
-The Apache ActiveMQ message broker is required by Opencast since version 2.0. It does not necessarily have to be
-installed on the same machine as Opencast, however many adopters commonly install it on their admin nodes.
-Install ActiveMQ with:
-
- apt-get install activemq-dist
-
-
-A prepared configuration file for ActiveMQ can be found at `/usr/share/opencast/docs/scripts/activemq/activemq.xml`
-*after Opencast itself has been installed* and should replace `/etc/activemq/activemq.xml`. For an all-in-one
-installation the following command should suffice:
-
- cp /usr/share/opencast/docs/scripts/activemq/activemq.xml /etc/activemq/activemq.xml
-
-ActiveMQ must be started *prior to* Opencast startup.
-
-More information about how to properly set up ActiveMQ for Opencast can be found in the [message broker configuration
-documentation](../configuration/message-broker.md).
-
-Note that most Debian based distributions also have ActiveMQ packaged by upstream package maintainers. These packages
-will work, however the ActiveMQ configuration file will require modification to function correctly.
-
-
Install Elasticsearch
---------------------
@@ -118,7 +93,7 @@ Install Opencast
For a basic installation (All-In-One) just run:
- apt-get install opencast-{{ opencast_major_version() }}-allinone elasticsearch-oss activemq-dist
+ apt-get install opencast-{{ opencast_major_version() }}-allinone elasticsearch-oss
This will install the default distribution of Opencast and all its dependencies, including the 3rd-Party-Tools. Note
that while the repository provides a packaged version of FFmpeg, your distribution may have a version which is
@@ -126,16 +101,14 @@ pre-installed or otherwise takes precedence. This version may work, however Ope
version(s) in the repository. To install the Opencast version of ffmpeg add `ffmpeg-dist` to the end of the command above.
At this point Opencast is installed and will work locally, but it is not completely configured. Because additional configuration
-is required, neither Opencast nor ActiveMQ are configured to start automatically. Please follow the
-[Basic Configuration guide](../configuration/basic.md). Once you are ready, enable Opencast and ActiveMQ to start on boot with:
+is required, Opencast is not configured to start automatically. Please follow the
+[Basic Configuration guide](../configuration/basic.md). Once you are ready, enable Opencast and Elasticsearch to start on boot with:
- systemctl enable activemq.service
systemctl enable elasticsearch.service
systemctl enable opencast.service
then start them with:
- systemctl start activemq.service
systemctl start elasticsearch.service
systemctl start opencast.service
@@ -247,5 +220,5 @@ Troubleshooting
### Missing Dependencies
This repository expects that the `stable` section is always available, regardless of which version of Opencast you have
-installed. The 3rd party tools (ActiveMQ, FFmpeg) may or may not be in the other sections, but if they are there it is
+installed. The 3rd party tools (e.g. FFmpeg) may or may not be in the other sections, but if they are there it is
only during a testing period for a new version. For day-to-day use, please install them from `stable`!
diff --git a/docs/guides/admin/docs/installation/docker-local.md b/docs/guides/admin/docs/installation/docker-local.md
index 7b0010d2f8..a366c5e60d 100644
--- a/docs/guides/admin/docs/installation/docker-local.md
+++ b/docs/guides/admin/docs/installation/docker-local.md
@@ -19,10 +19,9 @@ might be necessary to install [`docker-compose`](https://docs.docker.com/compose
Opencast is packaged into multiple distributions. There is a separate Docker image for each distribution. Simple
installations can use the all-in-one distribution.
-Opencast requires a database and a message broker (Apache ActiveMQ). We currently support H2 or MySQL/MariaDB databases.
+Opencast requires a database. We currently support H2 or MySQL/MariaDB databases.
The Docker Hub repository has official Docker images for MySQL and MariaDB. H2 is already integrated into Opencast so
-that no database container is needed. There are multiple 3rd-party Docker images for ActiveMQ; this guide uses
-`webcenter/activemq`.
+that no database container is needed.
`docker-compose` can be used to configure, start and connect all services automatically. The [opencast-docker
repository](https://github.com/opencast/opencast-docker/tree/master/docker-compose) contains multiple configuration
@@ -46,25 +45,6 @@ $ curl -o docker-compose.yml
You might want to edit the compose file and add extra volumes to include custom configurations or workflows (see
[compose file reference](https://docs.docker.com/compose/compose-file/)).
-The compose files assume that the ActiveMQ configuration is located at `./assets/activemq.xml`. You can download the
-file from the repository:
-
-```sh
-$ mkdir assets
-$ curl -o assets/activemq.xml https://raw.githubusercontent.com/opencast/opencast-docker//docker-compose/assets/activemq.xml
-```
-
-Alternatively, you can use the Docker images to generate the file. This has the advantage that the correct version is
-always used:
-
-```sh
-$ mkdir assets
-
-$ docker run -it --rm \
- quay.io/opencast/allinone: \
- app:print:activemq.xml > assets/activemq.xml
-```
-
At this point you are ready to start Opencast with the `up` command:
```sh
diff --git a/docs/guides/admin/docs/installation/index.md b/docs/guides/admin/docs/installation/index.md
index c6ea8b52b3..2b7d1ce82d 100644
--- a/docs/guides/admin/docs/installation/index.md
+++ b/docs/guides/admin/docs/installation/index.md
@@ -13,10 +13,11 @@ Installation from Repository
There are package repositories available for multiple operating systems. It provides packages containing pre-configured and
pre-built Opencast installations.
-* [RedHat 8 based](rpm-el8.md)
- * [RedHat Enterprise Linux 8](rpm-el8.md)
- * [CentOS 8](rpm-el8.md)
-* [RedHat 7 based](rpm-el8.md)
+* [Red Hat 8/9 based](rpm-el.md)
+ * [RedHat Enterprise Linux](rpm-el.md)
+ * [CentOS Stream](rpm-el.md)
+ * …
+* [Red Hat 7 based](rpm-el7.md)
* [RedHat Enterprise Linux 7](rpm-el7.md)
* [CentOS 7](rpm-el7.md)
* [Scientific Linux 7](rpm-el7.md)
diff --git a/docs/guides/admin/docs/installation/multiple-servers.md b/docs/guides/admin/docs/installation/multiple-servers.md
index fdd4a61446..166686124d 100644
--- a/docs/guides/admin/docs/installation/multiple-servers.md
+++ b/docs/guides/admin/docs/installation/multiple-servers.md
@@ -124,39 +124,12 @@ configure your firewall:
-Step 4: Set-Up ActiveMQ
------------------------
-
-Since version 2, Opencast requires an Apache ActiveMQ message broker as message relay for the administrative user
-interface. ActiveMQ can either be set up to run on its own machine or on one of the existing Opencast nodes (usually the
-admin node).
-
-ActiveMQ 5.10 or above should work. ActiveMQ 5.6 will not work. Versions in between are untested.
-
-
-### Installation
-
-* If you use the Opencast RPM repository, simply install the `activemq-dist` package.
-* If you are running RHEL, CentOS or Fedora you can use the [ActiveMQ-dist Copr RPM
- repository](https://copr.fedoraproject.org/coprs/lkiesow/apache-activemq-dist/)
-* You can download binary distributions from the [Apache ActiveMQ website](http://activemq.apache.org/download.html)
-
-
-### Configuration
-
-What you basically need to do is to point all your Opencast nodes to your message broker. For more information about
-the configuration, have a look at the [Message Broker Set-Up Guide](../configuration/message-broker.md).
-
-Do not forget that ActiveMQ uses TCP port 61616 (default configuration) for communication which you might have to allow
-in your firewall.
-
-
-Step 5: Configure Opencast
+Step 4: Configure Opencast
----------------------------
-You did already set-up and configured your database and message broker in the last steps, but there is some more
-configuration you have to do. First of all you should follow the Basic Configuration guide which will tell you how to
-set the login credentials etc. After that continue with the following steps:
+You already configured your database, but there is some more configuration you have to do. First of all you should
+follow the Basic Configuration guide which will tell you how to set the login credentials etc. After that continue with
+the following steps:
### custom.properties
@@ -185,8 +158,3 @@ set all servers to use the same URL (e.g. URL of the admin node).
prop.org.opencastproject.file.repo.url=http://:8080
-### org.opencastproject.serviceregistry.impl.ServiceRegistryJpaImpl.cfg
-
-To ensure that jobs are not dispatched by non-admin nodes, on these you should also set:
-
- dispatch.interval=0
diff --git a/docs/guides/admin/docs/installation/rpm-el8.md b/docs/guides/admin/docs/installation/rpm-el.md
similarity index 73%
rename from docs/guides/admin/docs/installation/rpm-el8.md
rename to docs/guides/admin/docs/installation/rpm-el.md
index e7f68c96b1..e213b00d39 100644
--- a/docs/guides/admin/docs/installation/rpm-el8.md
+++ b/docs/guides/admin/docs/installation/rpm-el.md
@@ -1,27 +1,28 @@
-Install from Repository (Red Hat Enterprise Linux 8.x, CentOS 8.x)
-==================================================================
+Install from Repository (Red Hat Enterprise Linux, CentOS Stream, …
+===================================================================
-> *This guide is for EL8 only. There is a separate [CentOS 7 and Red Hat Enterprise Linux 7 guide](rpm-el7.md).*
+This guide is based on an RPM software repository available for Red Hat based Linux distributions provided by [Osnabrück
+University](https://uni-osnabrueck.de) and [ELAN e.V.](https://elan-ev.de).
+This repository provides preconfigured Opencast installations and all necessary 3rd-party-tools.
-This guide is based on an RPM software repository available for Red Hat-based Linux distributions provided by [Osnabrück
-University](https://uni-osnabrueck.de). This repository provides preconfigured Opencast installations and all necessary
-3rd-party-tools.
-
-
- Opencast {{ opencast_major_version() }} is not yet available.
-
> In addition to this guide, we have also recorded [a full installation done in 30 minutes](https://vt.uos.de/71hfc)
> if you like to see how this works before you try it yourself.
+
+ Opencast {{ opencast_major_version() }} is not yet available.
+
Currently Supported
-------------------
-- CentOS 8.x (x86\_64)
-- Red Hat Enterprise Linux 8.x (x86\_64)
+We frequently test on CentOS Stream 8/9 and infrequently test on Red Hat Enterprise Linux 8/9,
+trying to ensure that installations on those systems work without problems.
+Since Rocky Linux and AlmaLinux OS are intended to be fully compatible to RHEL,
+those distributions should work as well.
+But we don't test against those.
-Other architectures like i386, i686, arm, … are not supported.
+We support only the x86\_64 architecture.
Activate Repository
@@ -30,7 +31,8 @@ Activate Repository
First you have to install the necessary repositories:
```sh
-dnf install -y https://pkg.opencast.org/rpms/release/el/8/oc-{{ opencast_major_version() }}/noarch/opencast-repository-{{ opencast_major_version() }}-1.el8.noarch.rpm
+dnf install -y \
+ "https://pkg.opencast.org/rpms/release/el/$(rpm -E %rhel)/oc-{{ opencast_major_version() }}/noarch/opencast-repository-{{ opencast_major_version() }}-1.el$(rpm -E %rhel).noarch.rpm"
```
It might take some time after the release of a new Opencast version before the RPMs are moved to the stable repository.
@@ -63,35 +65,6 @@ This will install the default distribution of Opencast and all its dependencies.
For more options, see the [advanced installation section below](#advanced-installation).
-Install Apache ActiveMQ
------------------------
-
-The Apache ActiveMQ message broker is required by Opencast.
-It can be run on the same machine as Opencast.
-Install ActiveMQ by running:
-
-```sh
-dnf install activemq-dist
-```
-
-A prepared configuration file for ActiveMQ comes with Opencast.
-It should suffice for an all-in-one installation and can be copied to replace the default configuration:
-
-```sh
-cp /usr/share/opencast/docs/scripts/activemq/activemq.xml /etc/activemq/activemq.xml
-```
-
-Then start and enable ActiveMQ by running:
-
-```sh
-systemctl start activemq
-systemctl enable activemq
-```
-
-More information about how to properly set up ActiveMQ for Opencast, cluster installations in particular,
-can be found in the [message broker configuration documentation](../configuration/message-broker.md).
-
-
Install Elasticsearch
---------------------
@@ -181,7 +154,8 @@ systemctl stop opencast.service
Then, update the repository:
```sh
-dnf install -y https://pkg.opencast.org/rpms/release/el/8/oc-{{ opencast_major_version() }}/noarch/opencast-repository-{{ opencast_major_version() }}-1.el8.noarch.rpm
+dnf install -y \
+ "https://pkg.opencast.org/rpms/release/el/$(rpm -E %rhel)/oc-{{ opencast_major_version() }}/noarch/opencast-repository-{{ opencast_major_version() }}-1.el$(rpm -E %rhel).noarch.rpm"
```
Upgrade to the new Opencast package by running:
diff --git a/docs/guides/admin/docs/installation/rpm-el7.md b/docs/guides/admin/docs/installation/rpm-el7.md
index e932ac536b..977b57fb91 100644
--- a/docs/guides/admin/docs/installation/rpm-el7.md
+++ b/docs/guides/admin/docs/installation/rpm-el7.md
@@ -1,9 +1,13 @@
Install from Repository (Red Hat Enterprise Linux 7.x, CentOS 7.x, Scientific Linux 7.x)
========================================================================================
-> *This guide is for EL7 only. There is a separate [CentOS 8 and Red Hat Enterprise Linux 8 guide](rpm-el8.md).*
-This guide is based on an RPM software repository available for Red Hat-based Linux distributions provided by [Osnabrück
+
+While we continue to support Opencast for EL7 until the CentOS 7 EOL in mid 2024,
+most testing happens on more modern platforms and we recommend using EL8 or EL9 instead.
+
+
+This guide is based on an RPM software repository available for Red Hat based Linux distributions provided by [Osnabrück
University](https://uni-osnabrueck.de). This repository provides preconfigured Opencast installations and all necessary
3rd-party-tools.
@@ -54,35 +58,6 @@ This will install the default distribution of Opencast and all its dependencies.
For more options, see the [advanced installation section below](#advanced-installation).
-Install Apache ActiveMQ
------------------------
-
-The Apache ActiveMQ message broker is required by Opencast.
-It can be run on the same machine as Opencast.
-Install ActiveMQ by running:
-
-```sh
-yum install activemq-dist
-```
-
-A prepared configuration file for ActiveMQ comes with Opencast.
-It should suffice for an all-in-one installation and can be copied to replace the default configuration:
-
-```sh
-cp /usr/share/opencast/docs/scripts/activemq/activemq.xml /etc/activemq/activemq.xml
-```
-
-Then start and enable ActiveMQ by running:
-
-```sh
-systemctl start activemq
-systemctl enable activemq
-```
-
-More information about how to properly set up ActiveMQ for Opencast, cluster installations in particular,
-can be found in the [message broker configuration documentation](../configuration/message-broker.md).
-
-
Install Elasticsearch
---------------------
diff --git a/docs/guides/admin/docs/installation/rpm-fedora.md b/docs/guides/admin/docs/installation/rpm-fedora.md
index 0921dad481..a456f9af36 100644
--- a/docs/guides/admin/docs/installation/rpm-fedora.md
+++ b/docs/guides/admin/docs/installation/rpm-fedora.md
@@ -31,17 +31,6 @@ For additional Unicode tests run during the build process, you can also install:
dnf install hunspell-de tesseract-langpack-deu
-Install Apache ActiveMQ
------------------------
-
-The Apache ActiveMQ message broker is commonly installed on the same machine as Opencast for an all-in-one system. The
-version of ActiveMQ shipped with Fedora is too old but you can use the [ActiveMQ-dist Copr RPM repository
-](https://copr.fedoraproject.org/coprs/lkiesow/apache-activemq-dist/)
-
-Make sure it is properly configured for Opencast. For more information about the setup, have a look at the
-[message broker configuration documentation](../configuration/message-broker.md).
-
-
Install Opencast
----------------
diff --git a/docs/guides/admin/docs/installation/source-linux.md b/docs/guides/admin/docs/installation/source-linux.md
index de7f4581ed..e47f318779 100644
--- a/docs/guides/admin/docs/installation/source-linux.md
+++ b/docs/guides/admin/docs/installation/source-linux.md
@@ -53,7 +53,6 @@ Required:
Required (not necessarily on the same machine):
- ActiveMQ >= 5.10 (older versions untested)
Elasticsearch 7.9.x
Required for text extraction (recommended):
@@ -79,7 +78,6 @@ website:
* [Get FFmpeg](http://ffmpeg.org/download.html)
* [Get Apache Maven](https://maven.apache.org/download.cgi)
-* [Get Apache ActiveMQ](http://activemq.apache.org/download.html)
* [Get Elasticsearch](https://elastic.co)
Building Opencast
@@ -110,7 +108,6 @@ hostname, login information, etc.
-
Running Opencast
------------------
diff --git a/docs/guides/admin/docs/installation/source-macosx.md b/docs/guides/admin/docs/installation/source-macosx.md
index e275a4d8d3..02cd981041 100644
--- a/docs/guides/admin/docs/installation/source-macosx.md
+++ b/docs/guides/admin/docs/installation/source-macosx.md
@@ -59,7 +59,6 @@ Required:
Required (not necessarily on the same machine):
- ActiveMQ >= 5.10 (older versions untested)
Elasticsearch 7.9.x
Required for text extraction:
@@ -89,7 +88,6 @@ Homebrew is a package manager for OS X. For installation instruction see [their
brew install maven
brew install ffmpeg
- brew install apache-activemq
brew install tesseract
brew install hunspell
@@ -107,7 +105,6 @@ Pre-built versions of most dependencies can be downloaded from the respective pr
* [Get Apache Maven](https://maven.apache.org/download.cgi)
* [Get FFmpeg](http://ffmpeg.org/download.html)
-* [Get Apache ActiveMQ](http://activemq.apache.org/download.html)
Building Opencast
@@ -129,10 +126,6 @@ name, login information, etc. Be aware that the config files now reside in the b
distribution. For the all-in-one distribution, this would be
`/your/path/to/opencast/build/opencast-dist-allinone-[…]/etc/`, again with `[…]` representing the selected version.
-As specified in the guide, make sure you replace the default ActiveMQ configuration with the one provided in
-`docs/scripts/activemq/activemq.xml`. If you installed ActiveMQ using homebrew, you can find the installation path with
-`brew info activemq`. The configuration is probably located in `/usr/local/Cellar/activemq//libexec/conf/`.
-
ffprobe is used to analyze new videos. It is installed with FFmpeg but usually not on the path to be automatically
executed. You have to link the ffprobe to `/usr/local/bin/`. You can find the FFmpeg install directory with
`brew info ffmpeg`. Usually you would link the file with
@@ -141,10 +134,8 @@ executed. You have to link the ffprobe to `/usr/local/bin/`. You can find the FF
Running Opencast
----------------
-Make sure you have ActiveMQ running (unless you're running it on a different machine). Then you can start Opencast using
-the start-opencast script:
+You can start Opencast using the start-opencast script:
- activemq start
cd /your/path/to/opencast/
cd build/opencast-dist-allinone-[…]
./bin/start-opencast
diff --git a/docs/guides/admin/docs/javascript/extra.js b/docs/guides/admin/docs/javascript/extra.js
index 63977ce88b..9dfe1f557f 100644
--- a/docs/guides/admin/docs/javascript/extra.js
+++ b/docs/guides/admin/docs/javascript/extra.js
@@ -27,8 +27,24 @@ $(document).ready(function () {
ga('send', 'pageview');
}
tocPaneFix();
+ tooltips();
});
+/**
+ * Style the tooltips.
+ */
+function tooltips() {
+ tippy('[title]', {
+ content(reference) {
+ const title = reference.getAttribute('title');
+ reference.removeAttribute('title');
+ return title;
+ },
+ interactive: true,
+ theme: 'opencast',
+ });
+}
+
/**
* Fixes the issue that you can click on the toc elements, while the toc pane on the left side is closed
diff --git a/docs/guides/admin/docs/javascript/popper.js b/docs/guides/admin/docs/javascript/popper.js
new file mode 100644
index 0000000000..4edfeba6be
--- /dev/null
+++ b/docs/guides/admin/docs/javascript/popper.js
@@ -0,0 +1,6 @@
+/**
+ * @popperjs/core v2.11.2 - MIT License
+ */
+
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Popper={})}(this,(function(e){"use strict";function t(e){if(null==e)return window;if("[object Window]"!==e.toString()){var t=e.ownerDocument;return t&&t.defaultView||window}return e}function n(e){return e instanceof t(e).Element||e instanceof Element}function r(e){return e instanceof t(e).HTMLElement||e instanceof HTMLElement}function o(e){return"undefined"!=typeof ShadowRoot&&(e instanceof t(e).ShadowRoot||e instanceof ShadowRoot)}var i=Math.max,a=Math.min,s=Math.round;function f(e,t){void 0===t&&(t=!1);var n=e.getBoundingClientRect(),o=1,i=1;if(r(e)&&t){var a=e.offsetHeight,f=e.offsetWidth;f>0&&(o=s(n.width)/f||1),a>0&&(i=s(n.height)/a||1)}return{width:n.width/o,height:n.height/i,top:n.top/i,right:n.right/o,bottom:n.bottom/i,left:n.left/o,x:n.left/o,y:n.top/i}}function c(e){var n=t(e);return{scrollLeft:n.pageXOffset,scrollTop:n.pageYOffset}}function p(e){return e?(e.nodeName||"").toLowerCase():null}function u(e){return((n(e)?e.ownerDocument:e.document)||window.document).documentElement}function l(e){return f(u(e)).left+c(e).scrollLeft}function d(e){return t(e).getComputedStyle(e)}function h(e){var t=d(e),n=t.overflow,r=t.overflowX,o=t.overflowY;return/auto|scroll|overlay|hidden/.test(n+o+r)}function m(e,n,o){void 0===o&&(o=!1);var i,a,d=r(n),m=r(n)&&function(e){var t=e.getBoundingClientRect(),n=s(t.width)/e.offsetWidth||1,r=s(t.height)/e.offsetHeight||1;return 1!==n||1!==r}(n),v=u(n),g=f(e,m),y={scrollLeft:0,scrollTop:0},b={x:0,y:0};return(d||!d&&!o)&&(("body"!==p(n)||h(v))&&(y=(i=n)!==t(i)&&r(i)?{scrollLeft:(a=i).scrollLeft,scrollTop:a.scrollTop}:c(i)),r(n)?((b=f(n,!0)).x+=n.clientLeft,b.y+=n.clientTop):v&&(b.x=l(v))),{x:g.left+y.scrollLeft-b.x,y:g.top+y.scrollTop-b.y,width:g.width,height:g.height}}function v(e){var t=f(e),n=e.offsetWidth,r=e.offsetHeight;return Math.abs(t.width-n)<=1&&(n=t.width),Math.abs(t.height-r)<=1&&(r=t.height),{x:e.offsetLeft,y:e.offsetTop,width:n,height:r}}function g(e){return"html"===p(e)?e:e.assignedSlot||e.parentNode||(o(e)?e.host:null)||u(e)}function y(e){return["html","body","#document"].indexOf(p(e))>=0?e.ownerDocument.body:r(e)&&h(e)?e:y(g(e))}function b(e,n){var r;void 0===n&&(n=[]);var o=y(e),i=o===(null==(r=e.ownerDocument)?void 0:r.body),a=t(o),s=i?[a].concat(a.visualViewport||[],h(o)?o:[]):o,f=n.concat(s);return i?f:f.concat(b(g(s)))}function x(e){return["table","td","th"].indexOf(p(e))>=0}function w(e){return r(e)&&"fixed"!==d(e).position?e.offsetParent:null}function O(e){for(var n=t(e),o=w(e);o&&x(o)&&"static"===d(o).position;)o=w(o);return o&&("html"===p(o)||"body"===p(o)&&"static"===d(o).position)?n:o||function(e){var t=-1!==navigator.userAgent.toLowerCase().indexOf("firefox");if(-1!==navigator.userAgent.indexOf("Trident")&&r(e)&&"fixed"===d(e).position)return null;for(var n=g(e);r(n)&&["html","body"].indexOf(p(n))<0;){var o=d(n);if("none"!==o.transform||"none"!==o.perspective||"paint"===o.contain||-1!==["transform","perspective"].indexOf(o.willChange)||t&&"filter"===o.willChange||t&&o.filter&&"none"!==o.filter)return n;n=n.parentNode}return null}(e)||n}var j="top",E="bottom",D="right",A="left",L="auto",P=[j,E,D,A],M="start",k="end",W="viewport",B="popper",H=P.reduce((function(e,t){return e.concat([t+"-"+M,t+"-"+k])}),[]),T=[].concat(P,[L]).reduce((function(e,t){return e.concat([t,t+"-"+M,t+"-"+k])}),[]),R=["beforeRead","read","afterRead","beforeMain","main","afterMain","beforeWrite","write","afterWrite"];function S(e){var t=new Map,n=new Set,r=[];function o(e){n.add(e.name),[].concat(e.requires||[],e.requiresIfExists||[]).forEach((function(e){if(!n.has(e)){var r=t.get(e);r&&o(r)}})),r.push(e)}return e.forEach((function(e){t.set(e.name,e)})),e.forEach((function(e){n.has(e.name)||o(e)})),r}function C(e){return e.split("-")[0]}function q(e,t){var n=t.getRootNode&&t.getRootNode();if(e.contains(t))return!0;if(n&&o(n)){var r=t;do{if(r&&e.isSameNode(r))return!0;r=r.parentNode||r.host}while(r)}return!1}function V(e){return Object.assign({},e,{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height})}function N(e,r){return r===W?V(function(e){var n=t(e),r=u(e),o=n.visualViewport,i=r.clientWidth,a=r.clientHeight,s=0,f=0;return o&&(i=o.width,a=o.height,/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(s=o.offsetLeft,f=o.offsetTop)),{width:i,height:a,x:s+l(e),y:f}}(e)):n(r)?function(e){var t=f(e);return t.top=t.top+e.clientTop,t.left=t.left+e.clientLeft,t.bottom=t.top+e.clientHeight,t.right=t.left+e.clientWidth,t.width=e.clientWidth,t.height=e.clientHeight,t.x=t.left,t.y=t.top,t}(r):V(function(e){var t,n=u(e),r=c(e),o=null==(t=e.ownerDocument)?void 0:t.body,a=i(n.scrollWidth,n.clientWidth,o?o.scrollWidth:0,o?o.clientWidth:0),s=i(n.scrollHeight,n.clientHeight,o?o.scrollHeight:0,o?o.clientHeight:0),f=-r.scrollLeft+l(e),p=-r.scrollTop;return"rtl"===d(o||n).direction&&(f+=i(n.clientWidth,o?o.clientWidth:0)-a),{width:a,height:s,x:f,y:p}}(u(e)))}function I(e,t,o){var s="clippingParents"===t?function(e){var t=b(g(e)),o=["absolute","fixed"].indexOf(d(e).position)>=0&&r(e)?O(e):e;return n(o)?t.filter((function(e){return n(e)&&q(e,o)&&"body"!==p(e)})):[]}(e):[].concat(t),f=[].concat(s,[o]),c=f[0],u=f.reduce((function(t,n){var r=N(e,n);return t.top=i(r.top,t.top),t.right=a(r.right,t.right),t.bottom=a(r.bottom,t.bottom),t.left=i(r.left,t.left),t}),N(e,c));return u.width=u.right-u.left,u.height=u.bottom-u.top,u.x=u.left,u.y=u.top,u}function _(e){return e.split("-")[1]}function F(e){return["top","bottom"].indexOf(e)>=0?"x":"y"}function U(e){var t,n=e.reference,r=e.element,o=e.placement,i=o?C(o):null,a=o?_(o):null,s=n.x+n.width/2-r.width/2,f=n.y+n.height/2-r.height/2;switch(i){case j:t={x:s,y:n.y-r.height};break;case E:t={x:s,y:n.y+n.height};break;case D:t={x:n.x+n.width,y:f};break;case A:t={x:n.x-r.width,y:f};break;default:t={x:n.x,y:n.y}}var c=i?F(i):null;if(null!=c){var p="y"===c?"height":"width";switch(a){case M:t[c]=t[c]-(n[p]/2-r[p]/2);break;case k:t[c]=t[c]+(n[p]/2-r[p]/2)}}return t}function z(e){return Object.assign({},{top:0,right:0,bottom:0,left:0},e)}function X(e,t){return t.reduce((function(t,n){return t[n]=e,t}),{})}function Y(e,t){void 0===t&&(t={});var r=t,o=r.placement,i=void 0===o?e.placement:o,a=r.boundary,s=void 0===a?"clippingParents":a,c=r.rootBoundary,p=void 0===c?W:c,l=r.elementContext,d=void 0===l?B:l,h=r.altBoundary,m=void 0!==h&&h,v=r.padding,g=void 0===v?0:v,y=z("number"!=typeof g?g:X(g,P)),b=d===B?"reference":B,x=e.rects.popper,w=e.elements[m?b:d],O=I(n(w)?w:w.contextElement||u(e.elements.popper),s,p),A=f(e.elements.reference),L=U({reference:A,element:x,strategy:"absolute",placement:i}),M=V(Object.assign({},x,L)),k=d===B?M:A,H={top:O.top-k.top+y.top,bottom:k.bottom-O.bottom+y.bottom,left:O.left-k.left+y.left,right:k.right-O.right+y.right},T=e.modifiersData.offset;if(d===B&&T){var R=T[i];Object.keys(H).forEach((function(e){var t=[D,E].indexOf(e)>=0?1:-1,n=[j,E].indexOf(e)>=0?"y":"x";H[e]+=R[n]*t}))}return H}var G={placement:"bottom",modifiers:[],strategy:"absolute"};function J(){for(var e=arguments.length,t=new Array(e),n=0;n=0?-1:1,i="function"==typeof n?n(Object.assign({},t,{placement:e})):n,a=i[0],s=i[1];return a=a||0,s=(s||0)*o,[A,D].indexOf(r)>=0?{x:s,y:a}:{x:a,y:s}}(n,t.rects,i),e}),{}),s=a[t.placement],f=s.x,c=s.y;null!=t.modifiersData.popperOffsets&&(t.modifiersData.popperOffsets.x+=f,t.modifiersData.popperOffsets.y+=c),t.modifiersData[r]=a}},ie={left:"right",right:"left",bottom:"top",top:"bottom"};function ae(e){return e.replace(/left|right|bottom|top/g,(function(e){return ie[e]}))}var se={start:"end",end:"start"};function fe(e){return e.replace(/start|end/g,(function(e){return se[e]}))}function ce(e,t){void 0===t&&(t={});var n=t,r=n.placement,o=n.boundary,i=n.rootBoundary,a=n.padding,s=n.flipVariations,f=n.allowedAutoPlacements,c=void 0===f?T:f,p=_(r),u=p?s?H:H.filter((function(e){return _(e)===p})):P,l=u.filter((function(e){return c.indexOf(e)>=0}));0===l.length&&(l=u);var d=l.reduce((function(t,n){return t[n]=Y(e,{placement:n,boundary:o,rootBoundary:i,padding:a})[C(n)],t}),{});return Object.keys(d).sort((function(e,t){return d[e]-d[t]}))}var pe={name:"flip",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,r=e.name;if(!t.modifiersData[r]._skip){for(var o=n.mainAxis,i=void 0===o||o,a=n.altAxis,s=void 0===a||a,f=n.fallbackPlacements,c=n.padding,p=n.boundary,u=n.rootBoundary,l=n.altBoundary,d=n.flipVariations,h=void 0===d||d,m=n.allowedAutoPlacements,v=t.options.placement,g=C(v),y=f||(g===v||!h?[ae(v)]:function(e){if(C(e)===L)return[];var t=ae(e);return[fe(e),t,fe(t)]}(v)),b=[v].concat(y).reduce((function(e,n){return e.concat(C(n)===L?ce(t,{placement:n,boundary:p,rootBoundary:u,padding:c,flipVariations:h,allowedAutoPlacements:m}):n)}),[]),x=t.rects.reference,w=t.rects.popper,O=new Map,P=!0,k=b[0],W=0;W=0,S=R?"width":"height",q=Y(t,{placement:B,boundary:p,rootBoundary:u,altBoundary:l,padding:c}),V=R?T?D:A:T?E:j;x[S]>w[S]&&(V=ae(V));var N=ae(V),I=[];if(i&&I.push(q[H]<=0),s&&I.push(q[V]<=0,q[N]<=0),I.every((function(e){return e}))){k=B,P=!1;break}O.set(B,I)}if(P)for(var F=function(e){var t=b.find((function(t){var n=O.get(t);if(n)return n.slice(0,e).every((function(e){return e}))}));if(t)return k=t,"break"},U=h?3:1;U>0;U--){if("break"===F(U))break}t.placement!==k&&(t.modifiersData[r]._skip=!0,t.placement=k,t.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function ue(e,t,n){return i(e,a(t,n))}var le={name:"preventOverflow",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,r=e.name,o=n.mainAxis,s=void 0===o||o,f=n.altAxis,c=void 0!==f&&f,p=n.boundary,u=n.rootBoundary,l=n.altBoundary,d=n.padding,h=n.tether,m=void 0===h||h,g=n.tetherOffset,y=void 0===g?0:g,b=Y(t,{boundary:p,rootBoundary:u,padding:d,altBoundary:l}),x=C(t.placement),w=_(t.placement),L=!w,P=F(x),k="x"===P?"y":"x",W=t.modifiersData.popperOffsets,B=t.rects.reference,H=t.rects.popper,T="function"==typeof y?y(Object.assign({},t.rects,{placement:t.placement})):y,R="number"==typeof T?{mainAxis:T,altAxis:T}:Object.assign({mainAxis:0,altAxis:0},T),S=t.modifiersData.offset?t.modifiersData.offset[t.placement]:null,q={x:0,y:0};if(W){if(s){var V,N="y"===P?j:A,I="y"===P?E:D,U="y"===P?"height":"width",z=W[P],X=z+b[N],G=z-b[I],J=m?-H[U]/2:0,K=w===M?B[U]:H[U],Q=w===M?-H[U]:-B[U],Z=t.elements.arrow,$=m&&Z?v(Z):{width:0,height:0},ee=t.modifiersData["arrow#persistent"]?t.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},te=ee[N],ne=ee[I],re=ue(0,B[U],$[U]),oe=L?B[U]/2-J-re-te-R.mainAxis:K-re-te-R.mainAxis,ie=L?-B[U]/2+J+re+ne+R.mainAxis:Q+re+ne+R.mainAxis,ae=t.elements.arrow&&O(t.elements.arrow),se=ae?"y"===P?ae.clientTop||0:ae.clientLeft||0:0,fe=null!=(V=null==S?void 0:S[P])?V:0,ce=z+ie-fe,pe=ue(m?a(X,z+oe-fe-se):X,z,m?i(G,ce):G);W[P]=pe,q[P]=pe-z}if(c){var le,de="x"===P?j:A,he="x"===P?E:D,me=W[k],ve="y"===k?"height":"width",ge=me+b[de],ye=me-b[he],be=-1!==[j,A].indexOf(x),xe=null!=(le=null==S?void 0:S[k])?le:0,we=be?ge:me-B[ve]-H[ve]-xe+R.altAxis,Oe=be?me+B[ve]+H[ve]-xe-R.altAxis:ye,je=m&&be?function(e,t,n){var r=ue(e,t,n);return r>n?n:r}(we,me,Oe):ue(m?we:ge,me,m?Oe:ye);W[k]=je,q[k]=je-me}t.modifiersData[r]=q}},requiresIfExists:["offset"]};var de={name:"arrow",enabled:!0,phase:"main",fn:function(e){var t,n=e.state,r=e.name,o=e.options,i=n.elements.arrow,a=n.modifiersData.popperOffsets,s=C(n.placement),f=F(s),c=[A,D].indexOf(s)>=0?"height":"width";if(i&&a){var p=function(e,t){return z("number"!=typeof(e="function"==typeof e?e(Object.assign({},t.rects,{placement:t.placement})):e)?e:X(e,P))}(o.padding,n),u=v(i),l="y"===f?j:A,d="y"===f?E:D,h=n.rects.reference[c]+n.rects.reference[f]-a[f]-n.rects.popper[c],m=a[f]-n.rects.reference[f],g=O(i),y=g?"y"===f?g.clientHeight||0:g.clientWidth||0:0,b=h/2-m/2,x=p[l],w=y-u[c]-p[d],L=y/2-u[c]/2+b,M=ue(x,L,w),k=f;n.modifiersData[r]=((t={})[k]=M,t.centerOffset=M-L,t)}},effect:function(e){var t=e.state,n=e.options.element,r=void 0===n?"[data-popper-arrow]":n;null!=r&&("string"!=typeof r||(r=t.elements.popper.querySelector(r)))&&q(t.elements.popper,r)&&(t.elements.arrow=r)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function he(e,t,n){return void 0===n&&(n={x:0,y:0}),{top:e.top-t.height-n.y,right:e.right-t.width+n.x,bottom:e.bottom-t.height+n.y,left:e.left-t.width-n.x}}function me(e){return[j,D,E,A].some((function(t){return e[t]>=0}))}var ve={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(e){var t=e.state,n=e.name,r=t.rects.reference,o=t.rects.popper,i=t.modifiersData.preventOverflow,a=Y(t,{elementContext:"reference"}),s=Y(t,{altBoundary:!0}),f=he(a,r),c=he(s,o,i),p=me(f),u=me(c);t.modifiersData[n]={referenceClippingOffsets:f,popperEscapeOffsets:c,isReferenceHidden:p,hasPopperEscaped:u},t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-reference-hidden":p,"data-popper-escaped":u})}},ge=K({defaultModifiers:[Z,$,ne,re]}),ye=[Z,$,ne,re,oe,pe,le,de,ve],be=K({defaultModifiers:ye});e.applyStyles=re,e.arrow=de,e.computeStyles=ne,e.createPopper=be,e.createPopperLite=ge,e.defaultModifiers=ye,e.detectOverflow=Y,e.eventListeners=Z,e.flip=pe,e.hide=ve,e.offset=oe,e.popperGenerator=K,e.popperOffsets=$,e.preventOverflow=le,Object.defineProperty(e,"__esModule",{value:!0})}));
+//# sourceMappingURL=popper.min.js.map
diff --git a/docs/guides/admin/docs/javascript/tippy.js b/docs/guides/admin/docs/javascript/tippy.js
new file mode 100644
index 0000000000..9f4f8bcd9e
--- /dev/null
+++ b/docs/guides/admin/docs/javascript/tippy.js
@@ -0,0 +1,2 @@
+!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("@popperjs/core")):"function"==typeof define&&define.amd?define(["@popperjs/core"],e):(t=t||self).tippy=e(t.Popper)}(this,(function(t){"use strict";var e="undefined"!=typeof window&&"undefined"!=typeof document,n=!!e&&!!window.msCrypto,r={passive:!0,capture:!0},o=function(){return document.body};function i(t,e,n){if(Array.isArray(t)){var r=t[e];return null==r?Array.isArray(n)?n[e]:n:r}return t}function a(t,e){var n={}.toString.call(t);return 0===n.indexOf("[object")&&n.indexOf(e+"]")>-1}function s(t,e){return"function"==typeof t?t.apply(void 0,e):t}function u(t,e){return 0===e?t:function(r){clearTimeout(n),n=setTimeout((function(){t(r)}),e)};var n}function p(t,e){var n=Object.assign({},t);return e.forEach((function(t){delete n[t]})),n}function c(t){return[].concat(t)}function f(t,e){-1===t.indexOf(e)&&t.push(e)}function l(t){return t.split("-")[0]}function d(t){return[].slice.call(t)}function v(t){return Object.keys(t).reduce((function(e,n){return void 0!==t[n]&&(e[n]=t[n]),e}),{})}function m(){return document.createElement("div")}function g(t){return["Element","Fragment"].some((function(e){return a(t,e)}))}function h(t){return a(t,"MouseEvent")}function b(t){return!(!t||!t._tippy||t._tippy.reference!==t)}function y(t){return g(t)?[t]:function(t){return a(t,"NodeList")}(t)?d(t):Array.isArray(t)?t:d(document.querySelectorAll(t))}function w(t,e){t.forEach((function(t){t&&(t.style.transitionDuration=e+"ms")}))}function x(t,e){t.forEach((function(t){t&&t.setAttribute("data-state",e)}))}function E(t){var e,n=c(t)[0];return null!=n&&null!=(e=n.ownerDocument)&&e.body?n.ownerDocument:document}function O(t,e,n){var r=e+"EventListener";["transitionend","webkitTransitionEnd"].forEach((function(e){t[r](e,n)}))}function C(t,e){for(var n=e;n;){var r;if(t.contains(n))return!0;n=null==n.getRootNode||null==(r=n.getRootNode())?void 0:r.host}return!1}var T={isTouch:!1},A=0;function L(){T.isTouch||(T.isTouch=!0,window.performance&&document.addEventListener("mousemove",D))}function D(){var t=performance.now();t-A<20&&(T.isTouch=!1,document.removeEventListener("mousemove",D)),A=t}function k(){var t=document.activeElement;if(b(t)){var e=t._tippy;t.blur&&!e.state.isVisible&&t.blur()}}var R=Object.assign({appendTo:o,aria:{content:"auto",expanded:"auto"},delay:0,duration:[300,250],getReferenceClientRect:null,hideOnClick:!0,ignoreAttributes:!1,interactive:!1,interactiveBorder:2,interactiveDebounce:0,moveTransition:"",offset:[0,10],onAfterUpdate:function(){},onBeforeUpdate:function(){},onCreate:function(){},onDestroy:function(){},onHidden:function(){},onHide:function(){},onMount:function(){},onShow:function(){},onShown:function(){},onTrigger:function(){},onUntrigger:function(){},onClickOutside:function(){},placement:"top",plugins:[],popperOptions:{},render:null,showOnCreate:!1,touch:!0,trigger:"mouseenter focus",triggerTarget:null},{animateFill:!1,followCursor:!1,inlinePositioning:!1,sticky:!1},{allowHTML:!1,animation:"fade",arrow:!0,content:"",inertia:!1,maxWidth:350,role:"tooltip",theme:"",zIndex:9999}),P=Object.keys(R);function j(t){var e=(t.plugins||[]).reduce((function(e,n){var r,o=n.name,i=n.defaultValue;o&&(e[o]=void 0!==t[o]?t[o]:null!=(r=R[o])?r:i);return e}),{});return Object.assign({},t,e)}function M(t,e){var n=Object.assign({},e,{content:s(e.content,[t])},e.ignoreAttributes?{}:function(t,e){return(e?Object.keys(j(Object.assign({},R,{plugins:e}))):P).reduce((function(e,n){var r=(t.getAttribute("data-tippy-"+n)||"").trim();if(!r)return e;if("content"===n)e[n]=r;else try{e[n]=JSON.parse(r)}catch(t){e[n]=r}return e}),{})}(t,e.plugins));return n.aria=Object.assign({},R.aria,n.aria),n.aria={expanded:"auto"===n.aria.expanded?e.interactive:n.aria.expanded,content:"auto"===n.aria.content?e.interactive?null:"describedby":n.aria.content},n}function V(t,e){t.innerHTML=e}function I(t){var e=m();return!0===t?e.className="tippy-arrow":(e.className="tippy-svg-arrow",g(t)?e.appendChild(t):V(e,t)),e}function S(t,e){g(e.content)?(V(t,""),t.appendChild(e.content)):"function"!=typeof e.content&&(e.allowHTML?V(t,e.content):t.textContent=e.content)}function B(t){var e=t.firstElementChild,n=d(e.children);return{box:e,content:n.find((function(t){return t.classList.contains("tippy-content")})),arrow:n.find((function(t){return t.classList.contains("tippy-arrow")||t.classList.contains("tippy-svg-arrow")})),backdrop:n.find((function(t){return t.classList.contains("tippy-backdrop")}))}}function N(t){var e=m(),n=m();n.className="tippy-box",n.setAttribute("data-state","hidden"),n.setAttribute("tabindex","-1");var r=m();function o(n,r){var o=B(e),i=o.box,a=o.content,s=o.arrow;r.theme?i.setAttribute("data-theme",r.theme):i.removeAttribute("data-theme"),"string"==typeof r.animation?i.setAttribute("data-animation",r.animation):i.removeAttribute("data-animation"),r.inertia?i.setAttribute("data-inertia",""):i.removeAttribute("data-inertia"),i.style.maxWidth="number"==typeof r.maxWidth?r.maxWidth+"px":r.maxWidth,r.role?i.setAttribute("role",r.role):i.removeAttribute("role"),n.content===r.content&&n.allowHTML===r.allowHTML||S(a,t.props),r.arrow?s?n.arrow!==r.arrow&&(i.removeChild(s),i.appendChild(I(r.arrow))):i.appendChild(I(r.arrow)):s&&i.removeChild(s)}return r.className="tippy-content",r.setAttribute("data-state","hidden"),S(r,t.props),e.appendChild(n),n.appendChild(r),o(t.props,t.props),{popper:e,onUpdate:o}}N.$$tippy=!0;var H=1,U=[],_=[];function z(e,a){var p,g,b,y,A,L,D,k,P=M(e,Object.assign({},R,j(v(a)))),V=!1,I=!1,S=!1,N=!1,z=[],F=u(wt,P.interactiveDebounce),W=H++,X=(k=P.plugins).filter((function(t,e){return k.indexOf(t)===e})),Y={id:W,reference:e,popper:m(),popperInstance:null,props:P,state:{isEnabled:!0,isVisible:!1,isDestroyed:!1,isMounted:!1,isShown:!1},plugins:X,clearDelayTimeouts:function(){clearTimeout(p),clearTimeout(g),cancelAnimationFrame(b)},setProps:function(t){if(Y.state.isDestroyed)return;at("onBeforeUpdate",[Y,t]),bt();var n=Y.props,r=M(e,Object.assign({},n,v(t),{ignoreAttributes:!0}));Y.props=r,ht(),n.interactiveDebounce!==r.interactiveDebounce&&(pt(),F=u(wt,r.interactiveDebounce));n.triggerTarget&&!r.triggerTarget?c(n.triggerTarget).forEach((function(t){t.removeAttribute("aria-expanded")})):r.triggerTarget&&e.removeAttribute("aria-expanded");ut(),it(),J&&J(n,r);Y.popperInstance&&(Ct(),At().forEach((function(t){requestAnimationFrame(t._tippy.popperInstance.forceUpdate)})));at("onAfterUpdate",[Y,t])},setContent:function(t){Y.setProps({content:t})},show:function(){var t=Y.state.isVisible,e=Y.state.isDestroyed,n=!Y.state.isEnabled,r=T.isTouch&&!Y.props.touch,a=i(Y.props.duration,0,R.duration);if(t||e||n||r)return;if(et().hasAttribute("disabled"))return;if(at("onShow",[Y],!1),!1===Y.props.onShow(Y))return;Y.state.isVisible=!0,tt()&&($.style.visibility="visible");it(),dt(),Y.state.isMounted||($.style.transition="none");if(tt()){var u=rt(),p=u.box,c=u.content;w([p,c],0)}L=function(){var t;if(Y.state.isVisible&&!N){if(N=!0,$.offsetHeight,$.style.transition=Y.props.moveTransition,tt()&&Y.props.animation){var e=rt(),n=e.box,r=e.content;w([n,r],a),x([n,r],"visible")}st(),ut(),f(_,Y),null==(t=Y.popperInstance)||t.forceUpdate(),at("onMount",[Y]),Y.props.animation&&tt()&&function(t,e){mt(t,e)}(a,(function(){Y.state.isShown=!0,at("onShown",[Y])}))}},function(){var t,e=Y.props.appendTo,n=et();t=Y.props.interactive&&e===o||"parent"===e?n.parentNode:s(e,[n]);t.contains($)||t.appendChild($);Y.state.isMounted=!0,Ct()}()},hide:function(){var t=!Y.state.isVisible,e=Y.state.isDestroyed,n=!Y.state.isEnabled,r=i(Y.props.duration,1,R.duration);if(t||e||n)return;if(at("onHide",[Y],!1),!1===Y.props.onHide(Y))return;Y.state.isVisible=!1,Y.state.isShown=!1,N=!1,V=!1,tt()&&($.style.visibility="hidden");if(pt(),vt(),it(!0),tt()){var o=rt(),a=o.box,s=o.content;Y.props.animation&&(w([a,s],r),x([a,s],"hidden"))}st(),ut(),Y.props.animation?tt()&&function(t,e){mt(t,(function(){!Y.state.isVisible&&$.parentNode&&$.parentNode.contains($)&&e()}))}(r,Y.unmount):Y.unmount()},hideWithInteractivity:function(t){nt().addEventListener("mousemove",F),f(U,F),F(t)},enable:function(){Y.state.isEnabled=!0},disable:function(){Y.hide(),Y.state.isEnabled=!1},unmount:function(){Y.state.isVisible&&Y.hide();if(!Y.state.isMounted)return;Tt(),At().forEach((function(t){t._tippy.unmount()})),$.parentNode&&$.parentNode.removeChild($);_=_.filter((function(t){return t!==Y})),Y.state.isMounted=!1,at("onHidden",[Y])},destroy:function(){if(Y.state.isDestroyed)return;Y.clearDelayTimeouts(),Y.unmount(),bt(),delete e._tippy,Y.state.isDestroyed=!0,at("onDestroy",[Y])}};if(!P.render)return Y;var q=P.render(Y),$=q.popper,J=q.onUpdate;$.setAttribute("data-tippy-root",""),$.id="tippy-"+Y.id,Y.popper=$,e._tippy=Y,$._tippy=Y;var G=X.map((function(t){return t.fn(Y)})),K=e.hasAttribute("aria-expanded");return ht(),ut(),it(),at("onCreate",[Y]),P.showOnCreate&&Lt(),$.addEventListener("mouseenter",(function(){Y.props.interactive&&Y.state.isVisible&&Y.clearDelayTimeouts()})),$.addEventListener("mouseleave",(function(){Y.props.interactive&&Y.props.trigger.indexOf("mouseenter")>=0&&nt().addEventListener("mousemove",F)})),Y;function Q(){var t=Y.props.touch;return Array.isArray(t)?t:[t,0]}function Z(){return"hold"===Q()[0]}function tt(){var t;return!(null==(t=Y.props.render)||!t.$$tippy)}function et(){return D||e}function nt(){var t=et().parentNode;return t?E(t):document}function rt(){return B($)}function ot(t){return Y.state.isMounted&&!Y.state.isVisible||T.isTouch||y&&"focus"===y.type?0:i(Y.props.delay,t?0:1,R.delay)}function it(t){void 0===t&&(t=!1),$.style.pointerEvents=Y.props.interactive&&!t?"":"none",$.style.zIndex=""+Y.props.zIndex}function at(t,e,n){var r;(void 0===n&&(n=!0),G.forEach((function(n){n[t]&&n[t].apply(n,e)})),n)&&(r=Y.props)[t].apply(r,e)}function st(){var t=Y.props.aria;if(t.content){var n="aria-"+t.content,r=$.id;c(Y.props.triggerTarget||e).forEach((function(t){var e=t.getAttribute(n);if(Y.state.isVisible)t.setAttribute(n,e?e+" "+r:r);else{var o=e&&e.replace(r,"").trim();o?t.setAttribute(n,o):t.removeAttribute(n)}}))}}function ut(){!K&&Y.props.aria.expanded&&c(Y.props.triggerTarget||e).forEach((function(t){Y.props.interactive?t.setAttribute("aria-expanded",Y.state.isVisible&&t===et()?"true":"false"):t.removeAttribute("aria-expanded")}))}function pt(){nt().removeEventListener("mousemove",F),U=U.filter((function(t){return t!==F}))}function ct(t){if(!T.isTouch||!S&&"mousedown"!==t.type){var n=t.composedPath&&t.composedPath()[0]||t.target;if(!Y.props.interactive||!C($,n)){if(c(Y.props.triggerTarget||e).some((function(t){return C(t,n)}))){if(T.isTouch)return;if(Y.state.isVisible&&Y.props.trigger.indexOf("click")>=0)return}else at("onClickOutside",[Y,t]);!0===Y.props.hideOnClick&&(Y.clearDelayTimeouts(),Y.hide(),I=!0,setTimeout((function(){I=!1})),Y.state.isMounted||vt())}}}function ft(){S=!0}function lt(){S=!1}function dt(){var t=nt();t.addEventListener("mousedown",ct,!0),t.addEventListener("touchend",ct,r),t.addEventListener("touchstart",lt,r),t.addEventListener("touchmove",ft,r)}function vt(){var t=nt();t.removeEventListener("mousedown",ct,!0),t.removeEventListener("touchend",ct,r),t.removeEventListener("touchstart",lt,r),t.removeEventListener("touchmove",ft,r)}function mt(t,e){var n=rt().box;function r(t){t.target===n&&(O(n,"remove",r),e())}if(0===t)return e();O(n,"remove",A),O(n,"add",r),A=r}function gt(t,n,r){void 0===r&&(r=!1),c(Y.props.triggerTarget||e).forEach((function(e){e.addEventListener(t,n,r),z.push({node:e,eventType:t,handler:n,options:r})}))}function ht(){var t;Z()&&(gt("touchstart",yt,{passive:!0}),gt("touchend",xt,{passive:!0})),(t=Y.props.trigger,t.split(/\s+/).filter(Boolean)).forEach((function(t){if("manual"!==t)switch(gt(t,yt),t){case"mouseenter":gt("mouseleave",xt);break;case"focus":gt(n?"focusout":"blur",Et);break;case"focusin":gt("focusout",Et)}}))}function bt(){z.forEach((function(t){var e=t.node,n=t.eventType,r=t.handler,o=t.options;e.removeEventListener(n,r,o)})),z=[]}function yt(t){var e,n=!1;if(Y.state.isEnabled&&!Ot(t)&&!I){var r="focus"===(null==(e=y)?void 0:e.type);y=t,D=t.currentTarget,ut(),!Y.state.isVisible&&h(t)&&U.forEach((function(e){return e(t)})),"click"===t.type&&(Y.props.trigger.indexOf("mouseenter")<0||V)&&!1!==Y.props.hideOnClick&&Y.state.isVisible?n=!0:Lt(t),"click"===t.type&&(V=!n),n&&!r&&Dt(t)}}function wt(t){var e=t.target,n=et().contains(e)||$.contains(e);"mousemove"===t.type&&n||function(t,e){var n=e.clientX,r=e.clientY;return t.every((function(t){var e=t.popperRect,o=t.popperState,i=t.props.interactiveBorder,a=l(o.placement),s=o.modifiersData.offset;if(!s)return!0;var u="bottom"===a?s.top.y:0,p="top"===a?s.bottom.y:0,c="right"===a?s.left.x:0,f="left"===a?s.right.x:0,d=e.top-r+u>i,v=r-e.bottom-p>i,m=e.left-n+c>i,g=n-e.right-f>i;return d||v||m||g}))}(At().concat($).map((function(t){var e,n=null==(e=t._tippy.popperInstance)?void 0:e.state;return n?{popperRect:t.getBoundingClientRect(),popperState:n,props:P}:null})).filter(Boolean),t)&&(pt(),Dt(t))}function xt(t){Ot(t)||Y.props.trigger.indexOf("click")>=0&&V||(Y.props.interactive?Y.hideWithInteractivity(t):Dt(t))}function Et(t){Y.props.trigger.indexOf("focusin")<0&&t.target!==et()||Y.props.interactive&&t.relatedTarget&&$.contains(t.relatedTarget)||Dt(t)}function Ot(t){return!!T.isTouch&&Z()!==t.type.indexOf("touch")>=0}function Ct(){Tt();var n=Y.props,r=n.popperOptions,o=n.placement,i=n.offset,a=n.getReferenceClientRect,s=n.moveTransition,u=tt()?B($).arrow:null,p=a?{getBoundingClientRect:a,contextElement:a.contextElement||et()}:e,c=[{name:"offset",options:{offset:i}},{name:"preventOverflow",options:{padding:{top:2,bottom:2,left:5,right:5}}},{name:"flip",options:{padding:5}},{name:"computeStyles",options:{adaptive:!s}},{name:"$$tippy",enabled:!0,phase:"beforeWrite",requires:["computeStyles"],fn:function(t){var e=t.state;if(tt()){var n=rt().box;["placement","reference-hidden","escaped"].forEach((function(t){"placement"===t?n.setAttribute("data-placement",e.placement):e.attributes.popper["data-popper-"+t]?n.setAttribute("data-"+t,""):n.removeAttribute("data-"+t)})),e.attributes.popper={}}}}];tt()&&u&&c.push({name:"arrow",options:{element:u,padding:3}}),c.push.apply(c,(null==r?void 0:r.modifiers)||[]),Y.popperInstance=t.createPopper(p,$,Object.assign({},r,{placement:o,onFirstUpdate:L,modifiers:c}))}function Tt(){Y.popperInstance&&(Y.popperInstance.destroy(),Y.popperInstance=null)}function At(){return d($.querySelectorAll("[data-tippy-root]"))}function Lt(t){Y.clearDelayTimeouts(),t&&at("onTrigger",[Y,t]),dt();var e=ot(!0),n=Q(),r=n[0],o=n[1];T.isTouch&&"hold"===r&&o&&(e=o),e?p=setTimeout((function(){Y.show()}),e):Y.show()}function Dt(t){if(Y.clearDelayTimeouts(),at("onUntrigger",[Y,t]),Y.state.isVisible){if(!(Y.props.trigger.indexOf("mouseenter")>=0&&Y.props.trigger.indexOf("click")>=0&&["mouseleave","mousemove"].indexOf(t.type)>=0&&V)){var e=ot(!1);e?g=setTimeout((function(){Y.state.isVisible&&Y.hide()}),e):b=requestAnimationFrame((function(){Y.hide()}))}}else vt()}}function F(t,e){void 0===e&&(e={});var n=R.plugins.concat(e.plugins||[]);document.addEventListener("touchstart",L,r),window.addEventListener("blur",k);var o=Object.assign({},e,{plugins:n}),i=y(t).reduce((function(t,e){var n=e&&z(e,o);return n&&t.push(n),t}),[]);return g(t)?i[0]:i}F.defaultProps=R,F.setDefaultProps=function(t){Object.keys(t).forEach((function(e){R[e]=t[e]}))},F.currentInput=T;var W=Object.assign({},t.applyStyles,{effect:function(t){var e=t.state,n={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};Object.assign(e.elements.popper.style,n.popper),e.styles=n,e.elements.arrow&&Object.assign(e.elements.arrow.style,n.arrow)}}),X={mouseover:"mouseenter",focusin:"focus",click:"click"};var Y={name:"animateFill",defaultValue:!1,fn:function(t){var e;if(null==(e=t.props.render)||!e.$$tippy)return{};var n=B(t.popper),r=n.box,o=n.content,i=t.props.animateFill?function(){var t=m();return t.className="tippy-backdrop",x([t],"hidden"),t}():null;return{onCreate:function(){i&&(r.insertBefore(i,r.firstElementChild),r.setAttribute("data-animatefill",""),r.style.overflow="hidden",t.setProps({arrow:!1,animation:"shift-away"}))},onMount:function(){if(i){var t=r.style.transitionDuration,e=Number(t.replace("ms",""));o.style.transitionDelay=Math.round(e/10)+"ms",i.style.transitionDuration=t,x([i],"visible")}},onShow:function(){i&&(i.style.transitionDuration="0ms")},onHide:function(){i&&x([i],"hidden")}}}};var q={clientX:0,clientY:0},$=[];function J(t){var e=t.clientX,n=t.clientY;q={clientX:e,clientY:n}}var G={name:"followCursor",defaultValue:!1,fn:function(t){var e=t.reference,n=E(t.props.triggerTarget||e),r=!1,o=!1,i=!0,a=t.props;function s(){return"initial"===t.props.followCursor&&t.state.isVisible}function u(){n.addEventListener("mousemove",f)}function p(){n.removeEventListener("mousemove",f)}function c(){r=!0,t.setProps({getReferenceClientRect:null}),r=!1}function f(n){var r=!n.target||e.contains(n.target),o=t.props.followCursor,i=n.clientX,a=n.clientY,s=e.getBoundingClientRect(),u=i-s.left,p=a-s.top;!r&&t.props.interactive||t.setProps({getReferenceClientRect:function(){var t=e.getBoundingClientRect(),n=i,r=a;"initial"===o&&(n=t.left+u,r=t.top+p);var s="horizontal"===o?t.top:r,c="vertical"===o?t.right:n,f="horizontal"===o?t.bottom:r,l="vertical"===o?t.left:n;return{width:c-l,height:f-s,top:s,right:c,bottom:f,left:l}}})}function l(){t.props.followCursor&&($.push({instance:t,doc:n}),function(t){t.addEventListener("mousemove",J)}(n))}function d(){0===($=$.filter((function(e){return e.instance!==t}))).filter((function(t){return t.doc===n})).length&&function(t){t.removeEventListener("mousemove",J)}(n)}return{onCreate:l,onDestroy:d,onBeforeUpdate:function(){a=t.props},onAfterUpdate:function(e,n){var i=n.followCursor;r||void 0!==i&&a.followCursor!==i&&(d(),i?(l(),!t.state.isMounted||o||s()||u()):(p(),c()))},onMount:function(){t.props.followCursor&&!o&&(i&&(f(q),i=!1),s()||u())},onTrigger:function(t,e){h(e)&&(q={clientX:e.clientX,clientY:e.clientY}),o="focus"===e.type},onHidden:function(){t.props.followCursor&&(c(),p(),i=!0)}}}};var K={name:"inlinePositioning",defaultValue:!1,fn:function(t){var e,n=t.reference;var r=-1,o=!1,i=[],a={name:"tippyInlinePositioning",enabled:!0,phase:"afterWrite",fn:function(o){var a=o.state;t.props.inlinePositioning&&(-1!==i.indexOf(a.placement)&&(i=[]),e!==a.placement&&-1===i.indexOf(a.placement)&&(i.push(a.placement),t.setProps({getReferenceClientRect:function(){return function(t){return function(t,e,n,r){if(n.length<2||null===t)return e;if(2===n.length&&r>=0&&n[0].left>n[1].right)return n[r]||e;switch(t){case"top":case"bottom":var o=n[0],i=n[n.length-1],a="top"===t,s=o.top,u=i.bottom,p=a?o.left:i.left,c=a?o.right:i.right;return{top:s,bottom:u,left:p,right:c,width:c-p,height:u-s};case"left":case"right":var f=Math.min.apply(Math,n.map((function(t){return t.left}))),l=Math.max.apply(Math,n.map((function(t){return t.right}))),d=n.filter((function(e){return"left"===t?e.left===f:e.right===l})),v=d[0].top,m=d[d.length-1].bottom;return{top:v,bottom:m,left:f,right:l,width:l-f,height:m-v};default:return e}}(l(t),n.getBoundingClientRect(),d(n.getClientRects()),r)}(a.placement)}})),e=a.placement)}};function s(){var e;o||(e=function(t,e){var n;return{popperOptions:Object.assign({},t.popperOptions,{modifiers:[].concat(((null==(n=t.popperOptions)?void 0:n.modifiers)||[]).filter((function(t){return t.name!==e.name})),[e])})}}(t.props,a),o=!0,t.setProps(e),o=!1)}return{onCreate:s,onAfterUpdate:s,onTrigger:function(e,n){if(h(n)){var o=d(t.reference.getClientRects()),i=o.find((function(t){return t.left-2<=n.clientX&&t.right+2>=n.clientX&&t.top-2<=n.clientY&&t.bottom+2>=n.clientY})),a=o.indexOf(i);r=a>-1?a:r}},onHidden:function(){r=-1}}}};var Q={name:"sticky",defaultValue:!1,fn:function(t){var e=t.reference,n=t.popper;function r(e){return!0===t.props.sticky||t.props.sticky===e}var o=null,i=null;function a(){var s=r("reference")?(t.popperInstance?t.popperInstance.state.elements.reference:e).getBoundingClientRect():null,u=r("popper")?n.getBoundingClientRect():null;(s&&Z(o,s)||u&&Z(i,u))&&t.popperInstance&&t.popperInstance.update(),o=s,i=u,t.state.isMounted&&requestAnimationFrame(a)}return{onMount:function(){t.props.sticky&&a()}}}};function Z(t,e){return!t||!e||(t.top!==e.top||t.right!==e.right||t.bottom!==e.bottom||t.left!==e.left)}return e&&function(t){var e=document.createElement("style");e.textContent=t,e.setAttribute("data-tippy-stylesheet","");var n=document.head,r=document.querySelector("head>style,head>link");r?n.insertBefore(e,r):n.appendChild(e)}('.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;white-space:normal;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1}'),F.setDefaultProps({plugins:[Y,G,K,Q],render:N}),F.createSingleton=function(t,e){var n;void 0===e&&(e={});var r,o=t,i=[],a=[],s=e.overrides,u=[],f=!1;function l(){a=o.map((function(t){return c(t.props.triggerTarget||t.reference)})).reduce((function(t,e){return t.concat(e)}),[])}function d(){i=o.map((function(t){return t.reference}))}function v(t){o.forEach((function(e){t?e.enable():e.disable()}))}function g(t){return o.map((function(e){var n=e.setProps;return e.setProps=function(o){n(o),e.reference===r&&t.setProps(o)},function(){e.setProps=n}}))}function h(t,e){var n=a.indexOf(e);if(e!==r){r=e;var u=(s||[]).concat("content").reduce((function(t,e){return t[e]=o[n].props[e],t}),{});t.setProps(Object.assign({},u,{getReferenceClientRect:"function"==typeof u.getReferenceClientRect?u.getReferenceClientRect:function(){var t;return null==(t=i[n])?void 0:t.getBoundingClientRect()}}))}}v(!1),d(),l();var b={fn:function(){return{onDestroy:function(){v(!0)},onHidden:function(){r=null},onClickOutside:function(t){t.props.showOnCreate&&!f&&(f=!0,r=null)},onShow:function(t){t.props.showOnCreate&&!f&&(f=!0,h(t,i[0]))},onTrigger:function(t,e){h(t,e.currentTarget)}}}},y=F(m(),Object.assign({},p(e,["overrides"]),{plugins:[b].concat(e.plugins||[]),triggerTarget:a,popperOptions:Object.assign({},e.popperOptions,{modifiers:[].concat((null==(n=e.popperOptions)?void 0:n.modifiers)||[],[W])})})),w=y.show;y.show=function(t){if(w(),!r&&null==t)return h(y,i[0]);if(!r||null!=t){if("number"==typeof t)return i[t]&&h(y,i[t]);if(o.indexOf(t)>=0){var e=t.reference;return h(y,e)}return i.indexOf(t)>=0?h(y,t):void 0}},y.showNext=function(){var t=i[0];if(!r)return y.show(0);var e=i.indexOf(r);y.show(i[e+1]||t)},y.showPrevious=function(){var t=i[i.length-1];if(!r)return y.show(t);var e=i.indexOf(r),n=i[e-1]||t;y.show(n)};var x=y.setProps;return y.setProps=function(t){s=t.overrides||s,x(t)},y.setInstances=function(t){v(!0),u.forEach((function(t){return t()})),o=t,v(!1),d(),l(),u=g(y),y.setProps({triggerTarget:a})},u=g(y),y},F.delegate=function(t,e){var n=[],o=[],i=!1,a=e.target,s=p(e,["target"]),u=Object.assign({},s,{trigger:"manual",touch:!1}),f=Object.assign({touch:R.touch},s,{showOnCreate:!0}),l=F(t,u);function d(t){if(t.target&&!i){var n=t.target.closest(a);if(n){var r=n.getAttribute("data-tippy-trigger")||e.trigger||R.trigger;if(!n._tippy&&!("touchstart"===t.type&&"boolean"==typeof f.touch||"touchstart"!==t.type&&r.indexOf(X[t.type])<0)){var s=F(n,f);s&&(o=o.concat(s))}}}}function v(t,e,r,o){void 0===o&&(o=!1),t.addEventListener(e,r,o),n.push({node:t,eventType:e,handler:r,options:o})}return c(l).forEach((function(t){var e=t.destroy,a=t.enable,s=t.disable;t.destroy=function(t){void 0===t&&(t=!0),t&&o.forEach((function(t){t.destroy()})),o=[],n.forEach((function(t){var e=t.node,n=t.eventType,r=t.handler,o=t.options;e.removeEventListener(n,r,o)})),n=[],e()},t.enable=function(){a(),o.forEach((function(t){return t.enable()})),i=!1},t.disable=function(){s(),o.forEach((function(t){return t.disable()})),i=!0},function(t){var e=t.reference;v(e,"touchstart",d,r),v(e,"mouseover",d),v(e,"focusin",d),v(e,"click",d)}(t)})),l},F.hideAll=function(t){var e=void 0===t?{}:t,n=e.exclude,r=e.duration;_.forEach((function(t){var e=!1;if(n&&(e=b(n)?t.reference===n:t.popper===n.popper),!e){var o=t.props.duration;t.setProps({duration:r}),t.hide(),t.state.isDestroyed||t.setProps({duration:o})}}))},F.roundArrow='',F}));
+//# sourceMappingURL=tippy-bundle.umd.min.js.map
diff --git a/docs/guides/admin/docs/modules/index.md b/docs/guides/admin/docs/modules/index.md
index 815bc00711..1f05eb25b3 100644
--- a/docs/guides/admin/docs/modules/index.md
+++ b/docs/guides/admin/docs/modules/index.md
@@ -11,9 +11,6 @@ Documentation for modules included in Opencast.
* [LTI Module](ltimodule.md)
* [Media Module](mediamodule.configuration.md)
* [Metrics (OpenMetrics, Prometheus)](metrics.md)
-* Player
- * [Configuration](player.configuration.md)
- * [URL Parameter](player.url.parameter.md)
* [Search Indexes](searchindex/index.md)
* [Solr](searchindex/solr.md)
* [Stream Security](stream-security.md)
@@ -27,6 +24,7 @@ Documentation for modules included in Opencast.
* Termination State
* [Basic](terminationstate.md)
* [AWS AutoScaling](terminationstate.aws.autoscaling.md)
-* [Transcripts (Google Speech)](googlespeechtranscripts.md)
-* [Transcripts (IBM Watson)](watsontranscripts.md)
+* [Transcripts (Google Speech)](transcription.modules/googlespeechtranscripts.md)
+* [Transcripts (IBM Watson)](transcription.modules/watsontranscripts.md)
+* [Transcripts (Microsoft Azure)](transcription.modules/microsoftazuretranscripts.md)
* [YouTube Publication](youtubepublication.md)
diff --git a/docs/guides/admin/docs/modules/paella.player7/configuration.md b/docs/guides/admin/docs/modules/paella.player7/configuration.md
new file mode 100644
index 0000000000..0d0ef7f32c
--- /dev/null
+++ b/docs/guides/admin/docs/modules/paella.player7/configuration.md
@@ -0,0 +1,41 @@
+Paella Player 7
+===============
+
+The Paella `(pronounced 'paeja')` [Player](https://paellaplayer.upv.es) is an Open Source
+JavaScript video player capable of playing an unlimited number of audio & video streams
+synchronously, Live Streaming, Zoom, Captions, contributed user plugins and a lot more.
+It is easy to install and customize for your own needs.
+
+Paella 7 will be a complete rewrite of Paella, aiming several issues
+
+- Allow easier integration in other platforms by leaving out the singleton design pattern.
+- Easier styling and accessibility support.
+- Reduce the number of dependencies.
+- Allow easier long-term maintenance of the project.
+- Solve the technical debt of 10 years of development.
+
+Have a look at the paella 7 [repository](https://github.com/polimediaupv/paella-core)
+or [documentation page](https://github.com/polimediaupv/paella-core/blob/main/doc/index.md).
+
+
+Configuration
+-------------
+
+The configurations for the player are done for each tenant. So the configuration keys are located in
+`.../etc/ui-config//paella7/config.yml`
+
+The default tenant for opencast is `mh_default_org`
+
+Change the default colors
+-------------------------
+
+To customize the theme modify the `.../etc/ui-config//paella7/custom_theme.css` file.
+
+Select the Opencast Player
+------------------------------
+
+To activate the player set for each tenant the property `prop.player` in the file `.../etc/org.opencastproject.organization-.cfg`.
+
+
+ prop.player=/paella7/ui/watch.html?id=#{id}
+
diff --git a/docs/guides/admin/docs/modules/player.configuration.md b/docs/guides/admin/docs/modules/player.configuration.md
index 369f9ddc45..674eba9963 100644
--- a/docs/guides/admin/docs/modules/player.configuration.md
+++ b/docs/guides/admin/docs/modules/player.configuration.md
@@ -2,14 +2,13 @@ Opencast Player - Configuration
===============================
The configurations for the player are done for each tenant. So the configuration keys are located in
-`.../etc/ui-config//theodul/config.yml`
+`.../etc/ui-config///`
The default tenant for opencast is `mh_default_org`
Select the Opencast Player
------------------------------
-To activate the player set in each tenant this line in the file `.../etc/org.opencastproject.organization-.cfg`.
-
+To change the default player for a tenant, set the following key in `.../etc/org.opencastproject.organization-.cfg`.
prop.player=/paella/ui/watch.html?id=#{id}
diff --git a/docs/guides/admin/docs/modules/player.matomo.tracking.md b/docs/guides/admin/docs/modules/player.matomo.tracking.md
deleted file mode 100644
index 741e0ccd42..0000000000
--- a/docs/guides/admin/docs/modules/player.matomo.tracking.md
+++ /dev/null
@@ -1,79 +0,0 @@
-Opencast Player - Matomo Tracking Plugin
-=======================================
-
-This plugin allows using [Matomo](https://matomo.org) to track usage data.
-To setup Matomo please follow the instructions on the Matomo website:
-
-- [The 5-minute Matomo Installation](https://matomo.org/docs/installation/#the-5-minute-matomo-installation)
-
-The plugin respects the [Do-Not-Track](https://en.wikipedia.org/wiki/Do_Not_Track) settings of a browser.
-Please consider the legal requirements of your country when you set up Matomo.
-
-This plugin uses a Matomo JavaScript library that is loaded from the remote Matomo server!
-
-Tested Matomo version: 3.0.2+ ; Matomo Analytics Cloud
-
-The configurations for the Matomo player plugin are done for each tenant.
-The configuration keys are located in `etc/ui-config//theodul/config.yml`.
-
-To activate the plugin set the Matomo server URL:
-
- server: https://matomo.example.com/matomo
-
-
-Configuration
--------------
-
-### server:
-
-The Matomo server from which the Piwik JS library will be loaded and where the data will be reported.
-
-### site_id: 1
-
-The Matomo site ID has to be numeric value. If not set this will be 1. It is recommended to use different site IDs for
-each tenant that is configured in Opencast.
-
-### heartbeat: 30
-
-The heartbeat setting to track how long a user stayed on the player page. Set to 0 or comment this line to
-disable the heartbeat.
-
-### notification: true
-
-The plugin shows a notification about the tracking to the user. This can be disabled with this option. (Default: `true`)
-Before you disable the notification, make sure that you do not violate any local regulations.
-
-### track_events: ["play", "pause", "seek", "ended"]
-
-This setting lets you track several player events. Add the events that you want to track to the list.
-Comment this property to prevent event tracking.
-
-Events that can be tracked:
-
-* play: play has been pressed (will also be called if after seeking).
-* pause: pause has been pressed (will also be called if before seeking).
-* seek: user jumps to a different time. Time in seconds will be stored
-* ended: video has reached the end
-* playbackrate: user changes the playback speed (values 0.75 to 3.00)
-* volume: Volume change by the user value 0.0 to 1.0
-* quality: manual change of video quality (quality tag is stored)
-* fullscreen: user presses fullscreen button
-* focus: user selects one video to be enlarged (flavor of selected video is stored)
-* layout\_reset: user switches back to default layout
-* zoom: user changes the zoom of the video
-
-Tracked Data
-------------
-
-Additional to the event data that can be turned on for each event (see above), this Opencast specific data is tracked
-if tracking is allowed:
-
-* Page name as ` - `
-* Custom Matomo variables:
- * "event" as ` ()`
- * "series" as ` ()`
- * "presenter"
- * "view\_mode" which can be `desktop`, `mobile` or `embed`
-
-Heartbeat data does not show how long a video has been played but how long a viewer remained on the page, while the page
-was in the foreground.
diff --git a/docs/guides/admin/docs/modules/player.url.parameter.md b/docs/guides/admin/docs/modules/player.url.parameter.md
deleted file mode 100644
index 33b70c7f68..0000000000
--- a/docs/guides/admin/docs/modules/player.url.parameter.md
+++ /dev/null
@@ -1,101 +0,0 @@
-Opencast Player * URL Parameters
-================================
-
-URL Parameters
---------------
-
-* **time**
- * Possible values
- * Minutes (with value `X`) and seconds (with value `Y`)
- * `XmYs`
- * `YsXm`
- * `XmY`
- * Minutes (with value `X`) only
- * `Xm`
- * Seconds (with value `Y`) only
- * `Ys`
- * `Y`
- * Default value
- * `-`
- * Description
- * Seeks initially automatically to a specified time
- * automatically plays the video from the specified time on
-* **autoplay**
- * Possible values
- * `true`
- * `false`
- * Default value
- * `false`
- * Description
- * Automatically starts playing the video after a short delay
-* **quality**
- * Possible values
- * `low`
- * `medium`
- * `high`
- * Default value
- * `medium`
- * Description
- * Sets a video quality if the video has been encoded in multiple qualities
-* **mode**
- * Possible values
- * `desktop`
- * `embed`
- * `mobile`
- * Default value
- * `desktop`
- * Description
- * Sets the player mode manually
-* **browser**
- * Possible values
- * `all`
- * `default`
- * Default value
- * `default`
- * Description
- * If your browser is not supported, try the new player with this flag activated overwrites filtering for supported
- browsers with parameter set to `all`
-
-
-### Example
-
- http://YOUR.SERVER:8080/engage/theodul/ui/core.html?id=SOME-ID&time=3m30s
-
-
-## Developer URL Parameters
-
-* **debug**
- * Possible values
- * `true`
- * `false`
- * Default value
- * `false`
- * Description
- * prints debug output to the developer console
-* **debugEvents**
- * Possible values
- * `true`
- * `false`
- * Default value
- * `false`
- * Description
- * Prints debug output to the developer console when an event occurs
-* **format**
- * Possible Values
- * `hls`: Apple HTTP Live Streaming
- * `dash`: MPEG DASH
- * `rtmp`: Adobe RTMP (Flash)
- * `mp4`: MP4 videos (no streaming)
- * `webm`: WebM videos (no streaming)
- * `audio`: audio only (no streaming)
- * `default`: reset to defaults
- * Default value
- * `default`
- * Description
- * sets the preferred (streaming) format
- * if not available, the defaults will be selected
- * the value is permanently stored for the browser in the local storage
-
-### Example
-
- http://YOUR.SERVER:8080/engage/theodul/ui/core.html?id=SOME-ID&debug=true&debugEvents=true
diff --git a/docs/guides/admin/docs/modules/plugin-management.md b/docs/guides/admin/docs/modules/plugin-management.md
new file mode 100644
index 0000000000..26f22693a7
--- /dev/null
+++ b/docs/guides/admin/docs/modules/plugin-management.md
@@ -0,0 +1,31 @@
+Plugin Management
+=================
+
+Opencast comes with a number of plugins which allow you to turn additional functionality off and on.
+Plugins can be enabled at runtime in `etc/org.opencastproject.plugin.impl.PluginManagerImpl.cfg` by setting the specific
+configuration to `on` or `off`.
+
+List of Available Plugins
+-------------------------
+
+- opencast-plugin-legacy-annotation
+ - Legacy annotation functionality. We do not recommend turning this on. It also requires additional configuration in
+ the player. It's kept for a few legacy use-cases.
+- opencast-plugin-transcription-services
+ - Support for the Amberscript transcription service
+ - Support for the Google cloud transcription service
+ - Support for the IBM cloud transcription service
+ - Support for the Microsoft Azure cloud transcription service
+- opencast-plugin-userdirectory-brightspace
+ - Module allowing Opencast to look up users in a Brightspace LMS
+- opencast-plugin-userdirectory-canvas
+ - Module allowing Opencast to look up users in a Canvas LMS
+- opencast-plugin-userdirectory-moodle
+ - Module allowing Opencast to look up users in a Moodle LMS
+- opencast-plugin-userdirectory-sakai
+ - Module allowing Opencast to look up users in a Sakai LMS
+- opencast-plugin-userdirectory-studip
+ - Module allowing Opencast to look up users in a Stud.IP LMS
+- opencast-plugin-usertracking
+ - Legacy user tracking module. We do not recommend turning this on. It also requires additional configuration in
+ the player. It's kept for a few legacy use-cases.
diff --git a/docs/guides/admin/docs/modules/searchindex/index.md b/docs/guides/admin/docs/modules/searchindex/index.md
index d9f359f8bd..d7864adcb0 100644
--- a/docs/guides/admin/docs/modules/searchindex/index.md
+++ b/docs/guides/admin/docs/modules/searchindex/index.md
@@ -4,7 +4,9 @@ Search Indexes
Opencast comes with multiple search indexes which act both as a cache and as a fast way to perform full text searches on
metadata. By default, the Solr search indexes are created automatically and no additional external software is required.
-For Elasticsearch, a separate installation is required since Opencast version 9.0.
+For Opensearch/Elasticsearch, a separate installation is required since Opencast version 9.0. Opencast 12 now supports
+both Opensearch and Elasticsearch, with Elasticsearch being the default. We are planning on deprecating Elasticsearch
+support with Opencast 13, and removing it with Opencast 14. New installs should use Opensearch.
While this works well, all indexes can be deployed separately. This comes with the obvious drawback of a harder
deployment but has also a few advantages like a smaller core system or being able to have some service redundancies
@@ -17,8 +19,9 @@ which would not be possible otherwise.
[Solr Configuration Guide](solr.md)
-- Elasticsearch powers the external API as well as the administrative user interface of Opencast.
+- Opensearch/Elasticsearch powers the external API as well as the administrative user interface of Opencast. Pick one of the following
[Elasticsearch Configuration Guide](../../configuration/elasticsearch.md)
+ [Opensearch Configuration Guide](../../configuration/opensearch.md)
---
diff --git a/docs/guides/admin/docs/modules/streaming-wowza.md b/docs/guides/admin/docs/modules/streaming-wowza.md
index 5ee54f9939..a00fd7521d 100644
--- a/docs/guides/admin/docs/modules/streaming-wowza.md
+++ b/docs/guides/admin/docs/modules/streaming-wowza.md
@@ -157,7 +157,6 @@ All this can be configured in the "Options" section of the Wowza application:
## Players and Formats
-* **Theodul**: HLS, DASH (over HTTP and HTTPS)
* **Paella** : HLS, DASH (over HTTP and HTTPS)
diff --git a/docs/guides/admin/docs/modules/amberscripttranscripts.md b/docs/guides/admin/docs/modules/transcription.modules/amberscripttranscripts.md
similarity index 94%
rename from docs/guides/admin/docs/modules/amberscripttranscripts.md
rename to docs/guides/admin/docs/modules/transcription.modules/amberscripttranscripts.md
index 15207369b3..562b2b42ed 100644
--- a/docs/guides/admin/docs/modules/amberscripttranscripts.md
+++ b/docs/guides/admin/docs/modules/transcription.modules/amberscripttranscripts.md
@@ -1,6 +1,9 @@
AmberScript Transcription Service
=================================
+> Using this requires you to turn on an Opencast plugin.
+> Take a look [at the plugin management documentation](../plugin-management.md) to find out how you can do that.
+
Overview
--------
@@ -199,6 +202,6 @@ into your existing workflow:
Workflow Operations
-------------------
-* [amberscript-start-transcription](../workflowoperationhandlers/amberscript-start-transcription-woh.md)
-* [amberscript-attach-transcription](../workflowoperationhandlers/amberscript-attach-transcription-woh.md)
+* [amberscript-start-transcription](../../workflowoperationhandlers/amberscript-start-transcription-woh.md)
+* [amberscript-attach-transcription](../../workflowoperationhandlers/amberscript-attach-transcription-woh.md)
diff --git a/docs/guides/admin/docs/modules/google-speech-authorisation.png b/docs/guides/admin/docs/modules/transcription.modules/google-speech-authorisation.png
similarity index 100%
rename from docs/guides/admin/docs/modules/google-speech-authorisation.png
rename to docs/guides/admin/docs/modules/transcription.modules/google-speech-authorisation.png
diff --git a/docs/guides/admin/docs/modules/google-speech-create_oauth-client-id.png b/docs/guides/admin/docs/modules/transcription.modules/google-speech-create_oauth-client-id.png
similarity index 100%
rename from docs/guides/admin/docs/modules/google-speech-create_oauth-client-id.png
rename to docs/guides/admin/docs/modules/transcription.modules/google-speech-create_oauth-client-id.png
diff --git a/docs/guides/admin/docs/modules/google-speech_client-secret.png b/docs/guides/admin/docs/modules/transcription.modules/google-speech_client-secret.png
similarity index 100%
rename from docs/guides/admin/docs/modules/google-speech_client-secret.png
rename to docs/guides/admin/docs/modules/transcription.modules/google-speech_client-secret.png
diff --git a/docs/guides/admin/docs/modules/google-speech_create_token.png b/docs/guides/admin/docs/modules/transcription.modules/google-speech_create_token.png
similarity index 100%
rename from docs/guides/admin/docs/modules/google-speech_create_token.png
rename to docs/guides/admin/docs/modules/transcription.modules/google-speech_create_token.png
diff --git a/docs/guides/admin/docs/modules/google-speech_genarated-token.png b/docs/guides/admin/docs/modules/transcription.modules/google-speech_genarated-token.png
similarity index 100%
rename from docs/guides/admin/docs/modules/google-speech_genarated-token.png
rename to docs/guides/admin/docs/modules/transcription.modules/google-speech_genarated-token.png
diff --git a/docs/guides/admin/docs/modules/googlespeechtranscripts.md b/docs/guides/admin/docs/modules/transcription.modules/googlespeechtranscripts.md
similarity index 93%
rename from docs/guides/admin/docs/modules/googlespeechtranscripts.md
rename to docs/guides/admin/docs/modules/transcription.modules/googlespeechtranscripts.md
index b80dc4f9cc..c664bf45cb 100644
--- a/docs/guides/admin/docs/modules/googlespeechtranscripts.md
+++ b/docs/guides/admin/docs/modules/transcription.modules/googlespeechtranscripts.md
@@ -1,6 +1,9 @@
Transcripts (Automated by Google Speech)
========================================
+> Using this requires you to turn on an Opencast plugin.
+> Take a look [at the plugin management documentation](../plugin-management.md) to find out how you can do that.
+
Overview
--------
@@ -103,6 +106,8 @@ Edit _etc/org.opencastproject.transcription.googlespeech.GoogleSpeechTranscript
* Use **_OAuth Client ID_**, **_OAuth Client secret_**, **_Refresh token_**, **_Token endpoint_** and **_storage bucket_** created above to respectively set _google.cloud.client.id_ , _google.cloud.client.secret_ , _google.cloud.refresh.token_ , _google.cloud.token.endpoint.url_ and _google.cloud.storage.bucket_
* Enter the appropriate language in _google.speech.language_, default is (_en-US_). List of supported language: [https://cloud.google.com/speech-to-text/docs/languages](https://cloud.google.com/speech-to-text/docs/languages)
* Remove profanity (bad language) from transcription by using _google.speech.profanity.filter_, default is (_false_), not removed by default
+* Set the transcription model using _google.speech.transcription.model_, default is (_default_). List of models: https://cloud.google.com/speech-to-text/docs/transcription-model
+* Enable punctuation for transcription result by setting _google.speech.transcription.punctuation_, to (_true_) default is (_false_)
* In _workflow_, enter the workflow definition id of the workflow to be used to attach the generated transcripts/captions
* Enter a _notification.email_ to get job failure notifications. If not entered, the email in _etc/custom.properties_ (org.opencastproject.admin.email) will be used.
If no email address specified in either _notification.email_ or _org.opencastproject.admin.email_,
@@ -129,6 +134,13 @@ google.speech.language=
# Filter out profanities from result. Default is false
google.speech.profanity.filter=false
+# Enable punctuations for transcription. Default is false
+google.speech.transcription.punctuation=true
+
+# Transcription model to use
+# If empty, the "default" model will be used
+google.speech.transcription.model=default
+
# Workflow to be executed when results are ready to be attached to media package.
workflow=google-speech-attach-transcripts
@@ -268,5 +280,5 @@ is cancelled (when something goes wrong).
Workflow Operations
-------------------
-* [google-speech-attach-transcription](../workflowoperationhandlers/google-speech-attach-transcription-woh.md)
-* [google-speech-start-transcription](../workflowoperationhandlers/google-speech-start-transcription-woh.md)
\ No newline at end of file
+* [google-speech-attach-transcription](../../workflowoperationhandlers/google-speech-attach-transcription-woh.md)
+* [google-speech-start-transcription](../../workflowoperationhandlers/google-speech-start-transcription-woh.md)
diff --git a/docs/guides/admin/docs/modules/transcription.modules/microsoftazuretranscripts.md b/docs/guides/admin/docs/modules/transcription.modules/microsoftazuretranscripts.md
new file mode 100644
index 0000000000..d362a1efbc
--- /dev/null
+++ b/docs/guides/admin/docs/modules/transcription.modules/microsoftazuretranscripts.md
@@ -0,0 +1,275 @@
+Transcripts (Automated by Microsoft Azure)
+========================================
+
+Overview
+--------
+
+The Microsoft Azure Transcription Service invokes the Azure Speech-to-Text service via its Java SDK to transcribe audio
+ to text.
+
+During the execution of an Opencast workflow, a file containing the audio to be transcribed is streamed to the
+Microsoft Azure Speech-to-Text service. Results are converted to WebVTT or SRT format
+and attached to the media package.
+
+**Note that because Speech-to-Text services require a significant amount of time to process a recording,
+we do not wait for it to finish before proceeding with the rest of Opencast's normal processing.
+This means that the transcription process is run asynchronously.**
+
+* Workflow 1 runs:
+ * Speech-to-Text job is started
+ * Workflow finishes
+
+Speech-to-Text job finishes, workflow 2 is started.
+
+* Workflow 2 runs:
+ * File is attached to media package
+ * Media package is republished with captions/transcripts
+
+Microsoft Azure Speech-to-Text service documentation, including which languages are currently supported, can be found
+ [here](https://docs.microsoft.com/en-us/azure/cognitive-services/speech-service/language-support?tabs=speechtotext#speech-to-text).
+
+
+Configuration
+-------------
+
+### Step 1: Get Azure subscription credentials
+
+* [Create an Azure subscription](https://azure.microsoft.com/en-US/free/cognitive-services/)
+* [Create a speech resource](https://portal.azure.com/#create/Microsoft.CognitiveServicesSpeechServices)
+* Get the subscription key and region. After your Speech resource is deployed, select 'Go to resource' to view and
+manage keys. For more information about Cognitive Services resources, see
+[here](https://docs.microsoft.com/en-us/azure/cognitive-services/cognitive-services-apis-create-account?tabs=multiservice%2Clinux#get-the-keys-for-your-resource)
+
+### Step 2: Install GStreamer
+
+The Microsoft speech-to-text client uses GStreamer to transcode audio stream.
+Therefore, GStreamer must be installed on your Opencast admin node.
+On Debian based systems, you can do that by running:
+
+```shell
+sudo apt-get install libgstreamer1.0-0 gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly
+```
+
+On Red Hat based systems, run:
+
+```shell
+sudo yum install gstreamer1 gstreamer1-plugins-base gstreamer1-plugins-good gstreamer1-plugins-bad-free gstreamer1-plugins-ugly-free
+```
+
+
+### Step 3: Configure the Microsoft Azure Transcription Service
+
+Edit _etc/org.opencastproject.transcription.microsoftazure.MicrosoftAzureTranscriptionServiec.cfg_:
+
+* Set _enabled_=true
+* Use service credentials obtained above to set _subscription.key_ and _region_
+* All other settings are optional and explained in the config file
+
+
+### Step 4: Add a workflow operations or create new workflow to start transcription
+
+The workflow below is a minimal working example for an event that has a video file in the `presenter/source` flavor.
+You do not necessarily need an extra workflow, and instead you can integrate the parts you need into your own. The
+relevant operations are `microsoft-azure-start-transcription` to start the transcription and `snapshot`, so a second
+workflow can retrieve the mediapackage to attach captions/transcriptions
+
+``` xml
+
+
+
+ microsoft-azure-transcription
+ Microsoft Azure Transcription Testing Workflow
+
+ upload
+ schedule
+ archive
+
+ 100
+
+ Microsoft Azure Transcription Testing Workflow
+
+
+
+
+
+
+
+ de-DE
+
+
+
+
+
+
+
+ captions/vtt+${language-code}
+ ${language-code}
+ presenter/source
+
+
+
+
+
+
+ */source
+ internal
+ http://localhost:8080/admin-ng/index.html#/events/events/${event_id}/tools/playback
+ false
+
+
+
+
+
+
+ dublincore/*,security/*,*/source
+ engage-download
+ engage-streaming
+ false
+
+
+
+
+
+
+
+ wf-properties/language
+ archive
+ language-code
+
+
+
+
+
+
+ */source,dublincore/*,security/*
+ archive
+
+
+
+
+
+
+ true
+
+ security/*
+
+
+
+
+
+
+
+```
+
+### Step 5: Add a workflow to attach transcriptions
+
+A sample attach workflow that works together with the workflow from Step 3. Attaches the generated transcription
+to the mediapackages and republishes it. Copy it into a new file under
+`etc/workflows/microsoft-azure-attach-transcripts.xml` in your Opencast installation.
+
+``` xml
+
+
+ microsoft-azure-attach-transcripts
+ Attach caption/transcripts generated by Microsoft Azure
+ Attach automated transcription generated by the Microsoft Azure service. This is an internal workflow, started by the Transcription Service.
+
+
+
+
+
+
+
+
+ wf-properties/language
+
+
+
+
+
+
+
+ ${transcriptionJobId}
+
+
+ captions/vtt+${language-code}
+ archive
+
+
+
+
+
+
+ dublincore/*,security/*,captions/*
+ merge
+ false
+
+
+
+
+
+
+ */*
+
+
+
+
+
+
+ true
+
+ security/*
+
+
+
+
+
+
+
+```
+
+Workflow Operations
+-------------------
+
+* [microsoft-azure-attach-transcription](../../workflowoperationhandlers/microsoft-azure-attach-transcription-woh.md)
+* [microsoft-azure-start-transcription](../../workflowoperationhandlers/microsoft-azure-start-transcription-woh.md)
\ No newline at end of file
diff --git a/docs/guides/admin/docs/modules/transcription.modules/vosk.md b/docs/guides/admin/docs/modules/transcription.modules/vosk.md
new file mode 100644
index 0000000000..9f9b096edf
--- /dev/null
+++ b/docs/guides/admin/docs/modules/transcription.modules/vosk.md
@@ -0,0 +1,20 @@
+Vosk Transcription Engine
+=========================
+
+Overview
+--------
+[Vosk](https://alphacephei.com/vosk/) is an offline open-source speech recognition toolkit. It enables speech recognition for 20+ languages.
+This engine is use by [SpeechToText WoH](../../workflowoperationhandlers/speech-to-text-woh.md)
+
+Enable Vosk in Opencast
+-----------------------
+
+Vosk is enabled by default in Opencast but it needs to be installed
+[vosk-cli](https://github.com/elan-ev/vosk-cli#installation) to work.
+
+Configure Vosk
+--------------
+
+The command that executes Vosk, the main STT engine or the job load can be modified in,
+`org.opencastproject.speechtotext.impl.SpeechToTextServiceImpl.cfg` and
+`org.opencastproject.speechtotext.impl.engine.VoskEngine.cfg`
diff --git a/docs/guides/admin/docs/modules/watsontranscripts.md b/docs/guides/admin/docs/modules/transcription.modules/watsontranscripts.md
similarity index 95%
rename from docs/guides/admin/docs/modules/watsontranscripts.md
rename to docs/guides/admin/docs/modules/transcription.modules/watsontranscripts.md
index 53f392f7e6..bc4f0c7684 100644
--- a/docs/guides/admin/docs/modules/watsontranscripts.md
+++ b/docs/guides/admin/docs/modules/transcription.modules/watsontranscripts.md
@@ -1,6 +1,9 @@
Transcripts (Automated by IBM Watson)
=====================================
+> Using this requires you to turn on an Opencast plugin.
+> Take a look [at the plugin management documentation](../plugin-management.md) to find out how you can do that.
+
Overview
--------
@@ -184,5 +187,5 @@ A sample one can be found in etc/workflows/retry-watson-transcripts.xml
Workflow Operations
-------------------
-* [start-watson-transcription](../workflowoperationhandlers/start-watson-transcription-woh.md)
-* [attach-watson-transcription](../workflowoperationhandlers/attach-watson-transcription-woh.md)
+* [start-watson-transcription](../../workflowoperationhandlers/start-watson-transcription-woh.md)
+* [attach-watson-transcription](../../workflowoperationhandlers/attach-watson-transcription-woh.md)
diff --git a/docs/guides/admin/docs/modules/transcription.modules/whisper.md b/docs/guides/admin/docs/modules/transcription.modules/whisper.md
new file mode 100644
index 0000000000..4d66399b62
--- /dev/null
+++ b/docs/guides/admin/docs/modules/transcription.modules/whisper.md
@@ -0,0 +1,38 @@
+Whisper Transcription Engine
+============================
+
+Overview
+--------
+
+Opencast can take advantage of [Open AI's Whisper Project]() to generate automatic transcriptions on premise through
+[SpeechToText WoH](../../workflowoperationhandlers/speech-to-text-woh.md).
+
+Advantages
+----------
+- Transcription on more than 80 languages
+- Fast processing (When using a GPU)
+- Run locally, no data sent to third parties.
+
+Enable Whisper engine
+---------------------
+To enable Whisper as for the `SpeechToText` WoH, follow these steps.
+
+1. [Install whisper](https://github.com/openai/whisper#setup) on the worker nodes.
+2. Enable whisper in `org.opencastproject.speechtotext.impl.SpeechToTextServiceImpl.cfg`.
+3. Set the target model to use in `org.opencastproject.speechtotext.impl.engine.WhisperEngine`.
+
+
+Additional Notes
+----------------
+
+- Whisper can be run on CPU or GPU, the use of a GPU increase the performance dramatically, it is strong recommended to
+use a GPU with this engine.
+- [There are five languages models available to use](https://github.com/openai/whisper#available-models-and-languages),
+from the lightest (tiny) to the most complete (large), having a
+bigger model improves the accuracy but diminishes the processing speed.
+
+#### Not yet implemented
+
+This is a list of features that are not implemented but are expected to be added in the near future.
+- Translation to english
+- Automatic language recognition and tagging
diff --git a/docs/guides/admin/docs/prereleases.md b/docs/guides/admin/docs/prereleases.md
new file mode 100644
index 0000000000..17383a078b
--- /dev/null
+++ b/docs/guides/admin/docs/prereleases.md
@@ -0,0 +1,49 @@
+# Prerelease Opencast Packages and Containers
+
+Shortly after a branch cut we start providing prerelease packages for the new branch. In general you can expect a new
+verison any time a pull request has been merged. This may be more than once a day, or it may be very rare late in the
+life cycle of a branch.
+
+Note: These packages come with *absolutely no support*, and may be broken at any time. Do not install these on
+anything other than a testing system. Do not feed the only copy of your recordings to these systems. These
+packages may break their host operating system, and may eat your dog. Do not feed these packages after midnight.
+
+
+Redhat Based Distributions
+--------------------------
+
+Add a repository configuration containing the following to `/etc/yum.repos.d/opencast-unstable.repo`. Note that the `el`
+version must match your distribution's version!
+
+ [opencast-unstable-noarch]
+ name = Opencast el 8 Repository - noarch
+ baseurl = http://ci.opencast.org/rpms/unstable/el/8/oc-{{ opencast_major_version() }}/noarch
+ enabled = 1
+ gpgcheck = 1
+ gpgkey = http://ci.opencast.org/keys/public-signing-key.gpg
+
+Note: This repo still requires the normal Opencast repository for dependencies (notably ffmpeg). Configuration for
+these packages should follow the [standard instructions](configuration/basic.md)
+
+Debian Based Distributions
+--------------------------
+
+First install the repository signing key with the following commands
+
+ curl http://ci.opencast.org/keys/public-signing-key.gpg | sudo gpg --no-default-keyring --keyring=/usr/share/keyrings/opencast-unstable.gpg --import -
+
+The insert the following into `/etc/apt/sources.list.d/opencast-unstable.list`
+
+ deb [signed-by=/usr/share/keyrings/opencast-unstable.gpg] http://ci.opencast.org/debian {{ opencast_major_version() }}.x unstable
+
+Note: This repo still requires the normal Opencast repository for dependencies (notably ffmpeg). Configuration for
+these packages should follow the [standard instructions](configuration/basic.md)
+
+Docker Images
+-------------
+
+All container images provide a `next` tag, e.g. `quay.io/opencast/allinone:next`. This version is a nightly build of the
+next upcoming major version. As such, it follows the latest release branch `r/Y.x` until `Y.0` is released. After that,
+it builds from `develop` until the next release branch is cut. This change is announced on list.
+
+Configuration for these images should follow the [standard instructions](configuration/basic.md)
diff --git a/docs/guides/admin/docs/releasenotes.md b/docs/guides/admin/docs/releasenotes.md
index 8702c332e2..92babc08c8 100644
--- a/docs/guides/admin/docs/releasenotes.md
+++ b/docs/guides/admin/docs/releasenotes.md
@@ -1,131 +1,109 @@
-# Opencast 11: Release Notes
-
-
-Features
---------
-
-- New Elasticsearch architecture, now there is one elastic search for the admin ui and the external api. This
- simplifies the maintenance and double the speed of index rebuild.
-- New *select-version* workflow operation handler, used to replace the media package in the currently
- running workflow with an older version from the asset manager.
-- Additional S3 distribution workflow operation handlers: *retract-partial-aws*, *publish-configure-aws*,
- *retract-configure-aws*
-- Wowza stream security configuration now allows the configuration "prefix:secret"
-- Allows upload of tracks (e.g. subtitles) as assets for new and existing
- events.
-
-Improvements
-------------
-
-- Save buttons for the metadata of existing series and events in the Admin UI.
-- Moved the configuration of the user interface configuration service (providing the /ui-config endpoint)
- from the global configuration to a service configuration file.
-- Extracting preview images are now from the source material instead, instead of processed files.
-- The groups are always updated regarded their user reference provider.
-- `execute-many` and `execute-once` now print all the output in the logs
-- Add support for `WebP` and `Advanced SubStation Alpha` mime types
-
-Behavior changes
------------------
-
-- There is now only one Elasticsearch index for both the Admin UI and the External API. Its structure is identical
- to the old Admin UI index, thus migration is possible, alternatively the index has to be rebuilt or the old Admin UI
- index can be configured (see upgrade guide).
- With this change the index rebuild should now be twice as fast as before. The index endpoints to clear and rebuild
- the index were moved to `/index`.
-- There is a completely new set of workflows. Please make sure to check your local configuration and adapt
- it accordingly if you made changes to your workflows before. Opencast will also continue to work with the old set of
- workflows. The new ones just remove a lot of redundancies, making the whole process more efficient.
- Some of the new workflows (e.g. `fast`) now use slightly different workflow configurations. This could potentially
- cause problems if you scheduled recordings using the old workflows but have the events processed using the new
- workflows. Please make sure the workflow you use work fine, or do not have anything scheduled via the upgrade.
-- Changes to the service registry config at `ServiceRegistryJpaImpl.cfg`:
- - The usage of `max.attempts` is modified in the sense that if you set -1, you can disable services going into error
- state completely. Before, this was equivalent to 0, which would have the service go into error state after one
- attempt, though this was undocumented. Check your configuration to be sure you didn't rely on this behavior.
- - `no.error.state.service.types` was added. With this, you can define service types that should never go into error
- state.
-- The default location of the user interface configuration service configuration is now
- `etc/org.opencastproject.uiconfig.UIConfigRest.cfg`. For more details, take a look at
- [pull request #2860](https://github.com/opencast/opencast/pull/2860).
-- There are changes to how hosts are mapped to tenants. If you use a multi-tenant system you therefore need to update
- your `org.opencastproject.organization-*.cfg` configuration files:
- Before Opencast 11 the domain names were mapped to tenants and a common port number was assumed for all domains. Now
- you need to configure a URL per instance you want to map to a tenant.
-```
-# Before:
-port=8080
-prop.org.opencastproject.host.admin.example.org=tenant1-admin.example.org
-prop.org.opencastproject.host.presentation.example.org=tenant1-presentation.example.org
-# Now:
-prop.org.opencastproject.host.admin.example.org=https://tenant1-admin.example.org
-prop.org.opencastproject.host.presentation.example.org=https://tenant1-presentation.example.org:8443
-```
-- Support for automatically setting up an HLS encoding ladder via the `{video,audio}.bitrates.mink`
- and `{video,audio}.bitrates.maxk` encoding profile options was removed. Instead, users should now explicitly specify
- the bit rate and bit rate control mechanism in the `ffmpeg.command`.
-- Some S3 distribution workflow operation handlers have been renamed: *publish-aws* to *publish-engage-aws* and
- *retract-aws* to *retract-engage-aws*.
-- The amount of job statistics for servers displayed in the admin interface was reduced to running and queued jobs to
- avoid performance problems and remove incorrect and/or misleading data.
-
-
-API changes
------------
-- [[#2814](https://github.com/opencast/opencast/pull/2814)] - Add track fields `is_master_playlist` and `is_live` to
- external API
-- [[#2878](https://github.com/opencast/opencast/pull/2878)] - Add endpoint to resume Index Rebuild for specified service
-- [[#3002](https://github.com/opencast/opencast/pull/3002)] - Sign publication URL of events in External API
-- [[#3148](https://github.com/opencast/opencast/pull/3148)] - Allow empty track duration
-
-Additional Notes about 11.3
----------------------------
-
-This release fixes several bugs and a security issue related to logging which was fixed in 10.9 and forward merged to
-this release (cf. [[#3305](https://github.com/opencast/opencast/pull/3305)]). A notable new feature is the
-`speechtotext` workflow operation introducing support for the STT Engine Vosk (cf. the
-[corresponding docs section](workflowoperationhandlers/speech-to-text-woh.md) and
-[[#2855](https://github.com/opencast/opencast/pull/2855)]). Additionally, the design of the embed code selection
-within the Admin UI was updated (cf. [[#3273](https://github.com/opencast/opencast/pull/3273)]). Furthermore,
-[[#3152](https://github.com/opencast/opencast/pull/3152)] and [[#3154](https://github.com/opencast/opencast/pull/3154)]
-introduced enhancements to the `execute-once` and `execute-many` workflow operations.
-
-Additional Notes about 11.2
----------------------------
-
-This release contains a security fix:
-
-- Further mitigation for Log4Shell (CVE-2021-45105)
-
-Like the previous release this is an out-of-order patch to address and resolve a further vulnerability discovered
-by security researchers. Unlike the previous release it not only provides an updated version of Pax Logging, but
-also entirely removes the replaced bundles from Opencast's assemblies to avoid confusion if people do find the old,
-vulnerable version of Log4J somewhere on the filesystem, even though it is not used.
-
-Additional Notes about 11.1
----------------------------
-
-This release contains an updated version of Pax Logging, which provides Opencast's Log4j functionality. Earlier
-versions are affected by the Log4Shell vulnerability, which was partially mitigated in 11.0 by
-[GHSA-mf4f-j588-5xm8](https://github.com/opencast/opencast/security/advisories/GHSA-mf4f-j588-5xm8). Further
-vulnerability discoveries by security researchers have rendered the previous mitigations ineffective. Normally
-we would wait for our underlying runtime (Apache Karaf) to update, however in light of the severity of these issues
-we have issued an out-of-order patch to address, and resolve, these concerns immediately.
+# Opencast 13: Release Notes
+
+
+Opencast 13.1
+-------------
+
+The first maintenance release of Opencast 13.
+
+- Bug fix: publish engage woh with merge SKIP the operation if media package not in search index
+([#4478](https://github.com/opencast/opencast/pull/4478))
+- Add silent detection based on subtitles (webvtt-to-cutmarks woh) ([#4482](https://github.com/opencast/opencast/pull/4482))
+- Fix: series deleted from search index cannot be re-added ([#4502](https://github.com/opencast/opencast/pull/4502))
+- Adds Whisper STT to SpeechToText WoH ([#4513](https://github.com/opencast/opencast/pull/4513))
+- Change default hotkeys for create dialogs in admin UI ([#4516](https://github.com/opencast/opencast/pull/4516))
+- Reduce number of snapshots taken in the new editor backend ([#4519](https://github.com/opencast/opencast/pull/4519))
+- Avoid using jobs in SeriesUpdatedEventHandler ([#4536](https://github.com/opencast/opencast/pull/4536))
+
+See [changelog](changelog.md) for a comprehensive list of changes.
+
+
+Opencast 13.0
+-------------
+
+### Features
+
+- New Plugin Management. Some parts of Opencast have become plugins and are now disabled by default but can be easily
+ enabled again by flipping a single configuration option. ([#3218](https://github.com/opencast/opencast/pull/3218))
+ For a list of plugins, take a look at
+ - `etc/org.opencastproject.plugin.impl.PluginManagerImpl.cfg` or the
+ - documentation: [The Plugin Management Documentation](modules/plugin-management.md)
+- Comments in the event index. Adds comment reason, text and resolvedStatus to the events index. This allows for
+ filtering events by certain comments in the Admin UI by using the searchbar. For example, if you are using the notes
+ column in the events table, you could search for all events that have a note that contains "silent". This requires
+ an index rebuild. ([#4029](https://github.com/opencast/opencast/pull/4029))
+- Support for f4v file type ([#4280](https://github.com/opencast/opencast/pull/4280))
+- Whisper as new Speech-To-Text engine. The new engine comes with additional configuration options and with a config
+ file to choose what model to use and the CLI command. ([#4513](https://github.com/opencast/opencast/pull/4513))
+- Specialist worker notes added. Adds the ability to define a list of worker nodes that gets preferred when dispatching
+ compilation jobs (Job Type: org.opencastproject.composer). This could for example be useful in a setup with one or
+ more GPU accelerated nodes. ([#3741](https://github.com/opencast/opencast/pull/3741))
+ This feature is disabled by default and only activated when a list of specialized worker nodes is set.
+ The comma-separated list of worker nodes is defined in the configuration file:
+ - `etc/org.opencastproject.serviceregistry.impl.ServiceRegistryJpaImpl.cfg`
+ To ensure backwards compatibility not defining a list of specialized worker nodes is safe and leaves the behavior of
+ the system unchanged.
+- The new `assert` workflow operation allows asserting that certain expressions are `true` or `false`. This replaces
+ the similar `failing` operation. ([#4358](https://github.com/opencast/opencast/pull/4358))
+
+### Improvements
+
+- Much faster fading effect for cuts from the video editor. ([#4013](https://github.com/opencast/opencast/pull/4013))
+- Default resolution of live schedule impl changed to standard 16:9 ([#4098](https://github.com/opencast/opencast/pull/4098))
+- JobDispatcher extracted from inside the ServiceRegistry into its own class. This makes the JobDispatcher a
+ configurable OSGi service, such that dispatching can be enabled or disabled during runtime. Also changes the
+ default job dispatch behaviour to not dispatch jobs, and alters the node profiles to enable it by default on
+ the expected nodes. This should not change current job dispatcher behaviour, aside from being able to enable
+ or disable job dispatch on the fly. ([#3607](https://github.com/opencast/opencast/pull/3607))
+- Multi-tenant clusters can now define a common metadata catalog per tenant. ([#4181](https://github.com/opencast/opencast/pull/4181))
+- PostgreSQL is no longer considered experimental and fully supported. ([#4359](https://github.com/opencast/opencast/pull/4359))
+- The `send-email` workflow operation now has the following improvements:
+ - Templates can now include values from all extended metadata catalogs. Previously, the flavor of the extended
+ catalog had to start with `dublincore/`. ([#4376](https://github.com/opencast/opencast/pull/4376))
+ - Templates can now include values from organization properties.
+ This can be useful for multi-tenant systems. ([#4380](https://github.com/opencast/opencast/pull/4380))
+ - `send-email` can now send multipart emails using text and HTML. ([#4408](https://github.com/opencast/opencast/pull/4408))
+- User details can now be mapped from LDAP attributes. ([#4440](https://github.com/opencast/opencast/pull/4440))
+
+
+### Behavior changes
+
+- Navigation shortcuts to switch tabs in modals for new events and new series in admin-ui. The combinations are:
+ `alt + enter` for next or - if applicable - the create button, and `alt + backspace` for the previous button
+ (alt == option on macOS). **Note**: Shortcuts will not be detected while `` or `
```css
diff --git a/docs/guides/developer/docs/modules/index.md b/docs/guides/developer/docs/modules/index.md
index 3ddbb0d41c..621c588f7d 100644
--- a/docs/guides/developer/docs/modules/index.md
+++ b/docs/guides/developer/docs/modules/index.md
@@ -10,11 +10,4 @@ or subsystems of Opencast.
- Capture Agent
- [Capture Agent](capture-agent/capture-agent.md)
- [Test Cases](capture-agent/testcases.md)
-- Player
- - [Architecture](player/architecture.md)
- - [Core Reference](player/core.reference.md)
- - [Events](player/events.md)
- - [Persistent local storage](player/storage.md)
- - [Create a new Plugin](player/plugin.development.md)
- - [Testing](player/testing.md)
- [Stream Security](stream-security.md)
diff --git a/docs/guides/developer/docs/modules/paella-player-7/index.md b/docs/guides/developer/docs/modules/paella-player-7/index.md
new file mode 100644
index 0000000000..c01d8855c0
--- /dev/null
+++ b/docs/guides/developer/docs/modules/paella-player-7/index.md
@@ -0,0 +1,71 @@
+
+# Paella Player 7 Opencast Module
+
+## Requisites
+
+Node.js version 14 or higher is required.
+
+## Debug and develop
+
+To debug Paella Player, a tool based on webpack debug server is provided, which allows to run Opencast through a proxy.
+
+### Install Paella Player in standalone mode
+
+First of all, install the Paella Player dependencies using npm:
+
+```sh
+cd [opencast-root]/modules/engage-paella-7
+npm ci
+```
+
+### Run Paella Player using the webpack proxy
+
+By default, Paella Player will point to `http://localhost:8080` to redirect all the requests to Opencast, so if you compile and run Opencast on your local machine. To do it, you simply have to execute the following npm command:
+
+```sh
+npm run dev
+```
+
+But you also can debug and develop Paella Player without having an Opencast installation on your local machine. To do it, simply specify the `server` environment variable when you launch the npm command:
+
+```sh
+npm run dev -- --env server=https://develop.opencast.org
+```
+
+### Run debugger
+
+You can debug access the webpack proxy using the `7070` port:
+
+```other
+http://localhost:7070/engage/ui/index.html
+```
+
+If Paella Player 7 is not the default player in your Opencast settings, you can access it using the following URL:
+
+```other
+http://localhost:7070/paella7/ui/watch.html?id=the-video-identifier
+```
+
+### Paella Player configuration
+
+The configuration files and their resources are located outside the Paella Player 7 module, in this location:
+
+```sh
+[opencast-root]/etc/ui-config/mh_default_org/paella7
+```
+
+### Check Paella Player code
+
+You can use the following npm commands to check your Paella Player code:
+
+```sh
+npm run eslint
+npm run html-linter
+npm run html-validate
+```
+
+Or you can use this command to execute all the previous commands together:
+
+```sh
+npm run check
+```
diff --git a/docs/guides/developer/docs/modules/player/architecture.md b/docs/guides/developer/docs/modules/player/architecture.md
deleted file mode 100644
index 931f8269ba..0000000000
--- a/docs/guides/developer/docs/modules/player/architecture.md
+++ /dev/null
@@ -1,193 +0,0 @@
-# Architecture
-
-## Overview
-
-The architecture of the theodul player has a plugin based structure based around a core. The core and the plugins have
-been realized as OSGi modules. Each plugin can be separately build.
-
-The following figure shows the OSGi architecture of the player.
-
-
-
-All Theodul OSGi modules are stored under:
-
- modules/engage-theodul-*
- #Core module
- modules/engage-theodul-api/
- modules/engage-theodul-core/
- #A plugin module
- modules/engage-theodul-plugin-*
- modules/engage-theodul-plugin-tab-description/
-
-## Plugin Manager
-
-The main workflow is implemented by the core, which recognizes new plugins, collects information about the plugin type
-and resources, runs the JavaScript logic and inserts the first compiled templates into the HTML DOM.
-
-The Plugin Manager Endpoint recognizes the OSGi modules. Each plugin has some information about its name and its
-resources. The Plugin Manager collects these information and publishes them via a REST endpoint. The following URL links
-to an example REST endpoint:
-
- http://localhost:8080/engage/theodul/manager/list.json
-
-The documentation and test forms of the endpoint can be found on the Opencast start page. The following data in JSON
-shows an example list of plugins, which are used by the player and provided by the Plugin Manager Endpoint.
-
- {
- "pluginlist":{
- "plugins":[
- {
- "name":"EngagePluginTabSlidetext",
- "id":"6",
- "description":"Simple implementation of a tab with the text of the slides",
- "static-path":"6\/static"
- },
- {
- "name":"EngagePluginControlsMockup",
- "id":"5",
- "description":"Simple implementation of a control bar",
- "static-path":"5\/static"
- }]
- }
- }
-
-Next to the Plugin Manager there is the Theodul Core module, which publishes the main HTML page, core.html.
-
-## UI Core
-
-The **core.html** is the main entry point and starts the Javascript core logic. Following listing shows the directory
-structure of core in the **engage-theodul-core OSGi** module.
-
- |-src
- |---main
- |-----java #Java impl of the plugin manager
- |-----resources
- |-------ui #UI of the core, core.html and engage_init.js
- |---------css #Global CSS Styles
- |---------js #JavaScript logic
- |-----------engage #Core logic, engage_core.js and engage_model.js
- |-----------lib #External libraries, backbone.js, jquery.js, require.js and underscore.js
- |---test #Unit Tests
- |-----resources
- |-------ui #JavaScript Unit Tests
- |---------js
- |-----------spec
-
-All Theodul JavaScript components are defined as a RequireJS module. The file `engage_init.js` is loaded firstly and
-contains the configuration of RequireJS. This init script additionally loads the core module, which is defined in the
-`engage_core.js`.
-
-The core module initializes the main HTML view. This view is realized as a BackboneJS view and is linked to a global
-Backbone model, which is stored in the model module in `engage_model.js`. The view is returned by the core module, so
-every other module, which has a dependency to the core module, has a reference to the view (simply called *Engage* in
-the plugins) and its functions. See the Core Reference for more information about the functions of the core view.
-
-## Plugins
-
-Plugins in the Theodul player are developed and distributed in own OSGi modules. Every plugin has a special UI type. In
-dependency of this type the core injects the plugin to the right position of the player. The following plugin types are
-possible:
-
-|Plugin Type|Description|Characteristics|Module Name|JS Plugin Type Name|Maven Plugin Type Name|
-|-----------|-----------|---------------|-----------|-------------------|----------------------|
-|Controls |Implements the main controls of the top of the player |Only one plugin per player possible. |engage-theodul-plugin-controls |engage_controls |controls|
-|Timeline |Timeline information below the main controls.|Good for processing time-based data like user tracking, slide previews or annotations.|Optional plugin, more than one possible. engage-theodul-plugin-timeline- |engage_timeline |timeline|
-|Videodisplay |Implementation of the video display. |Currently only one plugin per player possible, but in the future more video displays should be possible.|engage-theodul-plugin-video- |engage_video |video|
-|Description/Label |A plugin below the video display, good to show simple information about the video, like a title and the creator. |Only one plugin per player possible. |engage-theodul-plugin-description |engage_description |description|
-|Tab |Shows a tab in the tab view at the bottom of the player. |Optional plugin, more than one possible. |engage-theodul-plugin-tab- |engage_tab |tab|
-|Custom |A custom plugin without a relationship to an UI element.|Good for a custom REST endpoint, global data representation or to load custom JS code or libraries.|Optional plugin, more than one possible.|No connection to a preserved UI element.|engage-theodul-plugin-custom- |engage_custom |custom|
-
-The following listing shows the directory structure of a plugin module:
-
- |-src
- |---main
- |-----java
- |-------org
- |---------opencastproject
- |-----------engage
- |-------------theodul
- |---------------plugin
- |-----------------controls #Simple Java class, and optional REST endpoint
- |-----resources
- |-------OSGI-INF #OSGi information about the plugin
- |-------static #web ressources, contains the main.js entry point of the plugin
- |---------images #plugin ressources
- |---------js #plugin js libs
- |-----------bootstrap
- |-----------jqueryui
- |---test #Jasmine test ressources
- |-----resources
- |-------js
- |---------engage #Test Wrapper of the core
- |---------lib #Required test libs
- |---------spec #Jasmine test specs
-
-The main JavaScript entry point of the plugin is main.js in the static folder. This contains the RequireJS module
-definition of the plugin and the main logic. All other plugin logic can be implemented as a RequireJS module and loaded
-in the main module. The main module should have a dependency to the core, the Engage object. With this object you have
-access to main features of the core. See the Core Reference for more information about that.
-
-After the initialization process of the plugin, the plugin returns a plugin object with information about the plugin,
-like the type, the name, the ui template etc. This object is used by the core to decide about the UI type/location of
-plugin. The Core Reference describes the plugin object, before and after it is being processed by the core.
-
-Have a look to the code of a plugin to get an impression about the plugin implementation.
-
-## Model View Controller Support
-
-The Theodul player supports MVC design patterns for each plugin based on methods and objects of the BackboneJS library.
-It is not necessary to design a plugin in MVC style but it is highly recommended. An overview of the methods and objects
-of the BackboneJS library is listed on the official website of BackboneJS.
-
-Each plugin with a visual component has a reference to its view container and its template to fill the view container.
-Have a look at the Core Reference how to access the container and the template data. With this information the plugin
-can create a Backbone view with a reference to the to div container and a render function to compile the template.
-
-The next step is the creation of a model, which is being bound to the view. An usual way is to create a Backbone model,
-which is being passed by the view. In the initialization function of the view, the view binds the model change event to
-his render function:
-
-*Bind the "change" event always to the render function of a view*
-
- // bind the render function always to the view
- _.bindAll(this, "render");
- // listen for changes of the model and bind the render function to this
- this.model.bind("change", this.render);
-
-The model can only be visible by the plugin itself or it can be added to the global Engage model of the core. Adding the
-model to the Engage model has the advantage, that on the one hand data can be used by other plugins and on the other
-hand it is able to listen to change- or add-events. So other plugins are able to listen to a change of data in another
-model and can react to it by e.g. re-render its view. This feature is e.g. used by the "mhConnection" custom plugin. The
-plugin receives data of Opencast endpoints and saves them to a model, which is being added to the Engage Model. Each
-time the plugin gets newer endpoint data and updates its model's data, each plugin gets a notification and can re-render
-its view.
-
-A typical way to add a model to the Engage model is to add the model in the initialization function of the plugin after
-all other initializations. Here is an example of the video plugin:
-
-### Add a custom model to the Engage Model
-
- Engage.model.set("videoDataModel", new VideoDataModel(videoDisplays, videoSources, duration));
-
-In the same initialization function an event handler should be added to notice the addition of the model. Has the model
-successfully been added, a view with this model and other data can be created:
-
-*Model Event Handler*
-
- Engage.model.on("change:videoDataModel", function() {
- new VideoDataView(this.get("videoDataModel"), plugin.template, videojs_swf);
- });
-
-If another plugin wants to use the defined "videoDataModel" model, it has to list it in its own initialization process:
-
- Engage.model.on("change:videoDataModel", function() {
- initCount -= 1;
- if (initCount === 0) {
- initPlugin();
- }
- });
-
-Have a look at the full implementation of the VideoJS Plugin and the Controls Plugin to get an idea how the Backbone MVC
-design works. For completeness' sake, the "Controller" does not have an extra Object in the Backbone MVC design. The
-"Controller" is usually used as the render function in the view. This function can be very complex and should link to
-other functions, which are short and easy to be tested by the Jasmine Test Framework.
diff --git a/docs/guides/developer/docs/modules/player/architecture.png b/docs/guides/developer/docs/modules/player/architecture.png
deleted file mode 100644
index aa431eadfc..0000000000
Binary files a/docs/guides/developer/docs/modules/player/architecture.png and /dev/null differ
diff --git a/docs/guides/developer/docs/modules/player/core.reference.md b/docs/guides/developer/docs/modules/player/core.reference.md
deleted file mode 100644
index 9da7a3b643..0000000000
--- a/docs/guides/developer/docs/modules/player/core.reference.md
+++ /dev/null
@@ -1,62 +0,0 @@
-# Core Reference
-
-## Engage Core
-*RequireJS Path*
-
- 'engage/engage_core'
-
-Inherited object functions of the BackboneJS view, see http://backbonejs.org/#View
-
-Added object functions and properties:
-
-|Name|Parameters|Type|Description|
-|----|----------|----|-----------|
-|log(value):void |value:String |function |function to log via the core cross browser|
-|Event:EngageEvent|none |property |Returns the EngageEvent object prototype, the see EngageEvent Object for more information|
-|trigger(event):void |event:EngageEvent |function |triggers an EngageEvent|
-|on(event, handler, context):void |event:EngageEvent, handler:function, context:object|function |install an event handler on a EngageEvent|
-|model:EngageModel |none |property |Returns the singleton engage model for this session, see EngageModel for more information's|
-|getPluginPath(pluginName):String |pluginName:String |function |Returns the absolute path of a plugin by name.|
-
-## EngageEvent Object
-
-|Name|Paramters|Type|Description|
-|----|---------|----|-----------|
-|EngageEvent(name, description, type) |name:String, description:String, type:String | constructor |Create a new unbound EngageEvent, with a name, description and a type. For Example: var myEvent = new EngageEvent('play', 'plays the video', 'trigger')|
-|getName:String |none |function |Gets the name|
-|getDescription:String |none |function |Gets the description|
-|getType:String |none |function |Gets the Type, can be a "handler", "trigger" or "both"|
-|toString:String |none |function |Build a string that describes the event|
-
-## Engage Model
-
-Inherited object functions of the BackboneJS model, see http://backbonejs.org/#Model, how to use BackboneJS models. This
-model is a global singleton object and can be used by each plugin to add new models which can be used by another plugin
-again.
-
-No special functions are added, but the model is filled with some default data. This default data can be used by each
-plugin, which has a reference to the EngageModel.
-
-
-|Property Name|Type|Description|
-|-------------|----|-----------|
-|pluginsInfo |Backbone Model |Contains Information's of each plugin|
-|pluginModels |Backbone Collection |Contains the plugin models|
-|urlParameters |Object |Contains the data of the URL parameters.|
-
-## Plugin Object
-
-Each plugin **must** create and return a object with some properties which are set by the plugin itself. It is recommend
-to keep a reference to the object because some properties are set by the core after the plugin is processed.
-
-|Property Name|Type|Description|
-|-------------|----|-----------|
-|name |String |Name of the plugin, e.g. "Engage Controls". **This property is set by the plugin.**|
-|type |String |Type of the plugin, e.g. "engage_controls", see the plugin table in Architecture for the other plugin types. **This property is set by the plugin.**|
-|version |String |Version of plugin. **This property is set by the plugin.**|
-|styles |Array of Strings |Array of the paths of css files relative to the static folder of each plugin . **This property is set by the plugin.**|
-|template |String |Before the plugin object is returned by the plugin logic, the template property contains the path to the template relative to the static folder. **The path property is set first by the plugin**. After the plugin object is returned and the Theodul core processed the plugin, the template property is filled with the real template data and can be used to re-render the view.|
-|container |String |Contains the ID of the HTML div container, which contains the rendered template. This can be used to re-render the view. **This property is set by the core.**|
-|pluginPath |String |Contains the absolute path of the plugin. **This property is set by the core.**|
-|events |Object |Contains all events which are used of this plugin. Each handled and each triggered event.|
-
diff --git a/docs/guides/developer/docs/modules/player/events.md b/docs/guides/developer/docs/modules/player/events.md
deleted file mode 100644
index 484222c94b..0000000000
--- a/docs/guides/developer/docs/modules/player/events.md
+++ /dev/null
@@ -1,96 +0,0 @@
-# Theodul Pass Player - Events
-
-A Theodul Pass Player plugin can trigger and/or subscribe to events.
-
-An event is defined in the events section of the plugin and looks like this:
-
- NAME: new Engage.Event("MODULE:NAME", "DESCRIPTION", "OPTION")
-
-The event has the event name "MODULE:NAME", the description DESCRIPTION and one of the options "trigger", "handler" or
-"both" as OPTION. When the plugin just triggers the event, the option is "trigger", when it just handles the events the
-option is "handler" and when it does both - trigger and handle it - the option is "both".
-
-An event can be triggered via
-
- Engage.trigger(plugin.events.NAME.getName(), [parameter(s)]);
-
-and can be subscribed to via
-
- Engage.on(plugin.events.NAME.getName(), function () {});
-
-The following list contains all events of the Core + of all official plugins, sorted alphabetically after "Event name"
-for version 1.0 of Feb 12, 2015.
-
-Currently official plugins are
-
-* Controls
-* MHConnection
-* Notifications
-* Usertracking
-* Description
-* Description (Tab)
-* Slide text (Tab)
-* Shortcuts (Tab)
-* Timeline statistics
-* Videodisplay
-
-|Name | Event name | Additional parameters|Description|Triggered in|Handled in|
-|-----|------------|----------------------|-----------|------------|----------|
-|coreInit |Core:init | | |Core| |
-|plugin_load_done |Core:plugin_load_done | | |Core|Core, Controls, MHConnection, Notifications, Usertracking, Description, Description (Tab), Slide text (Tab), Shortcuts (Tab), Timeline statistics, Videodisplay|
-|timelineplugin_closed |Engage:timelineplugin_closed |*Note: No "Engage Event", just use as string, example: Engage.on("Engage:timelineplugin_closed", function() {});*| when the timeline plugin container closed |Core| |
-|timelineplugin_opened |Engage:timelineplugin_opened |*Note: No "Engage Event", just use as string, example: Engage.on("Engage:timelineplugin_opened", function() {});* |when the timeline plugin container opened |Core|Timeline statistics|
-|getMediaInfo |MhConnection:getMediaInfo| | | |MHConnection|
-|getMediaPackage |MhConnection:getMediaPackage| | | |MHConnection|
-|mediaPackageModelError |MhConnection:mediaPackageModelError | | |MHConnection| Core, Controls, Notifications, Usertracking, Description, Description (Tab), Slide text (Tab), Shortcuts (Tab), Timeline statistics, Videodisplay|
-|customError |Notification:customError |msg: The message to display |an error occurred | Core, Controls, Videodisplay| Notifications|
-|customNotification |Notification:customNotification |msg: The message to display |a custom message | Videodisplay| Notifications|
-|customOKMessage |Notification:customOKMessage | msg: The message to display | a custom message with an OK button |Controls | Notifications |
-|customSuccess |Notification:customSuccess |msg: The message to display |a custom success message |Core, Controls| Notifications|
-|segmentMouseout |Segment:mouseOut |no: Segment number |the mouse is off a segment |Controls, Slide text (Tab)| Controls, Slide text (Tab)|
-|segmentMouseover |Segment:mouseOver |no: Segment number |the mouse is over a segment |Controls, Slide text (Tab)| Controls, Slide text (Tab)|
-|sliderMousein |Slider:mouseIn | |the mouse entered the slider |Controls| |
-|sliderMouseout |Slider:mouseOut | |the mouse is off the slider |Controls | |
-|sliderMousemove |Slider:mouseMoved |timeInMs: The time on the hovered position in ms |the mouse is moving over the slider | Controls | |
-|sliderStart |Slider:start | |slider started |Controls| |
-|sliderStop |Slider:stop |time: The time the slider stopped at | slider stopped |Controls|Videodisplay|
-|aspectRatioSet |Video:aspectRatioSet |as: (array) as[0] = width, as[1] = height, as[2] = aspect ratio in %|the aspect ratio has been calculated |Videodisplay|Controls|
-|audioCodecNotSupported |Video:audioCodecNotSupported | |when the audio codec seems not to be supported by the browser | Videodisplay |Notifications|
-|autoplay |Video:autoplay | |autoplay the video |Core| Videodisplay|
-|bufferedAndAutoplaying |Video:bufferedAndAutoplaying | |buffering successful, was playing, autoplaying now |Videodisplay |Notifications|
-|bufferedButNotAutoplaying |Video:bufferedButNotAutoplaying | |buffering successful, was not playing, not autoplaying now |Videodisplay |Notifications|
-|buffering |Video:buffering | |video is buffering |Videodisplay|Notifications|
-|ended |Video:ended |triggeredByMaster: Whether or not the event has been triggered by master |video ended |Videodisplay|Controls|
-|fullscreenCancel |Video:fullscreenCancel | |cancel fullscreen |Controls, Videodisplay|Videodisplay|
-|fullscreenChange |Video:fullscreenChange | |a fullscreen change happened |Videodisplay|Controls|
-|fullscreenEnable |Video:fullscreenEnable | |enable fullscreen |Controls, Core| Controls, Videodisplay|
-|isAudioOnly |Video:isAudioOnly |audio: true if audio only, false else |whether it's audio only or not | Videodisplay|Controls, Notifications|
-|initialSeek |Video:initialSeek |time: The time to seek to |Seeks initially after all plugins have been loaded after a short delay | Core| Videodisplay|
-|mute |Video:mute | |mute |Videodisplay|Videodisplay|
-|muteToggle |Video:muteToggle | |toggle mute and unmute | Core|Videodisplay|
-|nextChapter |Video:nextChapter | | Core | |
-|numberOfVideodisplaysSet |Video:numberOfVideodisplaysSet |no: Number of videodisplays |the number of videodisplays has been set |Videodisplay| |
-|pause |Video:pause |triggeredByMaster: Whether or not the event has been triggered by master |pauses the video
-|Core, Controls, Videodisplay| Controls, Videodisplay|
-|play |Video:play |triggeredByMaster: Whether or not the event has been triggered by master |plays the video |Core, Controls, Videodisplay| Controls,Videodisplay |
-|playPause |Video:playPause | | |Core|Videodisplay|
-|previousChapter |Video:previousChapter | | |Core| |
-|playbackRateChanged |Video:playbackRateChanged |rate: The video playback rate (0.0-x, default: 1.0) |The video playback rate changed |Controls| Controls, Videodisplay|
-|playbackRateIncrease |Video:playbackRateIncrease | | |Core|Videodisplay|
-|playbackRateDecrease |Video:playbackRateDecrease | | |Core|Videodisplay|
-|playerLoaded |Video:playerLoaded | | player loaded successfully |Videodisplay| |
-|ready |Video:ready | |all videos loaded successfully |Videodisplay| Controls, Notifications|
-|seek |Video:seek |time: Current time in seconds seek video to a given position in seconds |Core, Controls, Slide text (Tab)|Videodisplay |
-|seekLeft |Video:seekLeft | | |Core|Videodisplay|
-|seekRight |Video:seekRight | | |Core|Videodisplay|
-|synchronizing |Video:synchronizing | |synchronizing videos with the master video |Videodisplay| |
-|timeupdate |Video:timeupdate |time: Current time in seconds, triggeredByMaster: Whether or not the event has been triggered by master|a timeupdate happened |Videodisplay| Controls, Usertracking|
-|qualitySet |Video:qualitySet |quality: the quality that has been set a video quality has been set |Controls|Videodisplay|
-|unmute |Video:unmute | |unmute |Controls|Controls|
-|usingFlash |Video:usingFlash |flash: true if flash is being used, false else |flash is being used |Videodisplay|Controls|
-|videoFormatsFound |Video:videoFormatsFound |format: array of video formats if different video formats (qualities) have been found |Videodisplay|Controls|
-|volumechange |Video:volumechange |vol: Current volume (0 is off (muted), 1.0 is all the way up, 0.5 is half way) | a volume change happened |Videodisplay| |
-|volumeDown |Video:volumeDown | | |Core|Controls|
-|volumeGet |Video:volumeGet |callback: A callback function with the current volume as a parameter |get the volume | Videodisplay|
-|volumeSet |Video:volumeSet |percentAsDecimal: Volume to set (0 is off (muted), 1.0 is all the way up, 0.5 is half way) |set the volume |Controls|Controls, Videodisplay|
-|volumeUp |Video:volumeUp | | |Core|Controls|
diff --git a/docs/guides/developer/docs/modules/player/plugin.development.md b/docs/guides/developer/docs/modules/player/plugin.development.md
deleted file mode 100644
index 95f09218a5..0000000000
--- a/docs/guides/developer/docs/modules/player/plugin.development.md
+++ /dev/null
@@ -1,148 +0,0 @@
-# How To Create A New Plugin
-
-## Plugin Archetype
-
-The [Maven Archetype Plugin](http://maven.apache.org/archetype/maven-archetype-plugin/) provides a convenient mechanism
-for automatically generating projects. Project templates are called Archetypes and they are basically maven artifacts of
-a special kind of packaging, ‘maven-archetype’.
-
-With the Theodul Plugin Archetype you can create a new plugin project in no time and start writing the plugin’s business
-logic right away, without caring about the POM or SCR component declarations.
-
-### Installation
-
-The Theodul Plugin Archetype is included in the Opencast source code (Theodul Player branch) in the modules directory.
-To make the artifact available on your system you need to install it like any other atrifacts. In the Opencast source
-directory type:
-
- > cd modules/engage-theodul-plugin-archetype
- > mvn install
-
-After successful build and installation the archetype is available in your system.
-
-### Generating a new plugin
-
-To generate a new plugin project simply go to the modules directory inside the Opencast source directory and type:
-
- > mvn archetype:generate -DarchetypeGroupId=org.opencastproject -DarchetypeArtifactId=theodul-plugin
-
-Provided the archetype is installed maven will now ask you for the properties configuration for the new project:
-
- [INFO] Generating project in Interactive mode
- [INFO] Archetype [org.opencastproject:theodul-plugin:1.5-SNAPSHOT] found in catalog local
- Define value for property 'groupId': : org.opencastproject
- Define value for property 'artifactId': : engage-theodul-plugin-test
- Define value for property 'version': 1.0-SNAPSHOT: : 1.5-SNAPSHOT
- Define value for property 'package': org.opencastproject: : org.opencastproject.engage.theodul.plugin.custom.test
- Define value for property 'plugin_description': : A test plugin
- Define value for property 'plugin_name': : testName
- Define value for property 'plugin_type': : custom
- Define value for property 'plugin_version': : 0.1
- Define value for property 'plugin_rest': : false
- Confirm properties configuration:
- groupId: org.opencastproject
- artifactId: engage-theodul-plugin-test
- version: 1.5-SNAPSHOT
- package: org.opencastproject.engage.theodul.plugin.test
- plugin_description: A test plugin
- plugin_name: test
- plugin_rest: true
- Y: : y
- [INFO] ----------------------------------------------------------------------------
- [INFO] Using following parameters for creating project from Archetype: theodul-plugin:1.5-SNAPSHOT
- [INFO] ----------------------------------------------------------------------------
- [INFO] Parameter: groupId, Value: org.opencastproject
- [INFO] Parameter: artifactId, Value: engage-theodul-plugin-test
- [INFO] Parameter: version, Value: 1.5-SNAPSHOT
- [INFO] Parameter: package, Value: org.opencastproject.engage.theodul.plugin.test
- [INFO] Parameter: packageInPathFormat, Value: org/opencastproject/engage/theodul/plugin/test
- [INFO] Parameter: package, Value: org.opencastproject.engage.theodul.plugin.test
- [INFO] Parameter: version, Value: 1.5-SNAPSHOT
- [INFO] Parameter: plugin_description, Value: A test plugin
- [INFO] Parameter: plugin_name, Value: test
- [INFO] Parameter: groupId, Value: org.opencastproject
- [INFO] Parameter: plugin_rest, Value: true
- [INFO] Parameter: artifactId, Value: engage-theodul-plugin-test
- [INFO] project created from Archetype in dir: /home/wulff/code/UOS/plugin-archetype/test/engage-theodul-plugin-test
- [INFO] ------------------------------------------------------------------------
- [INFO] BUILD SUCCESS
- [INFO] ------------------------------------------------------------------------
- [INFO] Total time: 3:39.195s
- [INFO] Finished at: Thu Jan 23 15:48:37 CET 2014
- [INFO] Final Memory: 15M/308M
- [INFO] ------------------------------------------------------------------------
-
-There you go, the newly created plugin project is waiting to be filled with life in the directory that is named after
-the atrifactId you entered before.
-
-### Project Properties
-
-In addition to the above explanation, here is a description of the properties you have to specify when generating a new
-project with the Theodul Plugin Archetype:
-
-#### groupId
-
-Maven group ID. For the Opencast developers this is
-
- org.opencastproject
-
-#### artifactId
-
-Maven artifact ID. Name by which your project is identified as an artifact by maven. Think of it as the project name. It
-will also be used as the name for your projects root directory. During the course of the Theodul project the following
-naming scheme came up:
-
- engage-theodul-plugin--
-
-#### version
-
-The project version. For Opencast developers: simply put in the version of the Opencast source tree your are working
-on.
-
-#### package
-
-The Java package in which the source for the back end part of your plugin will live. The following scheme is used by the
-Theodul developers:
-
- org.opencastproject.engage.theodul.plugin..
-
-#### plugin_version
-
-The version of the plugin itself. This is not to be confused with the maven project version which will, for instance, be
-updated when the Opencast version changes.
-
-#### plugin_type
-
-The type of the plugin to be created. See https://opencast.jira.com/wiki/display/MH/Architecture
-Possible types are: custom, controls, timeline, video, description, tab
-
-#### plugin_name
-
-The name by which your plugin will be registered by the plugin manager when running.
-
-#### plugin_description
-
-(optional) A short description of the plugin. The description will be provided by the [plugin list endpoint
-](https://engagedevcamp.wordpress.com/2013/04/15/plugin-infrastructure/) together with the other plugin data.
-
-#### plugin_rest
-
-(boolean) Whether or not the plugin should provide a Opencast Rest endpoint. If set to true, the Java class that makes
-up the back end part of your plugin will be augmented with the annotations necessary to work as a Rest endpoint provider
-in Opencast. Also an example endpoint (GET:sayHello) will be generated.
-
-
-## Example Plugin
-Have a look at the [snow showcase example plugin (custom)](https://bitbucket.org/CallToPower/theodul-snowshowcase-plugin).
-
-## Debugging
-To display debug information in the developer console, add the following parameters to the URL:
-
-**Display debug information**
-
- &debug=true
-
-**Display event debug information**
-
- &debugEvents=true
-
diff --git a/docs/guides/developer/docs/modules/player/storage.md b/docs/guides/developer/docs/modules/player/storage.md
deleted file mode 100644
index eaef49559b..0000000000
--- a/docs/guides/developer/docs/modules/player/storage.md
+++ /dev/null
@@ -1,28 +0,0 @@
-# How to store data in the browser persistently
-
-The Theodul Pass Player uses basil.js for storing persistent data such as the volume and the playback rate.
-
-Basil.js unifies localstorage, cookies and session storage and provides an easy-to-use JavaScript API.
-
-## Example Usage
-
-In your plugin you just have to require the basil lib which is being distributed globally:
-
- define([..., "basil", ...], function(..., Basil, ...) {
- ...
- }
-
-After that basil needs to be set up:
-
- var basilOptions = {
- namespace: 'mhStorage'
- };
- Basil = new window.Basil(basilOptions);
-
-The default plugins have "mhStorage" as their namespace, feel free to set your own. The default storage is the
-localstorage; if the localstorage is not available, a cookie is being used and so on.
-
-After setting up basil, the usage is straightforward:
-
- Basil.set("someKey", "someValue); // set a value
- Basil.get("someKey"); // get a value
diff --git a/docs/guides/developer/docs/modules/player/testing.md b/docs/guides/developer/docs/modules/player/testing.md
deleted file mode 100644
index e25b46c486..0000000000
--- a/docs/guides/developer/docs/modules/player/testing.md
+++ /dev/null
@@ -1,238 +0,0 @@
-# How To Test With Phantom.js and Jasmine
-
-## Integration Of Jasmine Into The Build Process (Maven)
-
-[Jasmine](http://pivotal.github.com/jasmine/) is integrated with the
-[jasmine-maven-plugin](http://pivotal.github.com/jasmine/) into the maven build process. Therefore only the pom.xml file
-will be enhanced by the following code, which specifies the [jasmine-maven-plugin](http://pivotal.github.com/jasmine/)
-as plugin for the build process. The configuration of the jasmine-maven-plugin is also done in this file. The meaning of
-every configuration parameter can be looked up on the jasmine-maven-plugin project page under this
-[link](http://searls.github.io/jasmine-maven-plugin/bdd-mojo.html). The following configuration uses a the
-specRunnerTemplate `REQUIRE_JS` in order to function properly with [RequireJS](http://requirejs.org/). Further
-information about spec runner templates can be found
-[here](http://searls.github.io/jasmine-maven-plugin/spec-runner-templates.html). On the next build the needed
-dependencies will be automatically resolved just like it is in the nature of maven.
-
-**pom.xml**
-
-
-
- ...
-
- com.github.searls
- jasmine-maven-plugin
- 1.3.1.2
-
-
-
- test
-
-
-
-
-
- ${project.basedir}/src/test/resources/js/lib/require.js
-
- ${project.basedir}/src/main/resources/static
-
- **/*.js
- **/*.coffee
-
- ${project.basedir}/src/test/resources/js/spec
-
- **/spec_helper.js
- **/*.js
- **/*.coffee
-
- REQUIRE_JS
- progress
-
-
-
-
-
-## Testing The Engage Core
-This chapter gives an overview over the directory structure used for testing the theodul engage core module, the
-configuration for the specs in the **spec_helper.js** and how to write specs for the core.
-
-### Directory Structure
-The test relevant files are located in the **src/test/resources/ui/js/spec** tree. Files that filename ends on
-**_spec.js** are considered as files with executable tests. The **spec_helper.js** in configured in the **pom.xml** for
-the initial setup.
-
-**Directory Structure Testing Engage Core**
-
- |-src
- |---main
- |-----java #Java impl of the plugin manager
- |-----resources
- |-------ui #UI of the core, core.html and engage_init.js
- |---------css #Global CSS Styles
- |---------js #JavaScript logic
- |-----------engage #Core logic, engage_core.js and engage_model.js
- |-----------lib #External libraries, backbone.js, jquery.js, require.js and underscore.js
- |---test #Unit Tests
- |-----resources
- |-------ui #JavaScript Unit Tests
- |---------js
- |-----------spec #Tests the *_spec.js and the helper file spec_helper.js
-
-### Spec Helper
-The file **spec_helper.js** takes over the configuration of RequireJS which is usually done by the `engage_init.js`. The
-paths differ slighty from the player has at runtime.
-
-**spec_helper for engage_core module**
-
- /*global requirejs*/
- requirejs.config({
- baseUrl: 'src/js/lib',
- paths: {
- require: 'require',
- jquery: 'jquery',
- underscore: 'underscore',
- backbone: 'backbone',
- engage: '../engage',
- plugins: '../engage/plugin/*/static'
- },
- shim: {
- 'backbone': {
- //script dependencies
- deps: ['underscore', 'jquery'],
- //global variable
- exports: 'Backbone'
- },
- 'underscore': {
- //global variable
- exports: '_'
- }
- }
- });
- var PLUGIN_MANAGER_PATH = '/engage/theodul/manager/list.json';
- var PLUGIN_PATH = '/engage/theodul/plugin/';
-
-
-## Testing Engage Plugins
-
-This chapter gives an overview over the directory structure used for testing a theodul engage plugin module, the
-configuration for the specs in the `spec_helper.js` and how to write specs for a plugin.
-
-### Directory Structure
-
-The test relevant files are located in the **src/test/resources/ui/js/spec** tree. Files that filename ends on
-**_spec.js** are considered as files with executable tests. The **spec_helper.js** in configured in the **pom.xml** for
-the initial setup. In the directory **test/resources/ui/js/engage** is a mockup of the theodul engage core module in
-order to be able to test the plugin module independent. The directory **test/resources/ui/js/lib** provides the
-libraries which are provides by the engage core module at runtime of the player, as well to be able to test the plugin
-module independently.
-
-**Directory Structure Testing Plugins**
-
- |-src
- |---main
- |-----java #Java impl of the plugin manager
- |-----resources
- |-------ui #UI of the core, core.html and engage_init.js
- |---------css #Global CSS Styles
- |---------js #JavaScript logic
- |-----------engage #Core logic, engage_core.js and engage_model.js
- |-----------lib #External libraries, backbone.js, jquery.js, require.js and underscore.js
- |---test #Unit Tests
- |-----resources
- |-------ui #JavaScript Unit Tests
- |---------js
- |-----------engage #Mockup of the engage_core.js and engage_model.js
- |-----------lib #Libraries used and provided by the core (A copy of the lib directory in the engage core module)
- |-----------spec #Tests the *_spec.js and the helper file spec_helper.js
-
-### Spec Helper
-The file **spec_helper.js** takes over the configuration of RequireJS which is usually done by the `engage_init.js`. The
-paths differ slighty from the player uses at runtime.
-
- /*global requirejs*/
- requirejs.config({
- baseUrl: 'src/',
- paths: {
- require: 'test/resources/js/lib/require',
- jquery: 'test/resources/js/lib/jquery',
- underscore: 'test/resources/js/lib/underscore',
- backbone: 'test/resources/js/lib/backbone',
- engage: 'test/resources/js/engage'
- },
- shim: {
- 'backbone': {
- //script dependencies
- deps: ['underscore', 'jquery'],
- //global variable
- exports: 'Backbone'
- },
- 'underscore': {
- //global variable
- exports: '_'
- }
- }
- });
-
-### Writing Specs
-TODO
-
-## Running The Tests
-
-Now you can start the build process and the jasmine specs will be executed. Each . stands for a successful test. F
-stands for a failure and will stop the build process like it is specified in the configuration. The example output shows
-a manipulated version of the tests for the theodul engage core in order to illustrate a failing test. Normally all three
-tests should succeed at this point.
-
-**Testing on build**
-
- mvn install -DdeployTo=${FELIX_HOME}
- // some output before
- [INFO]
- -------------------------------------------------------
- J A S M I N E S P E C S
- -------------------------------------------------------
- [INFO]
- F..
-
- 1 failure:
-
- 1.) EngageCore it should have a model <<< FAILURE!
-
- * Expected { cid : 'c3', ... _pending : false } not to be defined.
-
- Results: 3 specs, 1 failures
- // some output before
-
-The jasmine-maven-plugin can also be executed manually and show the result in a browser. This can be achieved by the
-following command:
-
-**Manual testing**
-
- mvn jasmine:bdd
- [INFO] Scanning for projects...
- [INFO]
- [INFO] ------------------------------------------------------------------------
- [INFO] Building engage-theodul-core 1.5-SNAPSHOT
- [INFO] ------------------------------------------------------------------------
- [INFO]
- [INFO] --- jasmine-maven-plugin:1.3.1.2:bdd (default-cli) @ engage-theodul-core ---
- 2014-01-28 14:33:30.722:INFO:oejs.Server:jetty-8.1.10.v20130312
- 2014-01-28 14:33:30.746:INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:8234
- [INFO]
-
- Server started--it's time to spec some JavaScript! You can run your specs as you develop by visiting this URL in
- a web browser:
-
- http://localhost:8234
-
- The server will monitor these two directories for scripts that you add, remove, and change:
-
- source directory: src/main/resources/ui
-
- spec directory: src/test/resources/ui/js/spec
-
- Just leave this process running as you test-drive your code, refreshing your browser window to re-run your specs.
- You can kill the server with Ctrl-C when you're done.
-
-In a browser you should see an output like it is shown on the next screenshot.
-
-
diff --git a/docs/guides/developer/docs/modules/player/testing.png b/docs/guides/developer/docs/modules/player/testing.png
deleted file mode 100644
index 9d90e3d7b1..0000000000
Binary files a/docs/guides/developer/docs/modules/player/testing.png and /dev/null differ
diff --git a/docs/guides/developer/docs/proposal-log.md b/docs/guides/developer/docs/proposal-log.md
index d93e58f0ea..ec3d365d71 100644
--- a/docs/guides/developer/docs/proposal-log.md
+++ b/docs/guides/developer/docs/proposal-log.md
@@ -9,6 +9,88 @@ The following list contains a list of passed proposals for reference.
Passed Proposals
----------------
+### Deprecate Theodul with Opencast 12
+Proposed by Greg Logan , passed on Fri, July 1 2022
+```no-highlight
+Hi all,
+
+After a discussion today at the technical meeting, I'm going to propose
+deprecating Theodul with Opencast 12. It's no longer the default, and actually
+causes problems in some situations[1]. It's also no longer being developed.
+If this passes then Theodul could be removed from the codebase with Opencast
+13. If this is a problem for your installation, now would be the time to speak
+up!
+
+Proposal closes EOD 2022-07-01
+
+G
+
+1: https://github.com/opencast/opencast/issues/1749
+```
+
+Note: Deprecation actually happened in Opencast 13, with removal in Opencast 14.
+
+### Opensearch Support
+Proposed by Greg Logan , passed on Wed, June 22 2022
+```no-highlight
+Hi all,
+
+As we probably all know, Elasticsearch did some goofy things with their
+licensing, and a fork (Opensearch) ended up starting up. Opensearch 1.x is
+protocol compatible with Elasticsearch 7 series releases, of which 7.10.2
+appears to be the last one with the older license. There is an Opensearch 2.x
+branch which is not compatible[1].
+
+Since long term we're probably going to be migrating to Opensearch, and
+Opensearch is drop-in compatible I'm going to file a pull request with the
+appropriate bits to enable proper testing going forward. The pull request for
+this is forthcoming.
+
+I'm also going to #propose that we add formal support for Opensearch to
+Opencast 12.0, deprecate Elasticsearch support in Opencast 13.0, and finally
+remove it in Opencast 14.0. This gives us the motivation to get 2.x support
+going sooner than later so we don't get hugely behind, while also giving us
+fallback where we can stick to an older version of Opensearch if we don't
+actually get that done.
+
+Proposal closes END 2022-06-22
+
+G
+
+1: https://opensearch.org/faq/#q1.9, also personal testing
+```
+
+### Drop official MySQL support
+Proposed by Lars Kiesow , passed on Wed, February 16 2022
+
+```no-highlight
+Hi everyone,
+since I'm testing database things once again, I noticed that more and
+more our infrastructure is set-up to test with MariaDB (or now
+PostegreSQL) and no longer with MySQL. We have MySQL left in none of our
+deployments and I feel like something could break compatibility at any
+moment right now and no one would notice during a release cycle.
+
+Overall, the situation is similar to back when we decided to no longer
+officially support PostgreSQL. It technically works and should continue
+to work, but no developers actually test against it and it could easily
+break without someone noticing.
+
+
+That is why, similar to the old decision, I would like to #propose to:
+
+- officially mark MySQL it as unsupported
+- explain that it should technically work, but we do not test it
+- explain that the set-up should be similar to MariaDB but may differ
+ slightly and we have no documentation for that
+
+
+Of course, also similar to PostgreSQL, we can always decide to support
+it again later, if interest picks up and the database landscape changes.
+
+–Lars
+```
+
### PR and release process changes
Proposed by Greg Logan , passed on Thu, 17 Jun 2021
diff --git a/docs/guides/developer/docs/release-manager.md b/docs/guides/developer/docs/release-manager.md
index 692d4a9411..771b09a373 100644
--- a/docs/guides/developer/docs/release-manager.md
+++ b/docs/guides/developer/docs/release-manager.md
@@ -19,6 +19,26 @@ meetings. It is important to note that, while release managers drive the release
charge of both the work and the decision making, meaning that votes and successful proposals from this body take
precedence over release manager decisions.
+Recommended practices for release managers
+------------------------------
+
+This is a recommendation of best practices to help to organize the duties of the release managers after they have been choosen
+these recomendations came from the experience of past release managers.
+
+### After the election of the release manager
+- Create a draft pull request for the release notes early
+- Create a draft article as a draft opencast.org Wordpress.
+- Create draft slides for presentation in summits and adopters meetings
+
+### After the end or begining of each month
+- Check the merged pull requests
+ - Update the release notes (If necessary)
+ - Add any missing tag from each pull request
+- Update the slides (If necessary)
+
+### After the end of translation week
+- Add/Remove languages acording the translation criteria
+
Responsibilities
----------------
@@ -68,27 +88,49 @@ Example on how to create the Opencast 7 release branch:
git checkout develop
git pull develop
-2. Make sure you did not modify any files. If you did, stash those changes:
+2. Modify the Paella target branch (For Paella 6.x and 7.x), found in the dependabot configuration
+ file `.github/dependabot.yml` to target the latest supported version when this version will released.
+
+ Example:
+ - package-ecosystem: npm
+ directory: "/modules/engage-paella-player-7"
+ schedule:
+ interval: daily
+ target-branch: "r/12.x"
+ open-pull-requests-limit: 10
+
+ to
+
+ - package-ecosystem: npm
+ directory: "/modules/engage-paella-player-7"
+ schedule:
+ interval: daily
+ target-branch: "r/13.x"
+ open-pull-requests-limit: 10
+
+ make a PR then merge this change to `develop` branch.
+
+3. Make sure you did not modify any files. If you did, stash those changes:
git status # check for modified files
git stash # stash them if necessary
-3. Create and push the new release branch:
+4. Create and push the new release branch:
git checkout -b r/7.x
git push r/7.x
-4. That is it for the release branch. Now update the versions in `develop` in preparation for the next release:
+5. That is it for the release branch. Now update the versions in `develop` in preparation for the next release:
git checkout develop
mvn versions:set -DnewVersion=8-SNAPSHOT versions:commit
-5. Have a look at the changes. Make sure that nothing else was modified:
+6. Have a look at the changes. Make sure that nothing else was modified:
git diff
git status | grep modified: | grep -v pom.xml # this should have no output
-6. If everything looks fine, commit the changes and push it to the community repository:
+7. If everything looks fine, commit the changes and push it to the community repository:
git add $(git status | grep 'modified:.*pom.xml' | awk '{print $2;}')
git commit -s -m 'Bumping pom.xml Version Numbers'
@@ -103,10 +145,13 @@ To: dev@opencast.org
Subject: Release Branch for Opencast Cut
Hi everyone,
-the Opencast release branch (r/) has been
-cut. Pull requests for bug fixes may still be made against
-this branch but, as usual, features should go into develop
-instead.
+the Opencast release branch (r/.x) has been
+cut. Please check if pull requests point to the correct branch.
+
+For a guide on what you can still add to release branches, please refer to
+
+ https://docs.opencast.org/develop/developer/development-process/#acceptance-criteria-for-patches-in-different-versions
+
Remember the release schedule for this release:
@@ -325,7 +370,7 @@ The following steps outline the necessary steps for cutting the final release:
git push 6.0:6.0
-8 Check the “Create new release” GitHub Actions workflow.
+8. Check the “Create new release” GitHub Actions workflow.
It will automatically build and upload the release tarballs and create a new release draft.
Once it is finished, review the draft, adjust the description and publish the release.
diff --git a/docs/guides/developer/mkdocs.yml b/docs/guides/developer/mkdocs.yml
index 7c07f96cc0..71b91e75b5 100644
--- a/docs/guides/developer/mkdocs.yml
+++ b/docs/guides/developer/mkdocs.yml
@@ -2,8 +2,11 @@ site_name: Developer Guide
repo_url: https://github.com/opencast/opencast
edit_uri: edit/develop/docs/guides/developer/docs/
-markdown_extensions:
- - markdown_inline_graphviz
+plugins:
+ - search:
+ - mermaid2:
+ arguments:
+ theme: neutral
# Default theme used is windmill
theme: windmill
@@ -77,13 +80,7 @@ nav:
- Capture Agent: 'modules/capture-agent/capture-agent.md'
- Input Selection: modules/capture-agent/capture-agent-input.md
- Test Cases: 'modules/capture-agent/testcases.md'
- - Player:
- - Architecture: 'modules/player/architecture.md'
- - Core Reference: 'modules/player/core.reference.md'
- - Events: 'modules/player/events.md'
- - Storage: 'modules/player/storage.md'
- - Plugin Development: 'modules/player/plugin.development.md'
- - Testing: 'modules/player/testing.md'
+ - Paella Player 7: 'modules/paella-player-7/index.md'
- Stream Security: 'modules/stream-security.md'
- OAI-PMH: 'modules/oaipmh.md'
- Infrastructure:
@@ -105,3 +102,4 @@ nav:
- Data Types: 'api/types.md'
- Glossary: 'api/glossary.md'
- Configure a Local Cluster for Testing: local-cluster.md
+- Explore H2 Database: explore-h2-database.md
diff --git a/docs/guides/package-lock.json b/docs/guides/package-lock.json
index 568d144c74..95fa8e7fea 100644
--- a/docs/guides/package-lock.json
+++ b/docs/guides/package-lock.json
@@ -6,7 +6,7 @@
"": {
"name": "docs",
"devDependencies": {
- "markdownlint-cli": "^0.31.1"
+ "markdownlint-cli": "^0.33.0"
}
},
"node_modules/argparse": {
@@ -22,30 +22,23 @@
"dev": true
},
"node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
+ "balanced-match": "^1.0.0"
}
},
"node_modules/commander": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-9.0.0.tgz",
- "integrity": "sha512-JJfP2saEKbQqvW+FI93OYUB4ByV5cizMpFMiiJI8xDbBvQvSkIk0VvQdn1CZ8mqAO8Loq2h0gYTYtDFUZUeERw==",
+ "version": "9.4.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz",
+ "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==",
"dev": true,
"engines": {
"node": "^12.20.0 || >=14"
}
},
- "node_modules/concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
- "dev": true
- },
"node_modules/deep-extend": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
@@ -56,10 +49,13 @@
}
},
"node_modules/entities": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
- "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz",
+ "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==",
"dev": true,
+ "engines": {
+ "node": ">=0.12"
+ },
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
@@ -67,7 +63,7 @@
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
"dev": true
},
"node_modules/get-stdin": {
@@ -83,29 +79,28 @@
}
},
"node_modules/glob": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
- "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
+ "version": "8.0.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz",
+ "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==",
"dev": true,
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
- "minimatch": "^3.0.4",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
+ "minimatch": "^5.0.1",
+ "once": "^1.3.0"
},
"engines": {
- "node": "*"
+ "node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/ignore": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
- "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
+ "version": "5.2.4",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
+ "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
"dev": true,
"engines": {
"node": ">= 4"
@@ -114,7 +109,7 @@
"node_modules/inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"dev": true,
"dependencies": {
"once": "^1.3.0",
@@ -128,12 +123,12 @@
"dev": true
},
"node_modules/ini": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz",
- "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-3.0.0.tgz",
+ "integrity": "sha512-TxYQaeNW/N8ymDvwAxPyRbhMBtnEwuvaTYpOQkFx1nSeusgezHniEc/l35Vo4iCq/mMiTJbpD7oYxN98hFlfmw==",
"dev": true,
"engines": {
- "node": ">=10"
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
}
},
"node_modules/js-yaml": {
@@ -149,29 +144,29 @@
}
},
"node_modules/jsonc-parser": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz",
- "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
+ "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
"dev": true
},
"node_modules/linkify-it": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
- "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz",
+ "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==",
"dev": true,
"dependencies": {
"uc.micro": "^1.0.1"
}
},
"node_modules/markdown-it": {
- "version": "12.3.2",
- "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
- "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==",
+ "version": "13.0.1",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz",
+ "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==",
"dev": true,
"dependencies": {
"argparse": "^2.0.1",
- "entities": "~2.1.0",
- "linkify-it": "^3.0.1",
+ "entities": "~3.0.1",
+ "linkify-it": "^4.0.1",
"mdurl": "^1.0.1",
"uc.micro": "^1.0.5"
},
@@ -180,98 +175,82 @@
}
},
"node_modules/markdownlint": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.25.1.tgz",
- "integrity": "sha512-AG7UkLzNa1fxiOv5B+owPsPhtM4D6DoODhsJgiaNg1xowXovrYgOnLqAgOOFQpWOlHFVQUzjMY5ypNNTeov92g==",
+ "version": "0.27.0",
+ "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.27.0.tgz",
+ "integrity": "sha512-HtfVr/hzJJmE0C198F99JLaeada+646B5SaG2pVoEakLFI6iRGsvMqrnnrflq8hm1zQgwskEgqSnhDW11JBp0w==",
"dev": true,
"dependencies": {
- "markdown-it": "12.3.2"
+ "markdown-it": "13.0.1"
},
"engines": {
- "node": ">=12"
+ "node": ">=14.18.0"
}
},
"node_modules/markdownlint-cli": {
- "version": "0.31.1",
- "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.31.1.tgz",
- "integrity": "sha512-keIOMwQn+Ch7MoBwA+TdkyVMuxAeZFEGmIIlvwgV0Z1TGS5MxPnRr29XCLhkNzCHU+uNKGjU+VEjLX+Z9kli6g==",
+ "version": "0.33.0",
+ "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.33.0.tgz",
+ "integrity": "sha512-zMK1oHpjYkhjO+94+ngARiBBrRDEUMzooDHBAHtmEIJ9oYddd9l3chCReY2mPlecwH7gflQp1ApilTo+o0zopQ==",
"dev": true,
"dependencies": {
- "commander": "~9.0.0",
+ "commander": "~9.4.1",
"get-stdin": "~9.0.0",
- "glob": "~7.2.0",
- "ignore": "~5.2.0",
+ "glob": "~8.0.3",
+ "ignore": "~5.2.4",
"js-yaml": "^4.1.0",
- "jsonc-parser": "~3.0.0",
- "markdownlint": "~0.25.1",
- "markdownlint-rule-helpers": "~0.16.0",
- "minimatch": "~3.0.5",
- "run-con": "~1.2.10"
+ "jsonc-parser": "~3.2.0",
+ "markdownlint": "~0.27.0",
+ "minimatch": "~5.1.2",
+ "run-con": "~1.2.11"
},
"bin": {
"markdownlint": "markdownlint.js"
},
"engines": {
- "node": ">=12"
+ "node": ">=14"
}
},
- "node_modules/markdownlint-rule-helpers": {
- "version": "0.16.0",
- "resolved": "https://registry.npmjs.org/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.16.0.tgz",
- "integrity": "sha512-oEacRUVeTJ5D5hW1UYd2qExYI0oELdYK72k1TKGvIeYJIbqQWAz476NAc7LNixSySUhcNl++d02DvX0ccDk9/w==",
- "dev": true
- },
"node_modules/mdurl": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
- "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=",
+ "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==",
"dev": true
},
"node_modules/minimatch": {
- "version": "3.0.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz",
- "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==",
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.2.tgz",
+ "integrity": "sha512-bNH9mmM9qsJ2X4r2Nat1B//1dJVcn3+iBLa3IgqJ7EbGaDNepL9QSHOxN4ng33s52VMMhhIfgCYDk3C4ZmlDAg==",
"dev": true,
"dependencies": {
- "brace-expansion": "^1.1.7"
+ "brace-expansion": "^2.0.1"
},
"engines": {
- "node": "*"
+ "node": ">=10"
}
},
"node_modules/minimist": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
- "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
+ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
"dev": true
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dev": true,
"dependencies": {
"wrappy": "1"
}
},
- "node_modules/path-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/run-con": {
- "version": "1.2.10",
- "resolved": "https://registry.npmjs.org/run-con/-/run-con-1.2.10.tgz",
- "integrity": "sha512-n7PZpYmMM26ZO21dd8y3Yw1TRtGABjRtgPSgFS/nhzfvbJMXFtJhJVyEgayMiP+w/23craJjsnfDvx4W4ue/HQ==",
+ "version": "1.2.11",
+ "resolved": "https://registry.npmjs.org/run-con/-/run-con-1.2.11.tgz",
+ "integrity": "sha512-NEMGsUT+cglWkzEr4IFK21P4Jca45HqiAbIIZIBdX5+UZTB24Mb/21iNGgz9xZa8tL6vbW7CXmq7MFN42+VjNQ==",
"dev": true,
"dependencies": {
"deep-extend": "^0.6.0",
- "ini": "~2.0.0",
- "minimist": "^1.2.5",
+ "ini": "~3.0.0",
+ "minimist": "^1.2.6",
"strip-json-comments": "~3.1.1"
},
"bin": {
@@ -299,7 +278,7 @@
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"dev": true
}
},
@@ -317,25 +296,18 @@
"dev": true
},
"brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"requires": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
+ "balanced-match": "^1.0.0"
}
},
"commander": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-9.0.0.tgz",
- "integrity": "sha512-JJfP2saEKbQqvW+FI93OYUB4ByV5cizMpFMiiJI8xDbBvQvSkIk0VvQdn1CZ8mqAO8Loq2h0gYTYtDFUZUeERw==",
- "dev": true
- },
- "concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "version": "9.4.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz",
+ "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==",
"dev": true
},
"deep-extend": {
@@ -345,15 +317,15 @@
"dev": true
},
"entities": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
- "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz",
+ "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==",
"dev": true
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
"dev": true
},
"get-stdin": {
@@ -363,29 +335,28 @@
"dev": true
},
"glob": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
- "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
+ "version": "8.0.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz",
+ "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
- "minimatch": "^3.0.4",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
+ "minimatch": "^5.0.1",
+ "once": "^1.3.0"
}
},
"ignore": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
- "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
+ "version": "5.2.4",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
+ "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
"dev": true
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"dev": true,
"requires": {
"once": "^1.3.0",
@@ -399,9 +370,9 @@
"dev": true
},
"ini": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz",
- "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-3.0.0.tgz",
+ "integrity": "sha512-TxYQaeNW/N8ymDvwAxPyRbhMBtnEwuvaTYpOQkFx1nSeusgezHniEc/l35Vo4iCq/mMiTJbpD7oYxN98hFlfmw==",
"dev": true
},
"js-yaml": {
@@ -414,111 +385,98 @@
}
},
"jsonc-parser": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz",
- "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
+ "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
"dev": true
},
"linkify-it": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
- "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz",
+ "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==",
"dev": true,
"requires": {
"uc.micro": "^1.0.1"
}
},
"markdown-it": {
- "version": "12.3.2",
- "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
- "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==",
+ "version": "13.0.1",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz",
+ "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==",
"dev": true,
"requires": {
"argparse": "^2.0.1",
- "entities": "~2.1.0",
- "linkify-it": "^3.0.1",
+ "entities": "~3.0.1",
+ "linkify-it": "^4.0.1",
"mdurl": "^1.0.1",
"uc.micro": "^1.0.5"
}
},
"markdownlint": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.25.1.tgz",
- "integrity": "sha512-AG7UkLzNa1fxiOv5B+owPsPhtM4D6DoODhsJgiaNg1xowXovrYgOnLqAgOOFQpWOlHFVQUzjMY5ypNNTeov92g==",
+ "version": "0.27.0",
+ "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.27.0.tgz",
+ "integrity": "sha512-HtfVr/hzJJmE0C198F99JLaeada+646B5SaG2pVoEakLFI6iRGsvMqrnnrflq8hm1zQgwskEgqSnhDW11JBp0w==",
"dev": true,
"requires": {
- "markdown-it": "12.3.2"
+ "markdown-it": "13.0.1"
}
},
"markdownlint-cli": {
- "version": "0.31.1",
- "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.31.1.tgz",
- "integrity": "sha512-keIOMwQn+Ch7MoBwA+TdkyVMuxAeZFEGmIIlvwgV0Z1TGS5MxPnRr29XCLhkNzCHU+uNKGjU+VEjLX+Z9kli6g==",
+ "version": "0.33.0",
+ "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.33.0.tgz",
+ "integrity": "sha512-zMK1oHpjYkhjO+94+ngARiBBrRDEUMzooDHBAHtmEIJ9oYddd9l3chCReY2mPlecwH7gflQp1ApilTo+o0zopQ==",
"dev": true,
"requires": {
- "commander": "~9.0.0",
+ "commander": "~9.4.1",
"get-stdin": "~9.0.0",
- "glob": "~7.2.0",
- "ignore": "~5.2.0",
+ "glob": "~8.0.3",
+ "ignore": "~5.2.4",
"js-yaml": "^4.1.0",
- "jsonc-parser": "~3.0.0",
- "markdownlint": "~0.25.1",
- "markdownlint-rule-helpers": "~0.16.0",
- "minimatch": "~3.0.5",
- "run-con": "~1.2.10"
+ "jsonc-parser": "~3.2.0",
+ "markdownlint": "~0.27.0",
+ "minimatch": "~5.1.2",
+ "run-con": "~1.2.11"
}
},
- "markdownlint-rule-helpers": {
- "version": "0.16.0",
- "resolved": "https://registry.npmjs.org/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.16.0.tgz",
- "integrity": "sha512-oEacRUVeTJ5D5hW1UYd2qExYI0oELdYK72k1TKGvIeYJIbqQWAz476NAc7LNixSySUhcNl++d02DvX0ccDk9/w==",
- "dev": true
- },
"mdurl": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
- "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=",
+ "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==",
"dev": true
},
"minimatch": {
- "version": "3.0.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz",
- "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==",
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.2.tgz",
+ "integrity": "sha512-bNH9mmM9qsJ2X4r2Nat1B//1dJVcn3+iBLa3IgqJ7EbGaDNepL9QSHOxN4ng33s52VMMhhIfgCYDk3C4ZmlDAg==",
"dev": true,
"requires": {
- "brace-expansion": "^1.1.7"
+ "brace-expansion": "^2.0.1"
}
},
"minimist": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
- "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
+ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
"dev": true
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dev": true,
"requires": {
"wrappy": "1"
}
},
- "path-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
- "dev": true
- },
"run-con": {
- "version": "1.2.10",
- "resolved": "https://registry.npmjs.org/run-con/-/run-con-1.2.10.tgz",
- "integrity": "sha512-n7PZpYmMM26ZO21dd8y3Yw1TRtGABjRtgPSgFS/nhzfvbJMXFtJhJVyEgayMiP+w/23craJjsnfDvx4W4ue/HQ==",
+ "version": "1.2.11",
+ "resolved": "https://registry.npmjs.org/run-con/-/run-con-1.2.11.tgz",
+ "integrity": "sha512-NEMGsUT+cglWkzEr4IFK21P4Jca45HqiAbIIZIBdX5+UZTB24Mb/21iNGgz9xZa8tL6vbW7CXmq7MFN42+VjNQ==",
"dev": true,
"requires": {
"deep-extend": "^0.6.0",
- "ini": "~2.0.0",
- "minimist": "^1.2.5",
+ "ini": "~3.0.0",
+ "minimist": "^1.2.6",
"strip-json-comments": "~3.1.1"
}
},
@@ -537,7 +495,7 @@
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"dev": true
}
}
diff --git a/docs/guides/package.json b/docs/guides/package.json
index e204bd8405..4cb79a4c28 100644
--- a/docs/guides/package.json
+++ b/docs/guides/package.json
@@ -2,7 +2,7 @@
"name": "docs",
"private": true,
"devDependencies": {
- "markdownlint-cli": "^0.31.1"
+ "markdownlint-cli": "^0.33.0"
},
"scripts": {
"test": "markdownlint *.md ./admin/**/*.md ./developer/**/*.md ../../*.md ../scripts/**/*md"
diff --git a/docs/guides/requirements.txt b/docs/guides/requirements.txt
index c743c7f341..5d2fce8e96 100644
--- a/docs/guides/requirements.txt
+++ b/docs/guides/requirements.txt
@@ -1,6 +1,4 @@
mkdocs
mkdocs-windmill
-markdown_inline_graphviz_extension
-markdown-inline-graphviz-extension-png
mkdocs-mermaid2-plugin
mkdocs-macros-plugin
diff --git a/docs/scripts/activemq/activemq.xml b/docs/scripts/activemq/activemq.xml
deleted file mode 100644
index fd5cade21a..0000000000
--- a/docs/scripts/activemq/activemq.xml
+++ /dev/null
@@ -1,164 +0,0 @@
-
-
-
-
-
-
-
- file:${activemq.conf}/credentials.properties
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/docs/scripts/devel-dependency-containers/docker-compose-all-sql.yml b/docs/scripts/devel-dependency-containers/docker-compose-all-sql.yml
index 684fd6bd5e..ccd7d5fed1 100644
--- a/docs/scripts/devel-dependency-containers/docker-compose-all-sql.yml
+++ b/docs/scripts/devel-dependency-containers/docker-compose-all-sql.yml
@@ -1,21 +1,19 @@
version: '2'
services:
elasticsearch:
- container_name: opencast-elasticsearch
- image: docker.elastic.co/elasticsearch/elasticsearch:7.10.2
+ container_name: opencast-opensearch
+ image: opensearchproject/opensearch:1
ports:
- 127.0.0.1:9200:9200
- 127.0.0.1:9300:9300
environment:
- discovery.type: single-node
- ES_JAVA_OPTS: '-Dlog4j2.formatMsgNoLookups=true'
- activemq:
- container_name: opencast-activemq
- image: quay.io/lkiesow/activemq
- ports:
- - 127.0.0.1:61616:61616
- volumes:
- - ../activemq/activemq.xml:/activemq-opencast.tpl.xml:ro
+ - cluster.name=opensearch-cluster
+ - node.name=opensearch-node1
+ - bootstrap.memory_lock=true # along with the memlock settings below, disables swapping
+ - "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" # minimum and maximum Java heap size, recommend setting both to 50% of system RAM
+ - "DISABLE_INSTALL_DEMO_CONFIG=true" # disables execution of install_demo_configuration.sh bundled with security plugin, which installs demo certificates and security configurations to OpenSearch
+ - "DISABLE_SECURITY_PLUGIN=true" # disables security plugin entirely in OpenSearch by setting plugins.security.disabled: true in opensearch.yml
+ - "discovery.type=single-node" # disables bootstrap checks that are enabled when network.host is set to a non-loopback address
postgresql:
container_name: opencast-postgresql
image: docker.io/library/postgres:13.2
diff --git a/docs/scripts/devel-dependency-containers/docker-compose-mariadb.yml b/docs/scripts/devel-dependency-containers/docker-compose-mariadb.yml
index dff8886d2f..ab86b6f88a 100644
--- a/docs/scripts/devel-dependency-containers/docker-compose-mariadb.yml
+++ b/docs/scripts/devel-dependency-containers/docker-compose-mariadb.yml
@@ -1,21 +1,19 @@
version: '2'
services:
elasticsearch:
- container_name: opencast-elasticsearch
- image: docker.elastic.co/elasticsearch/elasticsearch:7.10.2
+ container_name: opencast-opensearch
+ image: opensearchproject/opensearch:1
ports:
- 127.0.0.1:9200:9200
- 127.0.0.1:9300:9300
environment:
- discovery.type: single-node
- ES_JAVA_OPTS: '-Dlog4j2.formatMsgNoLookups=true'
- activemq:
- container_name: opencast-activemq
- image: quay.io/lkiesow/activemq
- ports:
- - 127.0.0.1:61616:61616
- volumes:
- - ../activemq/activemq.xml:/activemq-opencast.tpl.xml:ro
+ - cluster.name=opensearch-cluster
+ - node.name=opensearch-node1
+ - bootstrap.memory_lock=true # along with the memlock settings below, disables swapping
+ - "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" # minimum and maximum Java heap size, recommend setting both to 50% of system RAM
+ - "DISABLE_INSTALL_DEMO_CONFIG=true" # disables execution of install_demo_configuration.sh bundled with security plugin, which installs demo certificates and security configurations to OpenSearch
+ - "DISABLE_SECURITY_PLUGIN=true" # disables security plugin entirely in OpenSearch by setting plugins.security.disabled: true in opensearch.yml
+ - "discovery.type=single-node" # disables bootstrap checks that are enabled when network.host is set to a non-loopback address
mariadb:
container_name: opencast-mariadb
image: docker.io/library/mariadb:10.5.9
diff --git a/docs/scripts/devel-dependency-containers/docker-compose-postgresql.yml b/docs/scripts/devel-dependency-containers/docker-compose-postgresql.yml
index bdcf9063a4..2bbd66d5ba 100644
--- a/docs/scripts/devel-dependency-containers/docker-compose-postgresql.yml
+++ b/docs/scripts/devel-dependency-containers/docker-compose-postgresql.yml
@@ -1,21 +1,19 @@
version: '2'
services:
elasticsearch:
- container_name: opencast-elasticsearch
- image: docker.elastic.co/elasticsearch/elasticsearch:7.10.2
+ container_name: opencast-opensearch
+ image: opensearchproject/opensearch:1
ports:
- 127.0.0.1:9200:9200
- 127.0.0.1:9300:9300
environment:
- discovery.type: single-node
- ES_JAVA_OPTS: '-Dlog4j2.formatMsgNoLookups=true'
- activemq:
- container_name: opencast-activemq
- image: quay.io/lkiesow/activemq
- ports:
- - 127.0.0.1:61616:61616
- volumes:
- - ../activemq/activemq.xml:/activemq-opencast.tpl.xml:ro
+ - cluster.name=opensearch-cluster
+ - node.name=opensearch-node1
+ - bootstrap.memory_lock=true # along with the memlock settings below, disables swapping
+ - "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" # minimum and maximum Java heap size, recommend setting both to 50% of system RAM
+ - "DISABLE_INSTALL_DEMO_CONFIG=true" # disables execution of install_demo_configuration.sh bundled with security plugin, which installs demo certificates and security configurations to OpenSearch
+ - "DISABLE_SECURITY_PLUGIN=true" # disables security plugin entirely in OpenSearch by setting plugins.security.disabled: true in opensearch.yml
+ - "discovery.type=single-node" # disables bootstrap checks that are enabled when network.host is set to a non-loopback address
postgresql:
container_name: opencast-postgresql
image: docker.io/library/postgres:13.2
diff --git a/docs/scripts/devel-dependency-containers/docker-compose.yml b/docs/scripts/devel-dependency-containers/docker-compose.yml
index de8e962d7b..16772ed4e0 100644
--- a/docs/scripts/devel-dependency-containers/docker-compose.yml
+++ b/docs/scripts/devel-dependency-containers/docker-compose.yml
@@ -1,18 +1,16 @@
version: '2'
services:
elasticsearch:
- container_name: opencast-elasticsearch
- image: docker.elastic.co/elasticsearch/elasticsearch:7.10.2
+ container_name: opencast-opensearch
+ image: opensearchproject/opensearch:1
ports:
- 127.0.0.1:9200:9200
- 127.0.0.1:9300:9300
environment:
- discovery.type: single-node
- ES_JAVA_OPTS: '-Dlog4j2.formatMsgNoLookups=true'
- activemq:
- container_name: opencast-activemq
- image: quay.io/lkiesow/activemq
- ports:
- - 127.0.0.1:61616:61616
- volumes:
- - ../activemq/activemq.xml:/activemq-opencast.tpl.xml:ro
+ - cluster.name=opensearch-cluster
+ - node.name=opensearch-node1
+ - bootstrap.memory_lock=true # along with the memlock settings below, disables swapping
+ - "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" # minimum and maximum Java heap size, recommend setting both to 50% of system RAM
+ - "DISABLE_INSTALL_DEMO_CONFIG=true" # disables execution of install_demo_configuration.sh bundled with security plugin, which installs demo certificates and security configurations to OpenSearch
+ - "DISABLE_SECURITY_PLUGIN=true" # disables security plugin entirely in OpenSearch by setting plugins.security.disabled: true in opensearch.yml
+ - "discovery.type=single-node" # disables bootstrap checks that are enabled when network.host is set to a non-loopback address
diff --git a/docs/scripts/devel-dependency-containers/readme.md b/docs/scripts/devel-dependency-containers/readme.md
index 9be5699bdb..015e2a0818 100644
--- a/docs/scripts/devel-dependency-containers/readme.md
+++ b/docs/scripts/devel-dependency-containers/readme.md
@@ -29,12 +29,3 @@ podman-compose -f docker-compose-postgresql.yml up -d
No persistence for any data is configured so that you always start with a clean system for development and testing.
-
-SELinux
--------
-
-Make sure to label the ActiveMQ configuration file for container usage:
-
-```sh
-chcon -Rt container_file_t ../activemq/activemq.xml
-```
diff --git a/docs/upgrade/11_to_12/workflows_mariadb.py b/docs/upgrade/11_to_12/workflows_mariadb.py
new file mode 100644
index 0000000000..3f6356d85c
--- /dev/null
+++ b/docs/upgrade/11_to_12/workflows_mariadb.py
@@ -0,0 +1,385 @@
+# Upgrade script for MariaDB databases
+# Requires Python3 to run
+# Required packages:
+# $ pip install mysql_connector_python==8.0.29
+# NOTE: Please don't install version 8.0.30 of the mysql-connector-python module,
+# because the script runs into errors. Newer versions were not tested yet.
+# Set vars to point to your database
+# Run on commandline: "python3 workflow_db_upgrade.py"
+# WARNING: THIS SCRIPT DELETES DATA. CREATE A BACKUP BEFORE RUNNING
+
+# Module Imports
+import mysql.connector
+import xml.etree.ElementTree as ET
+from datetime import datetime
+
+# Vars
+user = "opencast"
+password = "dbpassword"
+host = "127.0.0.1"
+port = 3306
+database = "opencast"
+
+# Constants
+workflow_table_name = "oc_workflow"
+workflow_configuration_table_name = "oc_workflow_configuration"
+workflow_operation_table_name = "oc_workflow_operation"
+workflow_operation_configuration_table_name = "oc_workflow_operation_configuration"
+
+WORKFLOW_NS = "{http://workflow.opencastproject.org}"
+SECURITY_NS = "{http://org.opencastproject.security}"
+MEDIAPACKAGE_NS = '{http://mediapackage.opencastproject.org}'
+
+XML_DECLARATION = ""
+
+
+# DB functions
+def create_connection(host_name, port_number, user_name, user_password, db_name):
+ connection = mysql.connector.connect(
+ host=host_name,
+ port=port_number,
+ user=user_name,
+ passwd=user_password,
+ database=db_name,
+ )
+ connection.row_factory = lambda cursor, row: row[0]
+ print("Connection to database successful")
+ return connection
+
+
+def execute_query(connection, query):
+ cursor = connection.cursor()
+ cursor.execute(query)
+ connection.commit()
+ print("Query executed successfully")
+
+
+def execute_read_query(connection, query):
+ cursor = connection.cursor()
+ cursor.execute(query)
+ return cursor.fetchall()
+
+
+def insert_parsed(sql, list_of_lists):
+ data = []
+ for item in list_of_lists:
+ data.append(tuple(item))
+
+ cursor = connection.cursor()
+ cursor.executemany(sql, data)
+ connection.commit()
+
+
+# XML functions
+def get_node_value(node, name, ns=''):
+ result = node.find(f'{ns}{name}')
+ if result is None:
+ return None
+ return result.text
+
+
+def get_attrib_from_node(node, attribute):
+ return node.get(attribute)
+
+
+def parse_workflow_state(state):
+ states = {
+ "INSTANTIATED": 0,
+ "RUNNING": 1,
+ "STOPPED": 2,
+ "PAUSED": 3,
+ "SUCCEEDED": 4,
+ "FAILED": 5,
+ "FAILING": 6,
+ }
+ return states.get(state)
+
+
+def parse_operation_state(state):
+ states = {
+ "INSTANTIATED": 0,
+ "RUNNING": 1,
+ "PAUSED": 2,
+ "SUCCEEDED": 3,
+ "FAILED": 4,
+ "SKIPPED": 5,
+ "RETRY": 6,
+ }
+ return states.get(state)
+
+
+def none_safe(value, fn):
+ if value is None:
+ return None
+ return fn(value)
+
+
+def parse_bool(value):
+ if value is None:
+ return None
+ return value.lower() == 'true'
+
+
+# Connect
+print("Creating connection to database...")
+connection = create_connection(host, port, user, password, database)
+
+# Create new tables
+# Currently added indexes:
+# - Indexes for bidirectional relationships between Workflow <-> Operation <-> Configuration
+# - mediaPackageId, seriesId for oc_workflow
+print("Create tables...")
+create_workflow_table = f"""
+CREATE TABLE {workflow_table_name} (
+ `id` bigint(20) NOT NULL,
+ `creator_id` varchar(255) DEFAULT NULL,
+ `date_completed` datetime DEFAULT NULL,
+ `date_created` datetime DEFAULT NULL,
+ `description` varchar(255) DEFAULT NULL,
+ `mediapackage` longtext DEFAULT NULL,
+ `mediapackage_id` varchar(128) DEFAULT NULL,
+ `organization_id` varchar(255) DEFAULT NULL,
+ `series_id` varchar(128) DEFAULT NULL,
+ `state` int(11) DEFAULT NULL,
+ `template` varchar(255) DEFAULT NULL,
+ `title` varchar(255) DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ KEY `IX_oc_workflow_mediapackage_id` (`mediapackage_id`),
+ KEY `IX_oc_workflow_series_id` (`series_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+"""
+
+create_workflow_configuration_table = f"""
+CREATE TABLE {workflow_configuration_table_name} (
+ `workflow_id` bigint(20) DEFAULT NULL,
+ `configuration_value` longtext DEFAULT NULL,
+ `configuration_key` varchar(255) DEFAULT NULL,
+ KEY `FK_oc_workflow_configuration_workflow_id` (`workflow_id`),
+ CONSTRAINT `FK_oc_workflow_configuration_workflow_id` FOREIGN KEY (`workflow_id`) REFERENCES `oc_workflow` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+"""
+
+create_workflow_operation_table = f"""
+CREATE TABLE {workflow_operation_table_name} (
+ `id` bigint(20) NOT NULL,
+ `abortable` tinyint(1) DEFAULT 0,
+ `continuable` tinyint(1) DEFAULT 0,
+ `completed` datetime DEFAULT NULL,
+ `started` datetime DEFAULT NULL,
+ `description` varchar(255) DEFAULT NULL,
+ `exception_handler_workflow` varchar(255) DEFAULT NULL,
+ `if_condition` varchar(255) DEFAULT NULL,
+ `execution_host` varchar(255) DEFAULT NULL,
+ `fail_on_error` tinyint(1) DEFAULT 0,
+ `failed_attempts` int(11) DEFAULT NULL,
+ `job` bigint(20) DEFAULT NULL,
+ `max_attempts` int(11) DEFAULT NULL,
+ `retry_strategy` int(11) DEFAULT NULL,
+ `state` int(11) DEFAULT NULL,
+ `template` varchar(255) DEFAULT NULL,
+ `time_in_queue` bigint(20) DEFAULT NULL,
+ `workflow_id` bigint(20) NOT NULL,
+ `position` int(11) DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ KEY `FK_oc_workflow_operation_workflow_id` (`workflow_id`),
+ CONSTRAINT `FK_oc_workflow_operation_workflow_id` FOREIGN KEY (`workflow_id`) REFERENCES `oc_workflow` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+"""
+
+create_workflow_operation_configuration_table = f"""
+CREATE TABLE {workflow_operation_configuration_table_name} (
+ `workflow_operation_id` bigint(20) DEFAULT NULL,
+ `configuration_value` longtext DEFAULT NULL,
+ `configuration_key` varchar(255) NOT NULL,
+ KEY `cworkflowoperationconfigurationworkflowoperationid` (`workflow_operation_id`),
+ CONSTRAINT `cworkflowoperationconfigurationworkflowoperationid` FOREIGN KEY (`workflow_operation_id`) REFERENCES `oc_workflow_operation` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+"""
+
+execute_query(connection, create_workflow_table)
+execute_query(connection, create_workflow_configuration_table)
+execute_query(connection, create_workflow_operation_table)
+execute_query(connection, create_workflow_operation_configuration_table)
+
+print("Collect information from oc_job table...")
+select_workflow_count = """
+select count(*)
+from oc_job
+where operation = 'START_WORKFLOW'
+
+"""
+select_workflow_from_job_table = """
+SELECT id, payload, date_created, date_completed
+FROM oc_job
+WHERE operation = 'START_WORKFLOW'
+ORDER BY date_created ASC
+LIMIT 100
+OFFSET {0}
+"""
+
+workflow_count = execute_read_query(connection, select_workflow_count)[0][0]
+workflow_current = 0
+
+# Parse information from XML
+print("Put information from oc_job into the new tables...")
+operation_id = 0
+for offset in range(0, workflow_count, 100):
+ workflow_sql = select_workflow_from_job_table.format(offset)
+ workflow_jobs = execute_read_query(connection, workflow_sql)
+ for (workflow_id, payload, date_created, date_completed) in workflow_jobs:
+ root = ET.fromstring(payload)
+
+ # oc_workflow
+ workflow_current += 1
+ print(f'Migrating workflow {workflow_id} ({workflow_current}/{workflow_count})')
+ workflow_operations = []
+ workflow_operation_config = []
+ workflow_config = []
+ workflow = [
+ workflow_id,
+ get_node_value(root, 'creator-id', SECURITY_NS),
+ date_completed,
+ date_created,
+ get_node_value(root, 'description', WORKFLOW_NS),
+ get_node_value(root, 'organization-id', SECURITY_NS),
+ parse_workflow_state(get_attrib_from_node(root, "state")),
+ get_node_value(root, 'template', WORKFLOW_NS),
+ get_node_value(root, 'title', WORKFLOW_NS)]
+ ET.register_namespace('', 'http://mediapackage.opencastproject.org')
+ mediapackage = root.find(f"{MEDIAPACKAGE_NS}mediapackage")
+ mediapackage_str = ET.tostring(mediapackage, encoding="UTF-8").decode("utf-8")
+ # ET.tostring(…, xml_declaration=True) requires Python 3.8
+ if not mediapackage_str.startswith(XML_DECLARATION):
+ mediapackage_str = f'{XML_DECLARATION}\n{mediapackage_str}'
+ workflow.append(mediapackage_str)
+ workflow.append(get_attrib_from_node(mediapackage, "id"))
+ workflow.append(get_node_value(mediapackage, f"{MEDIAPACKAGE_NS}series"))
+
+ # oc_workflow_configuration
+ for configuration in root.find(f"{WORKFLOW_NS}configurations"):
+ value = configuration.text
+ workflow_config.append([
+ workflow_id,
+ get_attrib_from_node(configuration, "key"),
+ value if value is not None else ""])
+
+ # oc_workflow_operation
+ operation_position = 0
+ for operation in root.find(f"{WORKFLOW_NS}operations"):
+ workflow_operations.append([
+ operation_id,
+ parse_bool(get_attrib_from_node(operation, "abortable")),
+ parse_bool(get_attrib_from_node(operation, "continuable")),
+ none_safe(
+ get_node_value(operation, f"{WORKFLOW_NS}completed"),
+ lambda x: datetime.fromtimestamp(int(x) / 1000.0)),
+ none_safe(
+ get_node_value(operation, f"{WORKFLOW_NS}started"),
+ lambda x: datetime.fromtimestamp(int(x) / 1000.0)),
+ get_attrib_from_node(operation, "description"),
+ get_attrib_from_node(operation, "exception-handler-workflow"),
+ get_attrib_from_node(operation, "if"),
+ get_attrib_from_node(operation, "execution-host"),
+ parse_bool(get_attrib_from_node(operation, "fail-on-error")),
+ get_attrib_from_node(operation, "failed-attempts"),
+ get_attrib_from_node(operation, "job"),
+ get_attrib_from_node(operation, "max-attempts"),
+ {"none": 0, "retry": 1, "hold": 2}.get(
+ get_attrib_from_node(operation, "retry-strategy")),
+ parse_operation_state(get_attrib_from_node(operation, "state")),
+ get_attrib_from_node(operation, "id"), # now named template
+ get_node_value(operation, f"{WORKFLOW_NS}time-in-queue"),
+ workflow_id,
+ operation_position])
+
+ # oc_workflow_operation_configuration
+ for op_config in operation.find("{http://workflow.opencastproject.org}configurations"):
+ value = op_config.text
+ workflow_operation_config.append([
+ operation_id,
+ get_attrib_from_node(op_config, "key"),
+ value if value is not None else ""])
+
+ # Generate ID and position for next operation
+ operation_id += 1
+ operation_position += 1
+
+ # Insert parsed information into the created tables
+ create_workflow_sql = f"""
+ INSERT INTO {workflow_table_name} (
+ id,
+ creator_id,
+ date_completed,
+ date_created,
+ description,
+ organization_id,
+ state,
+ template,
+ title,
+ mediapackage,
+ mediapackage_id,
+ series_id
+ ) VALUES
+ ( %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s )
+ """
+
+ create_workflow_configuration_sql = f"""
+ INSERT INTO {workflow_configuration_table_name} (
+ workflow_id,
+ configuration_key,
+ configuration_value)
+ VALUES
+ ( %s, %s, %s )
+ """
+
+ create_workflow_operation_sql = f"""
+ INSERT INTO {workflow_operation_table_name} (
+ id,
+ abortable,
+ continuable,
+ completed,
+ started,
+ description,
+ exception_handler_workflow,
+ if_condition,
+ execution_host,
+ fail_on_error,
+ failed_attempts,
+ job,
+ max_attempts,
+ retry_strategy,
+ state,
+ template,
+ time_in_queue,
+ workflow_id,
+ `position`
+ ) VALUES
+ ( %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
+ %s, %s, %s, %s, %s, %s, %s, %s, %s )
+ """
+
+ create_workflow_operation_configuration_sql = f"""
+ INSERT INTO {workflow_operation_configuration_table_name} (
+ workflow_operation_id,
+ configuration_key,
+ configuration_value
+ ) VALUES
+ ( %s, %s, %s )
+ """
+
+ insert_parsed(create_workflow_sql, [workflow])
+ insert_parsed(create_workflow_configuration_sql, workflow_config)
+ insert_parsed(create_workflow_operation_sql, workflow_operations)
+ insert_parsed(create_workflow_operation_configuration_sql, workflow_operation_config)
+
+
+# Delete workflow information from oc_job
+print("Delete payloads from oc_job table...")
+sql_update_job_payload_query = """
+UPDATE oc_job
+SET payload = NULL
+WHERE operation = 'START_WORKFLOW'
+"""
+execute_query(connection, sql_update_job_payload_query)
+
+print("Update complete!")
diff --git a/docs/upgrade/11_to_12/workflows_postgresql.py b/docs/upgrade/11_to_12/workflows_postgresql.py
new file mode 100644
index 0000000000..85d5067c03
--- /dev/null
+++ b/docs/upgrade/11_to_12/workflows_postgresql.py
@@ -0,0 +1,382 @@
+# Upgrade script for PostgreSQL databases
+# Requires Python3 to run
+# Required packages:
+# $ pip install psycopg2-binary
+# Set vars to point to your database
+# Run on commandline: "python3 workflow_db_upgrade.py"
+# WARNING: THIS SCRIPT DELETES DATA. CREATE A BACKUP BEFORE RUNNING
+
+# Module Imports
+import psycopg2
+import xml.etree.ElementTree as ET
+from datetime import datetime
+
+# Vars
+user = "opencast"
+password = "dbpassword"
+host = "127.0.0.1"
+port = 5432
+database = "opencast"
+
+# Constants
+workflow_table_name = "oc_workflow"
+workflow_configuration_table_name = "oc_workflow_configuration"
+workflow_operation_table_name = "oc_workflow_operation"
+workflow_operation_configuration_table_name = "oc_workflow_operation_configuration"
+
+WORKFLOW_NS = "{http://workflow.opencastproject.org}"
+SECURITY_NS = "{http://org.opencastproject.security}"
+MEDIAPACKAGE_NS = '{http://mediapackage.opencastproject.org}'
+
+XML_DECLARATION = ""
+
+
+# DB functions
+def create_connection(host_name, port_number, user_name, user_password, db_name):
+ connection = psycopg2.connect(
+ host=host_name,
+ port=port_number,
+ user=user_name,
+ password=user_password,
+ database=db_name,
+ )
+ print("Connection to database successful")
+ return connection
+
+
+def execute_query(connection, query):
+ cursor = connection.cursor()
+ cursor.execute(query)
+ connection.commit()
+ print("Query executed successfully")
+
+
+def execute_read_query(connection, query):
+ cursor = connection.cursor()
+ cursor.execute(query)
+ return cursor.fetchall()
+
+
+def insert_parsed(sql, list_of_lists):
+ data = []
+ for item in list_of_lists:
+ data.append(tuple(item))
+
+ cursor = connection.cursor()
+ cursor.executemany(sql, data)
+ connection.commit()
+
+
+# XML functions
+def get_node_value(node, name, ns=''):
+ result = node.find(f'{ns}{name}')
+ if result is None:
+ return None
+ return result.text
+
+
+def get_attrib_from_node(node, attribute):
+ return node.get(attribute)
+
+
+def parse_workflow_state(state):
+ states = {
+ "INSTANTIATED": 0,
+ "RUNNING": 1,
+ "STOPPED": 2,
+ "PAUSED": 3,
+ "SUCCEEDED": 4,
+ "FAILED": 5,
+ "FAILING": 6,
+ }
+ return states.get(state)
+
+
+def parse_operation_state(state):
+ states = {
+ "INSTANTIATED": 0,
+ "RUNNING": 1,
+ "PAUSED": 2,
+ "SUCCEEDED": 3,
+ "FAILED": 4,
+ "SKIPPED": 5,
+ "RETRY": 6,
+ }
+ return states.get(state)
+
+
+def none_safe(value, fn):
+ if value is None:
+ return None
+ return fn(value)
+
+
+def parse_bool(value):
+ if value is None:
+ return None
+ return value.lower() == 'true'
+
+
+# Connect
+print("Creating connection to database...")
+connection = create_connection(host, port, user, password, database)
+
+# Create new tables
+# Currently added indexes:
+# - Indexes for bidirectional relationships between Workflow <-> Operation <-> Configuration
+# - mediaPackageId, seriesId for oc_workflow
+print("Create tables...")
+create_workflow_table = f"""
+CREATE TABLE {workflow_table_name} (
+ id bigint PRIMARY KEY,
+ creator_id character varying(255),
+ date_completed timestamp without time zone,
+ date_created timestamp without time zone,
+ description character varying(255),
+ mediapackage text,
+ mediapackage_id character varying(128),
+ organization_id character varying(255),
+ series_id character varying(128),
+ state integer,
+ template character varying(255),
+ title character varying(255)
+)
+"""
+
+create_workflow_table_index_mediapackageId = f"""
+CREATE INDEX ix_oc_workflow_mediapackage_id ON {workflow_table_name} USING btree (mediapackage_id);
+"""
+
+create_workflow_table_index_seriesId = f"""
+CREATE INDEX ix_oc_workflow_series_id ON {workflow_table_name} USING btree (series_id);
+"""
+
+create_workflow_configuration_table = f"""
+CREATE TABLE {workflow_configuration_table_name} (
+ workflow_id bigint REFERENCES {workflow_table_name}(id),
+ configuration_value text,
+ configuration_key character varying(255)
+)
+"""
+
+create_workflow_operation_table = f"""
+CREATE TABLE {workflow_operation_table_name} (
+ id bigint PRIMARY KEY,
+ abortable boolean,
+ continuable boolean,
+ completed timestamp without time zone,
+ started timestamp without time zone,
+ description character varying(255),
+ exception_handler_workflow character varying(255),
+ if_condition character varying(255),
+ execution_host character varying(255),
+ fail_on_error boolean,
+ failed_attempts integer,
+ job bigint,
+ max_attempts integer,
+ retry_strategy integer,
+ state integer,
+ template character varying(255),
+ time_in_queue bigint,
+ workflow_id bigint NOT NULL REFERENCES {workflow_table_name}(id),
+ "position" integer
+)
+"""
+
+create_workflow_operation_configuration_table = f"""
+CREATE TABLE {workflow_operation_configuration_table_name} (
+ workflow_operation_id bigint REFERENCES {workflow_operation_table_name}(id),
+ configuration_value text,
+ configuration_key character varying(255) NOT NULL
+)
+"""
+
+execute_query(connection, create_workflow_table)
+execute_query(connection, create_workflow_table_index_mediapackageId)
+execute_query(connection, create_workflow_table_index_seriesId)
+execute_query(connection, create_workflow_configuration_table)
+execute_query(connection, create_workflow_operation_table)
+execute_query(connection, create_workflow_operation_configuration_table)
+
+print("Collect information from oc_job table...")
+select_workflow_count = """
+select count(*)
+from oc_job
+where operation = 'START_WORKFLOW'
+
+"""
+select_workflow_from_job_table = """
+SELECT id, payload, date_created, date_completed
+FROM oc_job
+WHERE operation = 'START_WORKFLOW'
+ORDER BY date_created ASC
+LIMIT 100
+OFFSET {0}
+"""
+
+workflow_count = execute_read_query(connection, select_workflow_count)[0][0]
+workflow_current = 0
+
+# Parse information from XML
+print("Put information from oc_job into the new tables...")
+operation_id = 0
+for offset in range(0, workflow_count, 100):
+ workflow_sql = select_workflow_from_job_table.format(offset)
+ workflow_jobs = execute_read_query(connection, workflow_sql)
+ for (workflow_id, payload, date_created, date_completed) in workflow_jobs:
+ root = ET.fromstring(payload)
+
+ # oc_workflow
+ workflow_current += 1
+ print(f'Migrating workflow {workflow_id} ({workflow_current}/{workflow_count})')
+ workflow_operations = []
+ workflow_operation_config = []
+ workflow_config = []
+ workflow = [
+ workflow_id,
+ get_node_value(root, 'creator-id', SECURITY_NS),
+ date_completed,
+ date_created,
+ get_node_value(root, 'description', WORKFLOW_NS),
+ get_node_value(root, 'organization-id', SECURITY_NS),
+ parse_workflow_state(get_attrib_from_node(root, "state")),
+ get_node_value(root, 'template', WORKFLOW_NS),
+ get_node_value(root, 'title', WORKFLOW_NS)]
+ ET.register_namespace('', 'http://mediapackage.opencastproject.org')
+ mediapackage = root.find(f"{MEDIAPACKAGE_NS}mediapackage")
+ mediapackage_str = ET.tostring(mediapackage, encoding="UTF-8").decode("utf-8")
+ # ET.tostring(…, xml_declaration=True) requires Python 3.8
+ if not mediapackage_str.startswith(XML_DECLARATION):
+ mediapackage_str = f'{XML_DECLARATION}\n{mediapackage_str}'
+ workflow.append(mediapackage_str)
+ workflow.append(get_attrib_from_node(mediapackage, "id"))
+ workflow.append(get_node_value(mediapackage, f"{MEDIAPACKAGE_NS}series"))
+
+ # oc_workflow_configuration
+ for configuration in root.find(f"{WORKFLOW_NS}configurations"):
+ value = configuration.text
+ workflow_config.append([
+ workflow_id,
+ get_attrib_from_node(configuration, "key"),
+ value if value is not None else ""])
+
+ # oc_workflow_operation
+ operation_position = 0
+ for operation in root.find(f"{WORKFLOW_NS}operations"):
+ workflow_operations.append([
+ operation_id,
+ parse_bool(get_attrib_from_node(operation, "abortable")),
+ parse_bool(get_attrib_from_node(operation, "continuable")),
+ none_safe(
+ get_node_value(operation, f"{WORKFLOW_NS}completed"),
+ lambda x: datetime.fromtimestamp(int(x) / 1000.0)),
+ none_safe(
+ get_node_value(operation, f"{WORKFLOW_NS}started"),
+ lambda x: datetime.fromtimestamp(int(x) / 1000.0)),
+ get_attrib_from_node(operation, "description"),
+ get_attrib_from_node(operation, "exception-handler-workflow"),
+ get_attrib_from_node(operation, "if"),
+ get_attrib_from_node(operation, "execution-host"),
+ parse_bool(get_attrib_from_node(operation, "fail-on-error")),
+ get_attrib_from_node(operation, "failed-attempts"),
+ get_attrib_from_node(operation, "job"),
+ get_attrib_from_node(operation, "max-attempts"),
+ {"none": 0, "retry": 1, "hold": 2}.get(
+ get_attrib_from_node(operation, "retry-strategy")),
+ parse_operation_state(get_attrib_from_node(operation, "state")),
+ get_attrib_from_node(operation, "id"), # now named template
+ get_node_value(operation, f"{WORKFLOW_NS}time-in-queue"),
+ workflow_id,
+ operation_position])
+
+ # oc_workflow_operation_configuration
+ for op_config in operation.find("{http://workflow.opencastproject.org}configurations"):
+ value = op_config.text
+ workflow_operation_config.append([
+ operation_id,
+ get_attrib_from_node(op_config, "key"),
+ value if value is not None else ""])
+
+ # Generate ID and position for next operation
+ operation_id += 1
+ operation_position += 1
+
+ # Insert parsed information into the created tables
+ create_workflow_sql = f"""
+ INSERT INTO {workflow_table_name} (
+ id,
+ creator_id,
+ date_completed,
+ date_created,
+ description,
+ organization_id,
+ state,
+ template,
+ title,
+ mediapackage,
+ mediapackage_id,
+ series_id
+ ) VALUES
+ ( %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s )
+ """
+
+ create_workflow_configuration_sql = f"""
+ INSERT INTO {workflow_configuration_table_name} (
+ workflow_id,
+ configuration_key,
+ configuration_value)
+ VALUES
+ ( %s, %s, %s )
+ """
+
+ create_workflow_operation_sql = f"""
+ INSERT INTO {workflow_operation_table_name} (
+ id,
+ abortable,
+ continuable,
+ completed,
+ started,
+ description,
+ exception_handler_workflow,
+ if_condition,
+ execution_host,
+ fail_on_error,
+ failed_attempts,
+ job,
+ max_attempts,
+ retry_strategy,
+ state,
+ template,
+ time_in_queue,
+ workflow_id,
+ "position"
+ ) VALUES
+ ( %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
+ %s, %s, %s, %s, %s, %s, %s, %s, %s )
+ """
+
+ create_workflow_operation_configuration_sql = f"""
+ INSERT INTO {workflow_operation_configuration_table_name} (
+ workflow_operation_id,
+ configuration_key,
+ configuration_value
+ ) VALUES
+ ( %s, %s, %s )
+ """
+
+ insert_parsed(create_workflow_sql, [workflow])
+ insert_parsed(create_workflow_configuration_sql, workflow_config)
+ insert_parsed(create_workflow_operation_sql, workflow_operations)
+ insert_parsed(create_workflow_operation_configuration_sql, workflow_operation_config)
+
+
+# Delete workflow information from oc_job
+print("Delete payloads from oc_job table...")
+sql_update_job_payload_query = """
+UPDATE oc_job
+SET payload = NULL
+WHERE operation = 'START_WORKFLOW'
+"""
+execute_query(connection, sql_update_job_payload_query)
+
+print("Update complete!")
diff --git a/docs/upgrade/12_to_13/mariadb.sql b/docs/upgrade/12_to_13/mariadb.sql
new file mode 100644
index 0000000000..b3631ed4a2
--- /dev/null
+++ b/docs/upgrade/12_to_13/mariadb.sql
@@ -0,0 +1,29 @@
+CREATE INDEX IF NOT EXISTS IX_oc_aws_asset_mapping_object_key ON oc_aws_asset_mapping (object_key);
+CREATE INDEX IF NOT EXISTS IX_oc_job_argument_id ON oc_job_argument (id);
+
+ALTER TABLE oc_workflow
+ MODIFY COLUMN `description` LONGTEXT DEFAULT NULL;
+
+ALTER TABLE oc_workflow_operation
+ MODIFY COLUMN `description` LONGTEXT DEFAULT NULL,
+ MODIFY COLUMN `if_condition` LONGTEXT DEFAULT NULL;
+
+ALTER TABLE oc_workflow_configuration
+ DROP FOREIGN KEY IF EXISTS FK_oc_workflow_configuration_workflow_id,
+ ADD FOREIGN KEY IF NOT EXISTS IX_oc_workflow_configuration_workflow_id (`workflow_id`) REFERENCES `oc_workflow` (`id`);
+
+ALTER TABLE oc_workflow_operation
+ DROP FOREIGN KEY IF EXISTS FK_oc_workflow_operation_workflow_id,
+ ADD FOREIGN KEY IF NOT EXISTS IX_oc_workflow_operation_workflow_id (`workflow_id`) REFERENCES `oc_workflow` (`id`);
+
+ALTER TABLE oc_workflow_operation_configuration
+ DROP FOREIGN KEY IF EXISTS cworkflowoperationconfigurationworkflowoperationid,
+ ADD FOREIGN KEY IF NOT EXISTS IX_oc_workflow_operation_configuration_workflow_operation_id (`workflow_operation_id`) REFERENCES `oc_workflow_operation` (`id`);
+
+UPDATE oc_workflow_configuration
+SET configuration_value = ''
+WHERE configuration_value IS NULL;
+
+UPDATE oc_workflow_operation_configuration
+SET configuration_value = ''
+WHERE configuration_value IS NULL;
diff --git a/docs/upgrade/12_to_13/postgresql.sql b/docs/upgrade/12_to_13/postgresql.sql
new file mode 100644
index 0000000000..f9e0ba53ee
--- /dev/null
+++ b/docs/upgrade/12_to_13/postgresql.sql
@@ -0,0 +1,21 @@
+CREATE INDEX IF NOT EXISTS IX_oc_aws_asset_mapping_object_key ON oc_aws_asset_mapping (object_key);
+CREATE INDEX IF NOT EXISTS IX_oc_job_argument_id ON oc_job_argument (id);
+
+ALTER TABLE oc_workflow
+ ALTER COLUMN description TYPE TEXT;
+
+ALTER TABLE oc_workflow_operation
+ ALTER COLUMN description TYPE TEXT,
+ ALTER COLUMN if_condition TYPE TEXT;
+
+CREATE INDEX IF NOT EXISTS IX_oc_workflow_configuration_workflow_id ON oc_workflow_configuration (workflow_id);
+CREATE INDEX IF NOT EXISTS IX_oc_workflow_operation_workflow_id ON oc_workflow_operation (workflow_id);
+CREATE INDEX IF NOT EXISTS IX_oc_workflow_operation_configuration_workflow_operation_id ON oc_workflow_operation_configuration (workflow_operation_id);
+
+UPDATE oc_workflow_configuration
+SET configuration_value = ''
+WHERE configuration_value IS NULL;
+
+UPDATE oc_workflow_operation_configuration
+SET configuration_value = ''
+WHERE configuration_value IS NULL;
diff --git a/etc/custom.properties b/etc/custom.properties
index 663daabba7..d5c9917f00 100644
--- a/etc/custom.properties
+++ b/etc/custom.properties
@@ -12,6 +12,10 @@
# Also note that if this felix installation is proxied behind an Apache HTTPD reverse proxy, and communication is meant
# to go through that proxy, then server.url should point to the proxy's port (usually 80).
# Related options (like listening addresses) are located in etc/org.ops4j.pax.web.cfg
+#
+# It is not supported for Opencast or it's tenants to be hosted in a subpath. Opencast or the tenants need to be served
+# from the root path element. The RFC 3986 URI path component needs to be empty.
+
org.opencastproject.server.url=http://localhost:8080
# The environment specified below will show up in the email subject when sending a notification about transcription
@@ -116,7 +120,7 @@ org.opencastproject.download.directory=${org.opencastproject.storage.dir}/downlo
# .url=jdbc:h2:${org.opencastproject.storage.dir}/db
# .user=sa
# .pass=sa
-#org.opencastproject.db.jdbc.url=jdbc:mysql://localhost/opencast?useMysqlMetadata=true
+#org.opencastproject.db.jdbc.url=jdbc:mariadb://localhost/opencast?useMysqlMetadata=true
#org.opencastproject.db.jdbc.user=opencast
#org.opencastproject.db.jdbc.pass=dbpassword
@@ -161,17 +165,6 @@ org.opencastproject.working.file.repository.cleanup.max.age=100
org.opencastproject.working.file.repository.cleanup.collections=failed.zips
-######### ACTIVE MQ BROKER #########
-
-# This configures the connection to the Active MQ broker so that we can send and receive messages.
-# There are many settings for specifying the broker url: http://activemq.apache.org/activemq-4-connection-uris.html
-# Including with failover support details here: http://activemq.apache.org/failover-transport-reference.html
-# Default (url): failover://(tcp://127.0.0.1:61616)?initialReconnectDelay=2000&maxReconnectDelay=60000
-# Default (username/password): None
-#activemq.broker.url=failover://(tcp://127.0.0.1:61616)?initialReconnectDelay=2000&maxReconnectDelay=60000
-#activemq.broker.username=admin
-#activemq.broker.password=password
-
######### Elasticsearch #########
# The hostname of the Elasticsearch node for Opencast to use.
@@ -203,16 +196,12 @@ org.opencastproject.working.file.repository.cleanup.collections=failed.zips
# Directory to store the embedded solr indices. This should be a persistent and stable directory.
# Default: ${org.opencastproject.solr.dir}/{search, series, workflow}
#org.opencastproject.search.solr.dir=${org.opencastproject.solr.dir}/search
-#org.opencastproject.series.solr.dir=${org.opencastproject.solr.dir}/series
-#org.opencastproject.workflow.solr.dir=${org.opencastproject.solr.dir}/workflow
# URLs of dedicated Solr server to use. Note that if thesw URLs are specified, the local embedded Solr index as
# configured using `org.opencastproject.*.solr.dir` will be ignored. A dedicated Solr server should be set up in order
# to enable running multiple instances of the related service. Please consult http://lucene.apache.org/solr/ on how to
# set up a standalone Solr server.
#org.opencastproject.search.solr.url=http://localhost:8983/solr/
-#org.opencastproject.series.solr.url=http://localhost:8983/solr/
-#org.opencastproject.workflow.solr.url=http://localhost:8983/solr/
######### Service Registry & Jobs #########
@@ -360,5 +349,3 @@ karaf.pid.file=${karaf.data}/pid
# a system where url signing is not configured. For more information please see:
# http://docs.opencast.org/develop/admin/configuration/stream-security/#configuration-of-url-signing-timeout-values
#org.opencastproject.security.internal.url.signing.duration=60
-
-
diff --git a/etc/email/errorDetails b/etc/email/errorDetails
index 62e295e627..c44ef4038c 100644
--- a/etc/email/errorDetails
+++ b/etc/email/errorDetails
@@ -1,10 +1,10 @@
Error Details
-<#if catalogs['series']?has_content>
-Course: ${catalogs['series']['subject']!'series subject missing'} - ${catalogs['series']['title']!'series title missing'}
-Instructor: ${catalogs['series']['contributor']!'instructor missing'}
+<#if catalogs['dublincore/series']?has_content>
+Course: ${catalogs['dublincore/series']['subject']!'series subject missing'} - ${catalogs['dublincore/series']['title']!'series title missing'}
+Instructor: ${catalogs['dublincore/series']['contributor']!'instructor missing'}
#if>
-Title: ${catalogs['episode']['title']!'title missing'}
+Title: ${catalogs['dublincore/episode']['title']!'title missing'}
Event Date: ${mediaPackage.date?datetime?iso_local}
<#if failedOperation?has_content>
diff --git a/etc/encoding/opencast.properties b/etc/encoding/opencast.properties
index 93130a7c37..388e0b72c3 100644
--- a/etc/encoding/opencast.properties
+++ b/etc/encoding/opencast.properties
@@ -79,9 +79,9 @@ profile.player-preview.http.name = cover image for engage
profile.player-preview.http.input = visual
profile.player-preview.http.output = image
profile.player-preview.http.suffix = -player.jpg
-profile.player-preview.http.ffmpeg.command = -i #{in.video.path} -frames:v 1 \
- -filter:v select=eq(n\\,1)+lt(t\\,#{time}),fps=25,reverse,scale=-2:720 \
- #{out.dir}/#{out.name}#{out.suffix}
+profile.player-preview.http.ffmpeg.command = -ss #{time} -i #{in.video.path} \
+ -vf "fps=1,scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1 [in]; color=black:s=1280x720:r=1:d=1 [bg]; [bg][in] overlay=0:0 [out]" \
+ -frames:v 1 #{out.dir}/#{out.name}#{out.suffix}
# Slide preview images as shown in the player
profile.player-slides.http.name = slide preview image for engage
@@ -89,17 +89,17 @@ profile.player-slides.http.input = visual
profile.player-slides.http.output = image
profile.player-slides.http.suffix = .#{time}.jpg
profile.player-slides.http.ffmpeg.command = -ss #{time} -i #{in.video.path} \
- -r 1 -frames:v 1 -filter:v scale=160:-1 \
- #{out.dir}/#{out.name}#{out.suffix}
+ -vf "fps=1,scale=160:90:force_original_aspect_ratio=decrease,pad=160:90:-1:-1 [in]; color=black:s=160x90:r=1:d=1 [bg]; [bg][in] overlay=0:0 [out]" \
+ -frames:v 1 #{out.dir}/#{out.name}#{out.suffix}
# Cover image for search results
profile.search-cover.http.name = cover image for engage
profile.search-cover.http.input = visual
profile.search-cover.http.output = image
profile.search-cover.http.suffix = -search.jpg
-profile.search-cover.http.ffmpeg.command = -i #{in.video.path} -frames:v 1 \
- -filter:v select=eq(n\\,1)+lt(t\\,#{time}),fps=25,reverse,scale=160:-2 \
- #{out.dir}/#{out.name}#{out.suffix}
+profile.search-cover.http.ffmpeg.command = -ss #{time} -i #{in.video.path} \
+ -vf "fps=1,scale=160:90:force_original_aspect_ratio=decrease,pad=160:90:-1:-1 [in]; color=black:s=160x90:r=1:d=1 [bg]; [bg][in] overlay=0:0 [out]" \
+ -frames:v 1 #{out.dir}/#{out.name}#{out.suffix}
profile.mp4-preview.http.name = preview video
profile.mp4-preview.http.input = visual
@@ -138,8 +138,8 @@ profile.feed-cover.http.input = visual
profile.feed-cover.http.output = image
profile.feed-cover.http.suffix = -feed.jpg
profile.feed-cover.http.ffmpeg.command = -ss #{time} -i #{in.video.path} \
- -r 1 -frames:v 1 -filter:v scale=-1:54 \
- #{out.dir}/#{out.name}#{out.suffix}
+ -vf "fps=1,scale=96:54:force_original_aspect_ratio=decrease,pad=96:54:-1:-1 [in]; color=black:s=96x54:r=1:d=1 [bg]; [bg][in] overlay=0:0 [out]" \
+ -frames:v 1 #{out.dir}/#{out.name}#{out.suffix}
# Image to video
profile.image-movie.work.name = image to video
@@ -158,8 +158,8 @@ profile.editor.tracks.preview.output = image
profile.editor.tracks.preview.suffix = -preview.jpg
profile.editor.tracks.preview.mimetype = image/jpeg
profile.editor.tracks.preview.ffmpeg.command = -ss #{time} -i #{in.video.path} \
- -r 1 -frames:v 1 -filter:v scale=320:-1 \
- #{out.dir}/#{out.name}#{out.suffix}
+ -vf "fps=1,scale=320:180:force_original_aspect_ratio=decrease,pad=320:180:-1:-1 [in]; color=black:s=320x180:r=1:d=1 [bg]; [bg][in] overlay=0:0 [out]" \
+ -frames:v 1 #{out.dir}/#{out.name}#{out.suffix}
profile.composite.http.name = composite
profile.composite.http.input = visual
@@ -245,5 +245,5 @@ profile.text-analysis.http.input = visual
profile.text-analysis.http.output = image
profile.text-analysis.http.suffix = .#{time}.png
profile.text-analysis.http.ffmpeg.command = -ss #{time} -i #{in.video.path} \
- -filter:v curves=preset=increase_contrast \
- -frames:v 1 -pix_fmt:v gray -r 1 #{out.dir}/#{out.name}#{out.suffix}
\ No newline at end of file
+ -vf "fps=1,scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1 [in]; color=black:s=1280x720:r=1:d=1 [bg]; [bg][in] overlay=0:0 [mux]; [mux] curves=preset=increase_contrast,format=pix_fmts=gray [out]" \
+ -frames:v 1 #{out.dir}/#{out.name}#{out.suffix}
\ No newline at end of file
diff --git a/etc/listproviders/event.upload.asset.options.properties b/etc/listproviders/event.upload.asset.options.properties
index 4d9a11780f..f5d17d56e6 100644
--- a/etc/listproviders/event.upload.asset.options.properties
+++ b/etc/listproviders/event.upload.asset.options.properties
@@ -27,8 +27,9 @@
list.name=eventUploadAssetOptions
+# The 'multiple' attribute determines if multiple elements with the same flavor are allowed or not. Default is false i.e. existing elements with same flavor are overwritten.
+
# Asset upload options are for new and existing events.
-# Only one file can be uploaded for each of these options: the uploaded file replaces existing elements of the same type and flavor in the mediapackage.
# EVENTS.EVENTS.NEW.UPLOAD_ASSET.OPTION.CLASS_HANDOUT_NOTES={"id": "attachment_class_handout_notes", "type": "attachment", "flavorType": "attachment", "flavorSubType": "notes", "displayOrder":1}
# EVENTS.EVENTS.NEW.UPLOAD_ASSET.OPTION.CAPTIONS_DFXP={"id":"attachment_captions_dfxp", "type": "attachment", "flavorType": "captions", "flavorSubType": "dfxp", "displayOrder":2, "accept": ".ttml, .dfxp, .xml"}
# EVENTS.EVENTS.NEW.UPLOAD_ASSET.OPTION.CAPTIONS_WEBVTT={"id":"attachment_captions_webvtt", "type": "attachment", "flavorType": "text", "flavorSubType": "vtt", "displayOrder":3, "accept": ".vtt"}
@@ -36,11 +37,10 @@ list.name=eventUploadAssetOptions
EVENTS.EVENTS.NEW.UPLOAD_ASSET.WORKFLOWDEFID=publish-uploaded-assets
# The video source track upload options are only for new events.
-# Unlike the other assets, multiple source tracks can be uploaded for a single flavor.
# The MULTIPLE_PARTS example shows how to enable choosing multiple source files for a single flavor. In this case, a fictional "multipart/part+source".
# EVENTS.EVENTS.NEW.SOURCE.UPLOAD.MULTIPLE_PARTS={"id": "track_parts","type":"track", "flavorType": "multipart","flavorSubType": "part+source", "multiple":true, "displayOrder":11, "accept": ".avi,.flv,.m4v,.mkv,.mov,.mp4,.mpeg,.mpg,.ogv,.webm,.wmv,.flac,.m4a,.mp3,.ogg,.wav,.wma"}
# EVENTS.EVENTS.NEW.SOURCE.UPLOAD.AUDIO_ONLY={"id": "track_audio","type":"track", "flavorType": "presenter-audio", "flavorSubType": "source", "multiple":false, "displayOrder":12, "accept": ".flac,.m4a,.mp3,.ogg,.wav,.wma"}
-EVENTS.EVENTS.NEW.SOURCE.UPLOAD.NON_SEGMENTABLE={"id": "track_presenter","type":"track", "flavorType": "presenter","flavorSubType": "source", "multiple":false, "displayOrder":13, "accept": ".avi,.flv,.m4v,.mkv,.mov,.mp4,.mpeg,.mpg,.ogv,.webm,.wmv,.flac,.m4a,.mp3,.ogg,.wav,.wma"}
-EVENTS.EVENTS.NEW.SOURCE.UPLOAD.SEGMENTABLE={"id": "track_presentation","type":"track", "flavorType": "presentation","flavorSubType": "source", "multiple":false, "displayOrder":14, "accept": ".avi,.flv,.m4v,.mkv,.mov,.mp4,.mpeg,.mpg,.ogv,.webm,.wmv,.flac,.m4a,.mp3,.ogg,.wav,.wma"}
+EVENTS.EVENTS.NEW.SOURCE.UPLOAD.NON_SEGMENTABLE={"id": "track_presenter","type":"track", "flavorType": "presenter","flavorSubType": "source", "multiple":false, "displayOrder":13, "accept": ".avi,.flv,.m4v,.mkv,.mov,.mp4,.mpeg,.mpg,.ogv,.webm,.wmv,.flac,.m4a,.mp3,.ogg,.wav,.wma,.f4v"}
+EVENTS.EVENTS.NEW.SOURCE.UPLOAD.SEGMENTABLE={"id": "track_presentation","type":"track", "flavorType": "presentation","flavorSubType": "source", "multiple":false, "displayOrder":14, "accept": ".avi,.flv,.m4v,.mkv,.mov,.mp4,.mpeg,.mpg,.ogv,.webm,.wmv,.flac,.m4a,.mp3,.ogg,.wav,.wma,.f4v"}
# Presenter and Presentation tracks uploaded in a single container
# EVENTS.EVENTS.NEW.SOURCE.UPLOAD.MULTIPLE_TRACKS={"id": "track_multi","type":"track", "flavorType": "multitrack","flavorSubType": "source", "multiple":false, "displayOrder":15, "accept": ".avi,.flv,.m4v,.mkv,.mov,.mp4,.mpeg,.mpg,.ogv,.webm,.wmv,.flac,.m4a,.mp3,.ogg,.wav,.wma"}
diff --git a/etc/org.apache.felix.fileinstall-workflows.cfg b/etc/org.apache.felix.fileinstall-workflows.cfg
index 01e6c535d6..a71c222ffe 100644
--- a/etc/org.apache.felix.fileinstall-workflows.cfg
+++ b/etc/org.apache.felix.fileinstall-workflows.cfg
@@ -1,8 +1,8 @@
# The name of the directory to watch.
felix.fileinstall.dir=${karaf.etc}/workflows
-# Filter accepted files (only allow xml files)
-felix.fileinstall.filter=.*\\.xml
+# Filter accepted files (only allow xml|yaml|yml files)
+felix.fileinstall.filter=.*\\.(xml|yaml|yml)$
# Number of milliseconds between 2 polls of the directory
felix.fileinstall.poll=5000
diff --git a/etc/org.opencastproject.adminui.endpoint.SeriesEndpoint.cfg b/etc/org.opencastproject.adminui.endpoint.SeriesEndpoint.cfg
index ec8160d359..cf2bf7a18f 100644
--- a/etc/org.opencastproject.adminui.endpoint.SeriesEndpoint.cfg
+++ b/etc/org.opencastproject.adminui.endpoint.SeriesEndpoint.cfg
@@ -14,3 +14,30 @@
# to in the events filter.
# Default: true
#eventsFilter.onlySeriesWithWriteAccess=true
+
+
+### Tobira configuration
+# You can configure one Tobira instance per tenant. Just follow the following pattern:
+
+#tobira.my_org.origin=https://tobira.my.org
+#tobira.my_org.trustedKey=01234
+
+#tobira.my_other_org.origin=https://tobira.my.other.org
+#tobira.my_other_org.trustedKey=56789
+
+# Note that configuring this means that anyone with the proper UI roles
+# will be able to modify the page structure of the Tobira instance configured here.
+# If you want to be more restrictive, you can also always add content within Tobira itself.
+
+# See below for an example (including sane defaults for developers)
+# and further explanations of the individual keys.
+
+# The base URL of the Tobira instance you want to be able to publish series to.
+# You need to configure this for the Tobira panel to show up in the series creation wizard.
+#tobira.mh_default_org.origin=http://localhost:3080
+
+# A shared secret between Tobira and Opencast to get authenticated access to the
+# `mount`-API. See also the `auth.trusted_external_key` configuration option in your
+# Tobira configuration.
+# You need to configure this for the Tobira panel to show up in the series creation wizard.
+#tobira.mh_default_org.trustedKey=tobira
diff --git a/etc/org.opencastproject.adminui.cfg b/etc/org.opencastproject.adminui.impl.AdminUIConfiguration.cfg
similarity index 100%
rename from etc/org.opencastproject.adminui.cfg
rename to etc/org.opencastproject.adminui.impl.AdminUIConfiguration.cfg
diff --git a/etc/org.opencastproject.db.DBSessionFactoryImpl.cfg b/etc/org.opencastproject.db.DBSessionFactoryImpl.cfg
new file mode 100644
index 0000000000..0ae43ab46b
--- /dev/null
+++ b/etc/org.opencastproject.db.DBSessionFactoryImpl.cfg
@@ -0,0 +1,7 @@
+# DB query execution configuration
+
+# Depending on the configured transaction isolation level, the database might refuse to commit a transaction. In this
+# case, Opencast will attempt to execute the transaction again. This configures how many retries will be attempted.
+#
+# Default: 5
+#transaction.retries.max=5
diff --git a/etc/org.opencastproject.editor.EditorServiceImpl.cfg b/etc/org.opencastproject.editor.EditorServiceImpl.cfg
index 6a4d73188c..2338bf580a 100644
--- a/etc/org.opencastproject.editor.EditorServiceImpl.cfg
+++ b/etc/org.opencastproject.editor.EditorServiceImpl.cfg
@@ -30,6 +30,14 @@
# Default: */silence
#smil.silence.flavor=*/silence
+# Sets the flavor subtype of the waveform images
+# Default: waveform
+#waveform.subtype=waveform
+
+# Sets the flavor for captions. All captions file must conform to this flavor
+# Default: captions/*
+#captions.flavor=captions/*
+
# Stream Security Configuration:
# For further information please see:
@@ -45,3 +53,29 @@
# If this property is true then signed URLs for editing / previewing, such as videos accessed by the preview or editor
# player will be limited to the IP address of the client making the original request.
# url.signing.use.client.ip=true
+
+# The subtype of thumbnail images. Should match the subtype you are using in your workflows.
+# thumbnail.subtype=player+preview
+
+# If thumbnails are added from the editor, a workflow property will be set
+# The workflow property will look like "flavor.type/thumbnail.workflow.property"
+# thumbnail.workflow.property=thumbnail_edited
+
+# In Opencast workflows, one track is often used as the primary flavor for thumbnail generations, while other
+# tracks/flavors are used as fallbacks. Here you can specify a priority list to tell the editor frontend which
+# flavors are most important. The first flavor in the list will be the primary flavor, the second the secondary flavor
+# and so forth.
+# Flavors need to be fully qualified, separated by comma.
+# Example: thumbnail.priority.flavor=presenter/preview,presentation/preview
+#thumbnail.priority.flavor=
+
+# Indicator if publications are available locally from this server.
+# This should usually be the case if your download directory lives on an NFS mount.
+# Based on this, the editor front-end can decide to modify the location of requested files.
+#
+# The value can be a boolean or `auto`.
+# Set to auto, the code will determine if files are available locally by checking if the files returned in the first
+# request exist locally.
+#
+# Default: auto
+#publication.local = auto
diff --git a/etc/org.opencastproject.elasticsearch.index.ElasticsearchIndex.cfg b/etc/org.opencastproject.elasticsearch.index.ElasticsearchIndex.cfg
index 1973cc18f8..af52ab7783 100644
--- a/etc/org.opencastproject.elasticsearch.index.ElasticsearchIndex.cfg
+++ b/etc/org.opencastproject.elasticsearch.index.ElasticsearchIndex.cfg
@@ -1,10 +1,31 @@
# Elasticsearch index configuration
+# Config that cannot be updated during runtime:
+
# The base identifier of the Elasticsearch index. Subindices will be named after the following schema:
# identifier_subindex, e.g. opencast_event. If an index with this name doesn't exist, Opencast will create it.
# Default: opencast
#index.identifier=opencast
+# Config that can be updated during runtime:
+
# The index name. Will be used for logging.
# Default: Elasticsearch
#index.name=Elasticsearch
+
+# How many times to retry get requests to the Elasticsearch in case of ElasticsearchStatusException.
+# Default: 0
+#max.retry.attempts.get=0
+
+# How many times to retry update requests to the Elasticsearch in case of ElasticsearchStatusException (includes reads
+# necessary for updates).
+# Default: 0
+#max.retry.attempts.update=0
+
+# How long to wait between retry attempts of get requests (in milliseconds).
+# Default: 1s
+#retry.waiting.period.get=1000
+
+# How long to wait between retry attempts of update requests (in milliseconds).
+# Default: 1s
+#retry.waiting.period.update=1000
\ No newline at end of file
diff --git a/etc/org.opencastproject.external.userdirectory.ExternalGroupLoader.cfg b/etc/org.opencastproject.external.userdirectory.ExternalGroupLoader.cfg
new file mode 100644
index 0000000000..926a32b2a5
--- /dev/null
+++ b/etc/org.opencastproject.external.userdirectory.ExternalGroupLoader.cfg
@@ -0,0 +1,9 @@
+##############################################################################
+# External Group Loader Configuration
+##############################################################################
+
+# This configuration lets you deactivate the creation of default groups for
+# the external api.
+#
+# Default: true
+#create_default_groups = true
diff --git a/etc/org.opencastproject.index.service.resources.list.provider.ContributorsListProvider.cfg b/etc/org.opencastproject.index.service.resources.list.provider.ContributorsListProvider.cfg
index 6c1875c698..c97e03d222 100644
--- a/etc/org.opencastproject.index.service.resources.list.provider.ContributorsListProvider.cfg
+++ b/etc/org.opencastproject.index.service.resources.list.provider.ContributorsListProvider.cfg
@@ -8,6 +8,7 @@
# - canvas: Canvas user provider
# - moodle: Moodle referenced users
# - sakai: Sakai referenced users
+# - studip: Studip referenced users
# A special value to match all available providers is: `*`.
# This can improve the performance quite a bit if you do not need the users.
# Default value:
diff --git a/etc/org.opencastproject.ingest.impl.IngestServiceImpl.cfg b/etc/org.opencastproject.ingest.impl.IngestServiceImpl.cfg
index 3665184d3e..f5b191751a 100644
--- a/etc/org.opencastproject.ingest.impl.IngestServiceImpl.cfg
+++ b/etc/org.opencastproject.ingest.impl.IngestServiceImpl.cfg
@@ -49,8 +49,20 @@
# The credentials can be set for an external source (example: https://develop.opencast.org).
# For example, this can be used to make Opencast download files from another Opencast.
# The source is written as a regular expression.
+# auth.method can either be "Digest" or "Basic".
+# If auth.force_basic is true and method is Basic requests are always authenticated.
# Example for two sources: (.*)//develop.opencast.org/(.*)|(.*)//stable.opencast.org/(.*)
# Default:
#org.opencastproject.download.source = http://localhost/.*
+#org.opencastproject.download.auth.method = Digest
+#org.opencastproject.download.auth.force_basic = false
#org.opencastproject.download.user = opencast_system_account
#org.opencastproject.download.password = CHANGE_ME
+
+# Set the string added to the name of auto generated CA series. Events without series are added to the corresponding CA
+# series if set. This ensures that an event without series is still accessible for users with rights to the CA. Leaving
+# the string blank deactivates this function.
+#
+# Default:
+#
+#add.series.to.event.appendix = _CA_series
diff --git a/etc/org.opencastproject.liveschedule.impl.LiveScheduleServiceImpl.cfg b/etc/org.opencastproject.liveschedule.impl.LiveScheduleServiceImpl.cfg
index e351312abb..602c1c3e9d 100644
--- a/etc/org.opencastproject.liveschedule.impl.LiveScheduleServiceImpl.cfg
+++ b/etc/org.opencastproject.liveschedule.impl.LiveScheduleServiceImpl.cfg
@@ -9,8 +9,13 @@
# The base URL that the player will use to play the live stream
#live.streamingUrl=http://streaming.server/hls/
-# If a comma-separated list is provided, several resolutions will be generated for each flavor
-live.resolution=1920x540,960x270
+# If a comma-separated list is provided, several resolutions will be generated for each flavor.
+#
+# The default resolution is 16:9, a very typical aspect ratio nowadays. If your
+# capture agent's default is to stream two 16:9 images stitched together, as an
+# extra wide presenter and presentation video, parted later in an Opencast
+# workflow, it may help to set the resolution to 32:9: 1920x540,960x270.
+live.resolution=1920x1080,1280x720
# Possible variable substitutions:
# #{id} = media package id
diff --git a/etc/org.opencastproject.liveschedule.message.SchedulerUpdateHandler.cfg b/etc/org.opencastproject.liveschedule.message.SchedulerUpdateHandler.cfg
new file mode 100644
index 0000000000..cced9c32dc
--- /dev/null
+++ b/etc/org.opencastproject.liveschedule.message.SchedulerUpdateHandler.cfg
@@ -0,0 +1,9 @@
+##############################################################################
+# Liveschedule Update Handler Configuration
+##############################################################################
+
+# This config option can be used to disable the deletion of live events when
+# the capturing has failed.
+#
+# Default: true
+#live.deleteOnCapureError = true
diff --git a/etc/org.opencastproject.lti.service.impl.LtiServiceImpl.cfg b/etc/org.opencastproject.lti.service.impl.LtiServiceImpl.cfg
index 2f3cb146f5..6ff4b01d04 100644
--- a/etc/org.opencastproject.lti.service.impl.LtiServiceImpl.cfg
+++ b/etc/org.opencastproject.lti.service.impl.LtiServiceImpl.cfg
@@ -5,3 +5,8 @@ workflow-configuration={"flagForCutting":"false","flagForReview":"false","publis
# After deletion, events are retracted with this workflow
retract-workflow-id=retract
copy-workflow-id=copy-event-to-series
+
+# Whether list all jobs in series (include jobs created by other instructors).
+# Or, show jobs created by current user only.
+# default: false
+#list-all-jobs-in-series=false
diff --git a/etc/org.opencastproject.organization-mh_default_org.cfg b/etc/org.opencastproject.organization-mh_default_org.cfg
index 9f048fcfc3..34615816d3 100644
--- a/etc/org.opencastproject.organization-mh_default_org.cfg
+++ b/etc/org.opencastproject.organization-mh_default_org.cfg
@@ -178,8 +178,8 @@ prop.adminui.user.external_role_display=false
# Path to the default video player used by the engage interfaces and the LTI tools. Parameters for selecting the
# specific videos will be appended automatically. Common values include:
#
-# - theodul player: /engage/theodul/ui/core.html?id=#{id}
-# - paella player: /paella/ui/watch.html?id=#{id}
+# - paella player: /paella/ui/watch.html?id=#{id}
+# - paella player 7 (beta): /paella7/ui/watch.html?id=#{id}
#
# Default: /paella/ui/watch.html?id=#{id}
#prop.player=/paella/ui/watch.html?id=#{id}
@@ -217,6 +217,11 @@ prop.admin.shortcut.general.select_next_dashboard_filter=f
prop.admin.shortcut.general.select_previous_dashboard_filter=F
prop.admin.shortcut.general.main_menu=m
+# Shortcut definitions for admin UI add-event and add-series modals
+# Format: prop.admin.shortcut.add_media.=
+prop.admin.shortcut.add_media.next_tab=shift+alt+right
+prop.admin.shortcut.add_media.previous_tab=shift+alt+left
+
# Default values for fields in the tab Source of the Add Event wizard
#
# Automatically populates fields in the tab Source of the Add Event wizard.
@@ -315,6 +320,12 @@ prop.admin.shortcut.general.main_menu=m
# Default: optional
#prop.admin.series.acl.event.update.mode=optional
+# Whether the ACL of a new event is initialized with the ACL of its series.
+#
+# Format: Boolean
+# Default: true
+#prop.admin.init.event.acl.with.series.acl=true
+
# Default values for trim segment in the editor.
# Default: In milliseconds
#
diff --git a/etc/org.opencastproject.plugin.impl.PluginManagerImpl.cfg b/etc/org.opencastproject.plugin.impl.PluginManagerImpl.cfg
new file mode 100644
index 0000000000..18f9a1d086
--- /dev/null
+++ b/etc/org.opencastproject.plugin.impl.PluginManagerImpl.cfg
@@ -0,0 +1,20 @@
+###
+# Opencast Plugins
+#
+# This configuration allows you to turn additional functionality of Opencast off and on.
+# Plugins can be enabled at runtime.
+##
+
+# List of available plugins
+opencast-plugin-legacy-annotation = off
+opencast-plugin-transcription-services = off
+opencast-plugin-userdirectory-brightspace = off
+opencast-plugin-userdirectory-canvas = off
+opencast-plugin-userdirectory-moodle = off
+opencast-plugin-userdirectory-sakai = off
+opencast-plugin-userdirectory-studip = off
+opencast-plugin-usertracking = off
+
+# Enables Karaf's verbose feature activateion logs.
+# Note that Karaf writes these to stdout, not to the logger.
+verbose = false
diff --git a/etc/org.opencastproject.scheduler.conflict.handler.DefaultSchedulerConflictHandler.cfg b/etc/org.opencastproject.scheduler.conflict.handler.DefaultSchedulerConflictHandler.cfg
deleted file mode 100644
index 41035f9fb4..0000000000
--- a/etc/org.opencastproject.scheduler.conflict.handler.DefaultSchedulerConflictHandler.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-# Configuration option for the scheduler conflict handler. Two options are available:
-# - old (the old existing event takes precedence)
-# - new (the new updated event takes precedence)
-# Default: old
-#handler=old
diff --git a/etc/org.opencastproject.scheduler.conflict.notifier.email.EmailSchedulerConflictNotifier.cfg b/etc/org.opencastproject.scheduler.conflict.notifier.email.EmailSchedulerConflictNotifier.cfg
deleted file mode 100644
index 1d78f74691..0000000000
--- a/etc/org.opencastproject.scheduler.conflict.notifier.email.EmailSchedulerConflictNotifier.cfg
+++ /dev/null
@@ -1,18 +0,0 @@
-# Configuration options for the email scheduler conflict notifier.
-
-# The recipient of the notification emails. Not setting this will disable the notifications.
-# Default: none
-#to=info@opencast.org
-
-# Subject of the notification mails
-# Default: "Scheduling conflict"
-#subject=Scheduling conflict
-
-# Email template for the notification mail. The placeholder ${recordings} will be replaced with the list of conflicting
-# events.
-# Default:
-# Dear Administrator,
-# the following scheduled recordings are conflicting with existing ones:
-#
-# ${recordings}
-#template=Dear Administrator,\nthe following scheduled recordings are conflicting with existing ones:\n\n${recordings}
diff --git a/etc/org.opencastproject.serviceregistry.impl.JobDispatcher.cfg b/etc/org.opencastproject.serviceregistry.impl.JobDispatcher.cfg
new file mode 100644
index 0000000000..a28936239d
--- /dev/null
+++ b/etc/org.opencastproject.serviceregistry.impl.JobDispatcher.cfg
@@ -0,0 +1,8 @@
+# Configuration for the job dispatcher
+
+# The interval in seconds between two rounds of dispatching in the service registry. A minimum value of 1s is enforced
+# due to performance reasons. Set to 0 to disable dispatching from this service registry. Default for the job dispatch
+# node is 2. Service registry dispatching is automatically set to 0 on everything but admin or allinone nodes and should
+# usually not be activated on these nodes to avoid concurrency problems.
+# Default: 0
+#dispatch.interval=0
diff --git a/etc/org.opencastproject.serviceregistry.impl.ServiceRegistryJpaImpl.cfg b/etc/org.opencastproject.serviceregistry.impl.ServiceRegistryJpaImpl.cfg
index c73f1a7159..f5ee14f7f2 100644
--- a/etc/org.opencastproject.serviceregistry.impl.ServiceRegistryJpaImpl.cfg
+++ b/etc/org.opencastproject.serviceregistry.impl.ServiceRegistryJpaImpl.cfg
@@ -8,13 +8,6 @@
# Default: None
#no.error.state.service.types=
-# The interval in seconds between two rounds of dispatching in the service registry. A minimum value of 1s is enforced
-# due to performance reasons. Set to 0 to disable dispatching from this service registry.
-# Service registry dispatching is automatically set to 0 on everything but admin or allinone nodes and should usually
-# not be activated on these nodes to avoid concurrency problems.
-# Default: 2
-#dispatch.interval=2
-
# The interval in seconds between checking if the hosts in the service registry hosts are still alive.
# Set to 0 to disable checking if hosts are still alive and able to be dispatched to.
# Default: 60
@@ -28,3 +21,13 @@
# Note that this setting does have a large impact on the performance of service statistics generation.
# Default: 14
#org.opencastproject.statistics.services.max_job_age = 14
+
+
+# Comma-separated list of encoding specialized worker nodes. Specified workers are preferred when dispatching encoding jobs.
+# Default: empty
+#org.opencastproject.encoding.workers=http://example.com, http://example1.com:8080
+
+# Numeric value between 0 and 1. Sets an load value under which specified encoding workers are preferred over other workers when dispatching encoding jobs.
+# A value of 0.2 corresponds to a threshold of 20% worker load
+# Default: 0.0
+#org.opencastproject.encoding.workers.threshold=
diff --git a/etc/org.opencastproject.speechtotext.impl.SpeechToTextServiceImpl.cfg b/etc/org.opencastproject.speechtotext.impl.SpeechToTextServiceImpl.cfg
index ce9ba0bc5b..748baa9c01 100644
--- a/etc/org.opencastproject.speechtotext.impl.SpeechToTextServiceImpl.cfg
+++ b/etc/org.opencastproject.speechtotext.impl.SpeechToTextServiceImpl.cfg
@@ -1,3 +1,7 @@
# Job load for a speech-to-text job
# Default: 0.8
#job.load.speechtotext=0.8
+
+# Select STT engine.
+# Available engines: vosk, whisper | Default: vosk
+#SpeechToTextEngine.target=(enginetype=vosk)
diff --git a/etc/org.opencastproject.speechtotext.impl.engine.WhisperEngine.cfg b/etc/org.opencastproject.speechtotext.impl.engine.WhisperEngine.cfg
new file mode 100644
index 0000000000..1f7fea2d89
--- /dev/null
+++ b/etc/org.opencastproject.speechtotext.impl.engine.WhisperEngine.cfg
@@ -0,0 +1,8 @@
+# Configuration for setting a custom path to the Whisper command line tool
+# Default: whisper
+#whisper.root.path=whisper
+
+# Model to use in whisper
+# Available models: tiny, base, medium, large.
+# Default: base
+#whisper.model=base
diff --git a/etc/org.opencastproject.transcription.amberscript.AmberscriptTranscriptionService.cfg b/etc/org.opencastproject.transcription.amberscript.AmberscriptTranscriptionService.cfg
index faaf812333..e9e48ba456 100644
--- a/etc/org.opencastproject.transcription.amberscript.AmberscriptTranscriptionService.cfg
+++ b/etc/org.opencastproject.transcription.amberscript.AmberscriptTranscriptionService.cfg
@@ -8,6 +8,26 @@
# Can be one of: nl, en, de, fr, da, sv, fi, no, es
# language=en
+# Set to true if the transcription language should be taken from the dublincore catalog
+# If the dublincore catalog doesn't contain a language, the default process for determine
+# the language will be taken. Note, that the language field in the workflow operation
+# will be overwritten, in case the dublincore catalog has a language
+# Default=false
+#language.from.dublincore=false
+
+# Manual mapping for language codes
+# Here you can set which language spellings/codes from your system shall be
+# mapped to the corresponding amberscript language. In general the amberscript workflow
+# should figure it out by itself. Use this, if you have some special language strings and run into errors
+# You can map a language to the amberscript code with a Colon ':'
+# You can separate multiple mappings with a comma ','
+# Examples:
+# language.code.map=english:en
+# language.code.map=german:de,french:fr,spanish:es
+# language.code.map=SomeWeirdL4nguageC0de:en
+# These are three different examples, please note that you can specify 'language.code.map' only once
+#language.code.map=
+
# Default Job Type to use
# You can override this within you workflow (see workflowoperationhandler amberscript-start-transcription).
# Default: direct
@@ -17,9 +37,9 @@
# AmberScript API key
client.key=
-# Workflow to be executed when results are ready to be attached to media package
-# Defaults: amberscript-attach-transcripts.xml
-#workflow=amberscript-attach-transcripts.xml
+# Workflow to be executed when results are ready to be attached to media package (workflow-id)
+# Defaults: amberscript-attach-transcripts
+#workflow=amberscript-attach-transcripts
# Interval the workflow dispatcher runs to start workflows to attach transcripts to the media package
# after the transcription job is completed.
@@ -34,3 +54,11 @@ client.key=
# How long to keep result files in the working file repository in days.
# The default is 7 days.
#cleanup.results.days=7
+
+# Configure which metadata field shall be considered when "counting" the
+# number of speakers. The "presenter" or the "contributor" field.
+# Note for developers: the "presenter" becomes the "creator" in the Operation Handler
+# possible values: presenter, contributor, both
+# Both means, that both list will be joined (Union)
+# The default is presenter
+#speaker.metadata.field=presenter
diff --git a/etc/org.opencastproject.transcription.googlespeech.GoogleSpeechTranscriptionService.cfg b/etc/org.opencastproject.transcription.googlespeech.GoogleSpeechTranscriptionService.cfg
index 7050522d53..c40c87dad2 100644
--- a/etc/org.opencastproject.transcription.googlespeech.GoogleSpeechTranscriptionService.cfg
+++ b/etc/org.opencastproject.transcription.googlespeech.GoogleSpeechTranscriptionService.cfg
@@ -21,6 +21,17 @@ google.cloud.storage.bucket=
# Filter out profanities from result. Default is false
#google.speech.profanity.filter=false
+# Enable punctuations for transcription. Default is false
+# List of languages with punctuation support: https://cloud.google.com/speech-to-text/docs/languages
+#google.speech.transcription.punctuation=false
+
+# Transcription model to use
+# If empty, the "default" model will be used
+# List of models: https://cloud.google.com/speech-to-text/docs/transcription-model
+# model "video" best for videos currently works with language set to en-US:
+# https://cloud.google.com/speech-to-text/docs/languages
+#google.speech.transcription.model=default
+
# Audio encoding extension.
# The value will be used to store the audio file as [medidpackage_id].[extension] in the Google storage bucket
# If empty the he default will be used (flac)
diff --git a/etc/org.opencastproject.transcription.microsoftazure.MicrosoftAzureTranscriptionService.cfg b/etc/org.opencastproject.transcription.microsoftazure.MicrosoftAzureTranscriptionService.cfg
new file mode 100644
index 0000000000..277db50e0d
--- /dev/null
+++ b/etc/org.opencastproject.transcription.microsoftazure.MicrosoftAzureTranscriptionService.cfg
@@ -0,0 +1,84 @@
+# Change enabled to true to enable this service.
+enabled=false
+
+# Microsoft Azure Service details
+subscription.key=
+region=
+
+# Language code of the supplied audio. See the Google Speech-to-Text service documentation
+# for available languages. If empty, the default will be used ("en-US").
+# List of supported languages: https://learn.microsoft.com/en-us/azure/cognitive-services/speech-service/language-support?tabs=stt-tts
+#language=en-US
+
+# Setting this option will prompt Azure to detect the spoken language by itself. Language is detected once at the
+# start of the media file. Auto detection will take precedence over a defined language.
+# Default: false
+#auto.detect.language=false
+
+# A list of language codes. The Azure language auto detection will pick it's detected language from one of these.
+# The language auto detection cannot detect any languages not specified in this list.
+# The list needs to have at least one element and can have at most four elements.
+# List of supported languages: https://learn.microsoft.com/en-us/azure/cognitive-services/speech-service/language-support?tabs=language-identification
+# Example: en-US,de-DE,fr-FR,it-IT
+# Default: None
+#auto.detect.languages=
+
+# Filter out profanities from result. Valid values: raw, remove, mask
+# Raw: Includes the profanity in the result.
+# Remove: Removes all profanity from the result.
+# Mask: Replaces profanity with asterisks.
+#profanity.option=Raw
+
+# Default is VTT. Set this to true if you want SRT instead.
+#use.subrip.format=false
+
+# A phrase list is a list of words or phrases provided ahead of time to help improve their recognition. Adding a phrase
+# to a phrase list increases its importance, thus making it more likely to be recognized.
+# Maximum of 500 phrases, provided as a commma seperated list
+# Examples: Names, Geographical locations, Homonyms, Words or acronyms unique to your industry or organization
+# Example: Opencast,Github,ETH,Osnabrück
+#phrases.list=
+
+# Audio stream container format
+# Format of the source file. If you are not explicitely converting your files to the mentioned format prior to sending
+# them to the transcription service, leave this as ANY
+# Possible values: ALAW, AMRNB, AMRWB, ANY, FLAC, MP3, MULAW, OGG_OPUS
+# Default: ANY
+#encoding.extension=ANY
+
+# Set this to true if you want to limit the maximum size of a line in the subtitle file.
+# Azure does not do this automatically, and sometimes produces very long lines.
+# Default: false
+#split.text=false
+
+# The maximum amount of characters a single line in the subtitle file should contain.
+# Can go over the set number to avoid cutting words in half.
+# Only takes effect if "split.text" is set to true.
+# Default: 100
+#split.text.line.size=100
+
+# Workflow to be executed when results are ready to be attached to media package.
+#workflow=microsoft-azure-attach-transcripts
+
+# Interval the workflow dispatcher runs to start workflows to attach transcripts to the media package
+# after the transcription job is completed.
+# (in seconds) Default is 1 minute.
+#workflow.dispatch.interval=60
+
+# How long it should wait to check jobs after their start date + track duration has passed.
+# The default is 5 minutes.
+# (in seconds)
+#completion.check.buffer=300
+
+# How long to wait after a transcription is supposed to finish before marking the job as
+# cancelled in the database. Default is 5 hours.
+# (in seconds)
+#max.processing.time=18000
+
+# How long to keep result files in the working file repository in days.
+# The default is 7 days.
+#cleanup.results.days=7
+
+# Email to send notifications of errors. If not entered, the value from
+# org.opencastproject.admin.email in custom.properties will be used.
+#notification.email=
diff --git a/etc/org.opencastproject.ui.metadata.CatalogUIAdapterFactory-episode-common.cfg b/etc/org.opencastproject.ui.metadata.CatalogUIAdapterFactory-episode-common.cfg
index 954a633737..537aeadfec 100644
--- a/etc/org.opencastproject.ui.metadata.CatalogUIAdapterFactory-episode-common.cfg
+++ b/etc/org.opencastproject.ui.metadata.CatalogUIAdapterFactory-episode-common.cfg
@@ -1,5 +1,5 @@
type=events
-organization=mh_default_org
+organization=*
flavor=dublincore/episode
title=EVENTS.EVENTS.DETAILS.CATALOG.EPISODE
common-metadata=true
diff --git a/etc/org.opencastproject.ui.metadata.CatalogUIAdapterFactory-series-common.cfg b/etc/org.opencastproject.ui.metadata.CatalogUIAdapterFactory-series-common.cfg
index db2bc0c363..d627b2fb8f 100644
--- a/etc/org.opencastproject.ui.metadata.CatalogUIAdapterFactory-series-common.cfg
+++ b/etc/org.opencastproject.ui.metadata.CatalogUIAdapterFactory-series-common.cfg
@@ -1,5 +1,5 @@
type=series
-organization=mh_default_org
+organization=*
title=Series Metadata
flavor=dublincore/series
common-metadata=true
diff --git a/etc/org.opencastproject.userdirectory.brightspace-default.cfg.template b/etc/org.opencastproject.userdirectory.brightspace-default.cfg.template
index fcfcbaebb0..d956ee4d01 100644
--- a/etc/org.opencastproject.userdirectory.brightspace-default.cfg.template
+++ b/etc/org.opencastproject.userdirectory.brightspace-default.cfg.template
@@ -19,6 +19,11 @@ org.opencastproject.userdirectory.brightspace.application.key=application-key
# The maximum number of minutes to cache a user
#org.opencastproject.userdirectory.brightspace.cache.expiration=60
+# Optional comma-separated list of Brightspace roles which are mapped to Instructor role suffix in Opencast
+# default: TEACHER
+#org.opencastproject.userdirectory.brightspace.instructor.roles=TEACHER
-
+# Optional comma-separated list of usernames, which opencast wouldn't ask Brightspace for user's detail.
+# default: admin,anonymous
+#org.opencastproject.userdirectory.brightspace.ignored.usernames=admin,anonymous
diff --git a/etc/org.opencastproject.userdirectory.ldap.cfg.template b/etc/org.opencastproject.userdirectory.ldap.cfg.template
index 0e7218285e..5303b4e442 100644
--- a/etc/org.opencastproject.userdirectory.ldap.cfg.template
+++ b/etc/org.opencastproject.userdirectory.ldap.cfg.template
@@ -50,6 +50,19 @@ org.opencastproject.userdirectory.ldap.roleattributes=
#org.opencastproject.userdirectory.ldap.userDn=
#org.opencastproject.userdirectory.ldap.password=
+## The attributes used to construct the user details.
+## If left empty, the user details wont be mapped.
+## The name config key is a comma-separated list of attributes that will be joined
+## with a whitespace character in the order they appear.
+## Example:
+## org.opencastproject.userdirectory.ldap.userattributes.name=givenName,sn
+## org.opencastproject.userdirectory.ldap.userattributes.mail=mail
+## Result:
+## name: John Doe
+## mail: john.doe@example.org
+#org.opencastproject.userdirectory.ldap.userattributes.name=
+#org.opencastproject.userdirectory.ldap.userattributes.mail=
+
## The maximum number of users to cache
## Default: 1000
#org.opencastproject.userdirectory.ldap.cache.size=1000
diff --git a/etc/org.opencastproject.userdirectory.studip-default.cfg.template b/etc/org.opencastproject.userdirectory.studip-default.cfg.template
new file mode 100644
index 0000000000..f5ca1267a0
--- /dev/null
+++ b/etc/org.opencastproject.userdirectory.studip-default.cfg.template
@@ -0,0 +1,19 @@
+# Studip UserDirectoryProvider configuration
+
+# This is an an optional service which is not enabled by default. To enable it,
+# edit etc/org.apache.karaf.features.cfg and add opencast-studip to the featuresBoot option.
+
+# The organization for this provider
+org.opencastproject.userdirectory.studip.org=mh_default_org
+
+# The URL and token for the Studip REST webservice
+org.opencastproject.userdirectory.studip.url=https://my-studip.de/studip5/plugins.php/opencast/api/
+org.opencastproject.userdirectory.studip.token=mytoken1234abcdef
+
+# The maximum number of users to cache
+# Default: 1000
+#org.opencastproject.userdirectory.studip.cache.size=1000
+
+# The maximum number of minutes to cache a user
+# Default: 60
+#org.opencastproject.userdirectory.studip.cache.expiration=60
diff --git a/etc/org.opencastproject.videoeditor.impl.VideoEditorServiceImpl.cfg b/etc/org.opencastproject.videoeditor.impl.VideoEditorServiceImpl.cfg
index 2031f72c5f..df8ab70ade 100644
--- a/etc/org.opencastproject.videoeditor.impl.VideoEditorServiceImpl.cfg
+++ b/etc/org.opencastproject.videoeditor.impl.VideoEditorServiceImpl.cfg
@@ -1,8 +1,8 @@
# The following options are used by the ffmpeg video editor
# fade in/out time in seconds
-audio.fade = 2
-video.fade = 2
+audio.fade = 0.2
+video.fade = 0.2
# if not specified, default codec is same as input file
audio.codec = aac
@@ -10,9 +10,9 @@ video.codec = libx264
# ffmpeg general options for file quality
# This is a temporary file, so it doesn't have to be generic, the default is ffmpeg only - lossless
-# ffmpeg.properties = -strict -2 -preset ultrafast -qp 0 -tune film
+# ffmpeg.properties = -preset ultrafast -qp 0 -tune film
# DO NOT use filters here, it will conflict with -complex-filter in the editor
-ffmpeg.properties = -strict -2 -preset veryfast -crf 18 -tune film -map_metadata -1 -map_chapters -1 -sn -dn
+ffmpeg.properties = -preset veryfast -crf 18 -tune film -map_metadata -1 -map_chapters -1 -sn -dn
# preset can be: ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow. Default is medium
# faster = larger output file
diff --git a/etc/org.opencastproject.workflow.impl.WorkflowServiceImpl.cfg b/etc/org.opencastproject.workflow.impl.WorkflowServiceImpl.cfg
deleted file mode 100644
index eb6fe02c3e..0000000000
--- a/etc/org.opencastproject.workflow.impl.WorkflowServiceImpl.cfg
+++ /dev/null
@@ -1,4 +0,0 @@
-# Configuration for the workflow service
-
-# Whether to collect JMX statistics on the workflows, default is false
-workflowstats.collect=false
diff --git a/etc/org.opencastproject.workingfilerepository.impl.WorkingFileRepository.cfg b/etc/org.opencastproject.workingfilerepository.impl.WorkingFileRepository.cfg
new file mode 100644
index 0000000000..ecf75d0ae5
--- /dev/null
+++ b/etc/org.opencastproject.workingfilerepository.impl.WorkingFileRepository.cfg
@@ -0,0 +1,21 @@
+# Filename pattern of forbidden characters
+#
+# Opencast will filter out dangerous pattern from file names in order to make these compatible with different operating
+# and file systems and to prevent local security risks like path traversal. For example, the default conversion would
+# look like this:
+#
+# original: -problematic-file/../name&&&%.ext
+# converted: _problematic-file_.._name____.ext
+#
+# This option allows you to control which characters are not allowed. All parts of the file name matched by the
+# configured pattern will be replaced by `_`. The replacement is applied separately to the base file name and the
+# extension. In any case, both base name and extension are limited to 255 characters each.
+#
+# WARNING: This setting is dangerous. It lets you configure Opencast in a way that poses a security risk to your system
+# by e.g. allowing for path traversal attacks.
+# BETA: For a long time, this was a very restricted, fixed value. Consider this to be an unstable configuration which
+# might lead to problems since some component somewhere assumes the old restricted behavior. Test your system
+# very carefully after changing this. Feedback about problems and successful changes are welcome.
+#
+# Default: (^\\W|[^\\w-.])
+#filename.forbidden.pattern = (^\\W|[^\\w-_.])
diff --git a/etc/security/mh_default_org.xml b/etc/security/mh_default_org.xml
index 4f0ec3c269..16939bc285 100644
--- a/etc/security/mh_default_org.xml
+++ b/etc/security/mh_default_org.xml
@@ -85,9 +85,11 @@
+
+
@@ -219,6 +221,7 @@
+
@@ -273,9 +276,12 @@
-
+
+
+
+
@@ -298,7 +304,11 @@
-
+
+
+
+
+
@@ -332,15 +342,20 @@
+
+
+
+
+
@@ -354,26 +369,19 @@
-
+
+
-
-
-
-
@@ -438,12 +446,24 @@
+
+
+
+
+
+
+
+
+
+
+
@@ -479,6 +499,7 @@
+
@@ -486,6 +507,13 @@
+
+
+
@@ -696,7 +724,14 @@
-
+ -->
+
+
+
+
@@ -819,7 +863,7 @@
-
+
-
-
-
- true
-
-
-
-
-
-
-
- false
- false
-
-
-
-
-
-
-
- */source
- */preview
- engage-download,engage-streaming,rss,atom
- fast.http
-
-
-
-
-
-
-
- */source
- */search+preview
- engage-download
- search-cover.http
- 1
-
-
-
-
-
-
-
- */source
- */player+preview
- engage-download
- player-preview.http
- 1
-
-
-
-
-
-
-
- presentation/source
- engage-download
-
-
-
-
-
-
-
- presentation/source
- presentation/segment+preview
- engage-download
- engage-download
- player-slides.http
-
-
-
-
-
-
-
- */preview
- internal
- ${org_org_opencastproject_admin_ui_url!'http://localhost:8080'}/admin-ng/index.html#/events/events/${event_id}/tools/editor
- false
-
-
-
-
-
-
-
- dublincore/*,security/*
- engage-download
- false
-
-
-
-
-
-
-
- */source,dublincore/*,security/*
-
-
-
-
-
-
-
-
-
- true
-
- security/*
-
-
-
-
-
diff --git a/etc/workflows/fast.yaml b/etc/workflows/fast.yaml
new file mode 100644
index 0000000000..97cebcea43
--- /dev/null
+++ b/etc/workflows/fast.yaml
@@ -0,0 +1,130 @@
+---
+id: fast
+title: Fast Testing Workflow
+tags:
+ - upload
+ - schedule
+displayOrder: 100
+description: |-
+ A minimal workflow that transcodes media into distribution formats,
+ then publishes the resulting distribution files, along with their associated metadata.
+configuration_panel: |-
+