diff --git a/CHANGELOG.md b/CHANGELOG.md
index d2618baec..9f807dd8e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,25 @@
# Change Log
+## [5.6.0]
+- Introduced Dynamic Workflows
+
+## [5.5.0]
+- Updated to Opencast API 1.5.0
+- Introduced Publication Usages and solved issue #182
+
+## [5.4.1]
+- Fixed a compatibility issue in the new caching service.
+
+## [5.4.0]
+- Implemented improved Caching Service which fixes #194
+
+## [5.3.2]
+- Fix #220: Upload of large files lead to a memory limit error.
+- Fixed the Overlay when creating a new Event.
+
+## [5.3.1]
+- Fix #11 and #113: Introducing new Paella 7 Player
+
## [5.3.0]
- Implemented #193: The Chunk Size for Uploads is now configurable. The default value is 20MB, this can be changes in the plugin configuration.
- Fix #176: Fixed a static timeout in fileuploads, this now uses max_execution_time of the server.
diff --git a/classes/Conf/PermissionTemplates/class.xoctPermissionTemplateTableGUI.php b/classes/Conf/PermissionTemplates/class.xoctPermissionTemplateTableGUI.php
index 9a207280b..dc7762a8d 100644
--- a/classes/Conf/PermissionTemplates/class.xoctPermissionTemplateTableGUI.php
+++ b/classes/Conf/PermissionTemplates/class.xoctPermissionTemplateTableGUI.php
@@ -57,7 +57,8 @@ public function __construct(xoctPermissionTemplateGUI $a_parent_obj, $a_parent_c
$b->setUrl($this->ctrl->getLinkTarget($a_parent_obj, xoctPermissionTemplateGUI::CMD_ADD));
$this->addCommandButtonInstance($b);
- xoctWaiterGUI::initJS();
+ new WaitOverlay($this->main_tpl); // TODO check if needed
+
$this->main_tpl->addJavaScript($this->plugin->getDirectory() . '/templates/default/sortable.js');
$base_link = $this->ctrl->getLinkTarget($this->parent_obj, 'reorder', '', true);
$this->main_tpl->addOnLoadCode("xoctSortable.init('" . $base_link . "');");
diff --git a/classes/Conf/PublicationUsage/class.xoctPublicationGroupFormGUI.php b/classes/Conf/PublicationUsage/class.xoctPublicationGroupFormGUI.php
new file mode 100644
index 000000000..11e02f61a
--- /dev/null
+++ b/classes/Conf/PublicationUsage/class.xoctPublicationGroupFormGUI.php
@@ -0,0 +1,154 @@
+
+ */
+class xoctPublicationGroupFormGUI extends ilPropertyFormGUI
+{
+ public const F_NAME = 'name';
+ public const F_DISPLAY_NAME = 'display_name';
+ public const F_DESCRIPTION = 'description';
+ public const F_DISPLAY_NAME_MAX_LENGTH = 10;
+
+ /**
+ * @var PublicationUsageGroup
+ */
+ protected $object;
+ /**
+ * @var xoctPublicationUsageGUI
+ */
+ protected $parent_gui;
+ /**
+ * @var bool $is_new
+ */
+ protected $is_new = true;
+
+
+
+ /**
+ * @param xoctPublicationUsageGUI $parent_gui
+ * @param PublicationUsageGroup $xoctPublicationUsageGroup
+ * @param bool $is_new
+ */
+ public function __construct($parent_gui, $xoctPublicationUsageGroup, $is_new = true)
+ {
+ parent::__construct();
+ $this->object = $xoctPublicationUsageGroup;
+ $this->parent_gui = $parent_gui;
+ $this->parent_gui->setTab();
+ $this->ctrl->saveParameter($parent_gui, 'id');
+ $this->is_new = $is_new;
+ $this->initForm();
+ }
+
+
+ /**
+ *
+ */
+ protected function initForm()
+ {
+ $this->setTarget('_top');
+ $this->setFormAction($this->ctrl->getFormAction($this->parent_gui));
+ $this->initButtons();
+
+ $te = new ilTextInputGUI($this->txt(self::F_NAME), self::F_NAME);
+ $te->setRequired(true);
+ $this->addItem($te);
+
+ $max_lenght = self::F_DISPLAY_NAME_MAX_LENGTH;
+ $display_name = (!empty($this->object->getDisplayName()) ? $this->object->getDisplayName() : '{added display name}');
+ $info = sprintf($this->txt(self::F_DISPLAY_NAME . '_info'), $max_lenght, strtolower($display_name));
+ $te = new ilTextInputGUI($this->txt(self::F_DISPLAY_NAME), self::F_DISPLAY_NAME);
+ $te->setInfo($info);
+ $te->setMaxLength($max_lenght);
+ $te->setRequired(true);
+ $this->addItem($te);
+
+ $te = new ilTextAreaInputGUI($this->txt(self::F_DESCRIPTION), self::F_DESCRIPTION);
+ $this->addItem($te);
+ }
+
+
+ /**
+ * @param $lang_var
+ *
+ * @return string
+ */
+ protected function txt($lang_var): string
+ {
+ return $this->parent_gui->txt("group_{$lang_var}");
+ }
+
+
+ /**
+ *
+ */
+ public function fillForm()
+ {
+ $array = [
+ self::F_NAME => $this->object->getName(),
+ self::F_DISPLAY_NAME => $this->object->getDisplayName(),
+ self::F_DESCRIPTION => $this->object->getDescription(),
+ ];
+
+ $this->setValuesByArray($array);
+ }
+
+
+ /**
+ * returns whether checkinput was successful or not.
+ *
+ * @return bool
+ */
+ public function fillObject(): bool
+ {
+ if (!$this->checkInput()) {
+ return false;
+ }
+
+ $this->object->setName($this->getInput(self::F_NAME));
+ $this->object->setDisplayName($this->getInput(self::F_DISPLAY_NAME));
+ $this->object->setDescription($this->getInput(self::F_DESCRIPTION));
+
+ return true;
+ }
+
+
+ /**
+ * @return bool
+ */
+ public function saveObject(): bool
+ {
+ if (!$this->fillObject()) {
+ return false;
+ }
+ if ($this->is_new) {
+ $this->object->create();
+ } else {
+ $this->object->update();
+ }
+
+ return true;
+ }
+
+
+ /**
+ *
+ */
+ protected function initButtons()
+ {
+ if ($this->is_new) {
+ $this->setTitle($this->parent_gui->txt('create_group'));
+ $this->addCommandButton(xoctPublicationUsageGUI::CMD_CREATE_NEW_GROUP, $this->parent_gui->txt(xoctPublicationUsageGUI::CMD_CREATE));
+ } else {
+ $this->setTitle($this->parent_gui->txt('edit_group'));
+ $this->addCommandButton(xoctPublicationUsageGUI::CMD_UPDATE_GROUP, $this->parent_gui->txt(xoctPublicationUsageGUI::CMD_UPDATE));
+ }
+
+ $this->addCommandButton(xoctPublicationUsageGUI::CMD_CANCEL, $this->parent_gui->txt(xoctPublicationUsageGUI::CMD_CANCEL));
+ }
+}
diff --git a/classes/Conf/PublicationUsage/class.xoctPublicationGroupTableGUI.php b/classes/Conf/PublicationUsage/class.xoctPublicationGroupTableGUI.php
new file mode 100644
index 000000000..386549ea7
--- /dev/null
+++ b/classes/Conf/PublicationUsage/class.xoctPublicationGroupTableGUI.php
@@ -0,0 +1,132 @@
+
+ */
+class xoctPublicationGroupTableGUI extends ilTable2GUI
+{
+ public const TBL_ID = 'tbl_xoct_pub_g';
+ /**
+ * @var array
+ */
+ protected $filter = [];
+ /**
+ * @var ilOpenCastPlugin
+ */
+ protected $plugin;
+ /**
+ * @var OpencastDIC
+ */
+ protected $container;
+
+
+ /**
+ * @param xoctPublicationUsageGUI $a_parent_obj
+ * @param string $a_parent_cmd
+ */
+ public function __construct(xoctPublicationUsageGUI $a_parent_obj, $a_parent_cmd)
+ {
+ parent::__construct($a_parent_obj, $a_parent_cmd);
+ $this->container = OpencastDIC::getInstance();
+ $this->plugin = $this->container->plugin();
+ $this->setId(self::TBL_ID);
+ $this->setPrefix(self::TBL_ID);
+ $this->setFormName(self::TBL_ID);
+ $this->ctrl->saveParameter($a_parent_obj, $this->getNavParameter());
+ $this->parent_obj = $a_parent_obj;
+ $this->setTitle($this->parent_obj->txt('table_title_usage_group'));
+ $this->setRowTemplate(
+ 'tpl.publication_group.html',
+ 'Customizing/global/plugins/Services/Repository/RepositoryObject/OpenCast'
+ );
+ $this->setFormAction($this->ctrl->getFormAction($a_parent_obj));
+ $this->initColumns();
+ $this->parseData();
+ }
+
+
+ /**
+ * @param array $a_set
+ *
+ * @throws DICException
+ */
+ public function fillRow($a_set)
+ {
+ /**
+ * @var $publication_usage_group PublicationUsageGroup
+ */
+ $publication_usage_group = PublicationUsageGroup::find($a_set['id']);
+ $this->tpl->setVariable('NAME', $publication_usage_group->getName());
+ $this->tpl->setVariable('DISPLAY_NAME', $publication_usage_group->getDisplayName());
+ $this->tpl->setVariable('DESCRIPTION', $publication_usage_group->getDescription());
+
+ $this->addActionMenu($publication_usage_group);
+ }
+
+
+ protected function initColumns()
+ {
+ $this->addColumn($this->parent_obj->txt('group_name'));
+ $this->addColumn($this->parent_obj->txt('group_display_name'));
+ $this->addColumn($this->parent_obj->txt('group_description'));
+
+ $this->addColumn($this->plugin->txt('common_actions'), '', '150px');
+ }
+
+
+ /**
+ * @param PublicationUsageGroup $publication_usage_group
+ *
+ * @throws DICException
+ */
+ protected function addActionMenu(PublicationUsageGroup $publication_usage_group)
+ {
+ $current_selection_list = new ilAdvancedSelectionListGUI();
+ $current_selection_list->setListTitle($this->plugin->txt('common_actions'));
+ $current_selection_list->setId(self::TBL_ID . '_actions_' . $publication_usage_group->getId());
+ $current_selection_list->setUseImages(false);
+
+ $this->ctrl->setParameter($this->parent_obj, 'id', $publication_usage_group->getId());
+ $current_selection_list->addItem(
+ $this->parent_obj->txt(xoctPublicationUsageGUI::CMD_EDIT),
+ xoctPublicationUsageGUI::CMD_EDIT_GROUP,
+ $this->ctrl->getLinkTarget($this->parent_obj, xoctPublicationUsageGUI::CMD_EDIT_GROUP)
+ );
+ $current_selection_list->addItem(
+ $this->parent_obj->txt(xoctPublicationUsageGUI::CMD_DELETE),
+ xoctPublicationUsageGUI::CMD_DELETE_GROUP,
+ $this->ctrl->getLinkTarget($this->parent_obj, xoctPublicationUsageGUI::CMD_CONFIRM_DELETE_GROUP)
+ );
+
+ $this->tpl->setVariable('ACTIONS', $current_selection_list->getHTML());
+ }
+
+
+ protected function parseData()
+ {
+ $groups = PublicationUsageGroupRepository::getSortedArrayList();
+ $this->setData($groups);
+ }
+
+
+ /**
+ * @param $item
+ */
+ protected function addAndReadFilterItem(ilFormPropertyGUI $item)
+ {
+ $this->addFilterItem($item);
+ $item->readFromSession();
+ if ($item instanceof ilCheckboxInputGUI) {
+ $this->filter[$item->getPostVar()] = $item->getChecked();
+ } else {
+ $this->filter[$item->getPostVar()] = $item->getValue();
+ }
+ }
+}
diff --git a/classes/Conf/PublicationUsage/class.xoctPublicationSubUsageFormGUI.php b/classes/Conf/PublicationUsage/class.xoctPublicationSubUsageFormGUI.php
new file mode 100644
index 000000000..4baa3b183
--- /dev/null
+++ b/classes/Conf/PublicationUsage/class.xoctPublicationSubUsageFormGUI.php
@@ -0,0 +1,281 @@
+
+ */
+class xoctPublicationSubUsageFormGUI extends ilPropertyFormGUI
+{
+ public const F_PARENT_USAGE_ID = 'parent_usage_id';
+ public const F_TITLE = 'title';
+ public const F_DESCRIPTION = 'description';
+ public const F_DISPLAY_NAME = 'display_name';
+ public const F_GROUP_ID = 'group_id';
+ public const F_CHANNEL = 'channel';
+ public const F_STATUS = 'status';
+ public const F_SEARCH_KEY = 'search_key';
+ public const F_FLAVOR = PublicationUsage::SEARCH_KEY_FLAVOR;
+ public const F_TAG = PublicationUsage::SEARCH_KEY_TAG;
+ public const F_MD_TYPE = 'md_type';
+ public const F_ALLOW_MULTIPLE = 'allow_multiple';
+ public const F_MEDIATYPE = 'mediatype';
+ public const F_IGNORE_OBJECT_SETTINGS = 'ignore_object_settings';
+ public const F_EXT_DL_SOURCE = 'ext_dl_source';
+
+ /**
+ * @var PublicationUsage
+ */
+ protected $object;
+ /**
+ * @var xoctPublicationUsageGUI
+ */
+ protected $parent_gui;
+ /**
+ * @var bool $is_new
+ */
+ protected $is_new = true;
+ /**
+ * @var ilOpenCastPlugin
+ */
+ protected $plugin;
+ /**
+ * @var OpencastDIC
+ */
+ protected $container;
+
+
+ /**
+ * @param xoctPublicationUsageGUI $parent_gui
+ * @param xoctPublicationSubUsage $xoctPublicationSubUsage
+ */
+ public function __construct($parent_gui, $xoctPublicationSubUsage, $is_new = true)
+ {
+ global $DIC;
+ $this->container = OpencastDIC::getInstance();
+ $this->plugin = $this->container->plugin();
+ $DIC->ui()->mainTemplate()->addJavaScript(
+ $this->plugin->getDirectory() . '/js/opencast/dist/index.js'
+ );
+ $DIC->ui()->mainTemplate()->addOnLoadCode('il.Opencast.Form.publicationUsage.init()');
+ parent::__construct();
+ $this->object = $xoctPublicationSubUsage;
+ $this->parent_gui = $parent_gui;
+ $this->parent_gui->setTab();
+ $this->ctrl->saveParameter($parent_gui, 'id');
+ $this->is_new = $is_new;
+ $this->initForm();
+ }
+
+
+ /**
+ *
+ */
+ protected function initForm()
+ {
+ $this->setTarget('_top');
+ $this->setFormAction($this->ctrl->getFormAction($this->parent_gui));
+ $this->initButtons();
+
+ $te = new ilTextInputGUI($this->parent_gui->txt(self::F_PARENT_USAGE_ID), self::F_PARENT_USAGE_ID);
+ $te->setRequired(true);
+ $te->setDisabled(true);
+ $this->addItem($te);
+
+ $te = new ilTextInputGUI($this->parent_gui->txt(self::F_TITLE), self::F_TITLE);
+ $te->setRequired(true);
+ $te->setDisabled(true);
+ $this->addItem($te);
+
+ // F_DISPLAY_NAME
+ $max_lenght = 20;
+ $display_name = (!empty($this->object->getDisplayName()) ? $this->object->getDisplayName() : '{added display name}');
+ $info = sprintf($this->plugin->txt('publication_usage_sub_' . self::F_DISPLAY_NAME . '_info'), $max_lenght, strtolower($display_name));
+ $te = new ilTextInputGUI($this->parent_gui->txt(self::F_DISPLAY_NAME), self::F_DISPLAY_NAME);
+ $te->setInfo($info);
+ $te->setMaxLength($max_lenght);
+ $this->addItem($te);
+
+ $te = new ilTextAreaInputGUI($this->parent_gui->txt(self::F_DESCRIPTION), self::F_DESCRIPTION);
+ $this->addItem($te);
+
+ // F_GROUP_ID
+ $xoctPublicationUsageGroupsArray = PublicationUsageGroup::getArray('id', 'name');
+ $empty_groups = ['' => '-'];
+ $publication_groups = $empty_groups + $xoctPublicationUsageGroupsArray;
+ $te = new ilSelectInputGUI($this->parent_gui->txt(self::F_GROUP_ID), self::F_GROUP_ID);
+ $te->setOptions($publication_groups);
+ $this->addItem($te);
+
+ $te = new ilTextInputGUI($this->parent_gui->txt(self::F_CHANNEL), self::F_CHANNEL);
+ $te->setRequired(true);
+ $this->addItem($te);
+
+ $te = new ilSelectInputGUI($this->parent_gui->txt(self::F_MD_TYPE), self::F_MD_TYPE);
+ $te->setRequired(true);
+ $te->setOptions([
+ PublicationUsage::MD_TYPE_PUBLICATION_ITSELF => $this->parent_gui->txt(
+ 'md_type_' . PublicationUsage::MD_TYPE_PUBLICATION_ITSELF
+ ),
+ PublicationUsage::MD_TYPE_ATTACHMENT => $this->parent_gui->txt(
+ 'md_type_' . PublicationUsage::MD_TYPE_ATTACHMENT
+ ),
+ PublicationUsage::MD_TYPE_MEDIA => $this->parent_gui->txt('md_type_' . PublicationUsage::MD_TYPE_MEDIA)
+ ]);
+ $this->addItem($te);
+
+ $radio = new ilRadioGroupInputGUI($this->parent_gui->txt(self::F_SEARCH_KEY), self::F_SEARCH_KEY);
+ $radio->setInfo($this->parent_gui->txt(self::F_SEARCH_KEY . '_info'));
+
+ $opt = new ilRadioOption($this->parent_gui->txt(self::F_FLAVOR), self::F_FLAVOR);
+ $te = new ilTextInputGUI('', self::F_FLAVOR);
+ $te->setInfo($this->parent_gui->txt(self::F_FLAVOR . '_info'));
+ $opt->addSubItem($te);
+ $radio->addOption($opt);
+
+ $opt = new ilRadioOption($this->parent_gui->txt(self::F_TAG), self::F_TAG);
+ $te = new ilTextInputGUI('', self::F_TAG);
+ $opt->addSubItem($te);
+ $radio->addOption($opt);
+
+ $radio->setValue(self::F_FLAVOR);
+ $this->addItem($radio);
+
+ //F_MEDIATYPE
+ $te = new ilTextInputGUI($this->parent_gui->txt(self::F_MEDIATYPE), self::F_MEDIATYPE);
+ $te->setInfo($this->parent_gui->txt(self::F_MEDIATYPE . '_info'));
+ $this->addItem($te);
+
+ if (in_array(
+ $this->object->getParentUsageId(),
+ [PublicationUsage::USAGE_DOWNLOAD, PublicationUsage::USAGE_DOWNLOAD_FALLBACK],
+ true
+ )) {
+ $allow_multiple = new ilCheckboxInputGUI($this->parent_gui->txt(self::F_ALLOW_MULTIPLE), self::F_ALLOW_MULTIPLE);
+ $allow_multiple->setInfo($this->parent_gui->txt(self::F_ALLOW_MULTIPLE . '_info'));
+ //F_IGNORE_OBJECT_SETTINGS
+ $ignore_object_setting = new ilCheckboxInputGUI(
+ $this->parent_gui->txt(self::F_IGNORE_OBJECT_SETTINGS),
+ self::F_IGNORE_OBJECT_SETTINGS
+ );
+ $ignore_object_setting->setInfo($this->parent_gui->txt(self::F_IGNORE_OBJECT_SETTINGS . '_info'));
+ //F_EXT_DL_SOURCE
+ $ext_dl_source = new ilCheckboxInputGUI(
+ $this->parent_gui->txt(self::F_EXT_DL_SOURCE),
+ self::F_EXT_DL_SOURCE
+ );
+ $ext_dl_source->setInfo($this->parent_gui->txt(self::F_EXT_DL_SOURCE . '_info'));
+ } else {
+ $allow_multiple = new ilHiddenInputGUI(self::F_ALLOW_MULTIPLE);
+ $allow_multiple->setValue(0);
+ $ignore_object_setting = new ilHiddenInputGUI(self::F_IGNORE_OBJECT_SETTINGS);
+ $ignore_object_setting->setValue(0);
+ $ext_dl_source = new ilHiddenInputGUI(self::F_EXT_DL_SOURCE);
+ $ext_dl_source->setValue(0);
+ }
+ $this->addItem($allow_multiple);
+ $this->addItem($ignore_object_setting);
+ $this->addItem($ext_dl_source);
+ }
+
+
+ /**
+ *
+ */
+ public function fillForm()
+ {
+ $array = [
+ self::F_PARENT_USAGE_ID => $this->object->getParentUsageId(),
+ self::F_TITLE => $this->object->getTitle(),
+ self::F_DISPLAY_NAME => $this->object->getDisplayName(),
+ self::F_DESCRIPTION => $this->object->getDescription(),
+ self::F_GROUP_ID => $this->object->getGroupId(),
+ self::F_CHANNEL => $this->object->getChannel(),
+ self::F_SEARCH_KEY => $this->object->getSearchKey(),
+ self::F_FLAVOR => $this->object->getFlavor(),
+ self::F_TAG => $this->object->getTag(),
+ self::F_MD_TYPE => $this->object->getMdType(),
+ self::F_ALLOW_MULTIPLE => $this->object->isAllowMultiple(),
+ self::F_MEDIATYPE => $this->object->getMediaType(),
+ self::F_IGNORE_OBJECT_SETTINGS => $this->object->ignoreObjectSettings(),
+ self::F_EXT_DL_SOURCE => $this->object->isExternalDownloadSource(),
+ ];
+
+ $this->setValuesByArray($array);
+ }
+
+
+ /**
+ * returns whether checkinput was successful or not.
+ *
+ * @return bool
+ */
+ public function fillObject(): bool
+ {
+ if (!$this->checkInput()) {
+ return false;
+ }
+
+ $this->object->setParentUsageId($this->getInput(self::F_PARENT_USAGE_ID));
+ $this->object->setTitle($this->getInput(self::F_TITLE));
+ $this->object->setDisplayName($this->getInput(self::F_DISPLAY_NAME));
+ $this->object->setDescription($this->getInput(self::F_DESCRIPTION));
+ $this->object->setGroupId($this->getInput(self::F_GROUP_ID));
+ $this->object->setChannel($this->getInput(self::F_CHANNEL));
+ $this->object->setSearchKey($this->getInput(self::F_SEARCH_KEY));
+ $this->object->setFlavor($this->getInput(self::F_FLAVOR));
+ $this->object->setTag($this->getInput(self::F_TAG));
+ $this->object->setMdType($this->getInput(self::F_MD_TYPE));
+ $this->object->setAllowMultiple((bool)$this->getInput(self::F_ALLOW_MULTIPLE));
+ $this->object->setMediaType($this->getInput(self::F_MEDIATYPE));
+ $this->object->setIgnoreObjectSettings((bool)$this->getInput(self::F_IGNORE_OBJECT_SETTINGS));
+ $this->object->setExternalDownloadSource((bool)$this->getInput(self::F_EXT_DL_SOURCE));
+
+ return true;
+ }
+
+
+ /**
+ * @return bool
+ */
+ public function saveObject(): bool
+ {
+ if (!$this->fillObject()) {
+ return false;
+ }
+ if ($this->is_new) {
+ $this->object->create();
+ } else {
+ $this->object->update();
+ }
+
+ return true;
+ }
+
+
+ /**
+ *
+ */
+ protected function initButtons()
+ {
+ if ($this->is_new) {
+ $this->setTitle($this->parent_gui->txt('create_sub'));
+ $this->addCommandButton(
+ xoctPublicationUsageGUI::CMD_CREATE_SUB,
+ $this->parent_gui->txt(xoctPublicationUsageGUI::CMD_CREATE)
+ );
+ } else {
+ $this->setTitle($this->parent_gui->txt('edit_sub'));
+ $this->addCommandButton(
+ xoctPublicationUsageGUI::CMD_UPDATE_SUB,
+ $this->parent_gui->txt(xoctPublicationUsageGUI::CMD_UPDATE)
+ );
+ }
+
+ $this->addCommandButton(xoctPublicationUsageGUI::CMD_CANCEL, $this->parent_gui->txt(xoctPublicationUsageGUI::CMD_CANCEL));
+ }
+}
diff --git a/classes/Conf/PublicationUsage/class.xoctPublicationSubUsageTableGUI.php b/classes/Conf/PublicationUsage/class.xoctPublicationSubUsageTableGUI.php
new file mode 100644
index 000000000..0a0e2faca
--- /dev/null
+++ b/classes/Conf/PublicationUsage/class.xoctPublicationSubUsageTableGUI.php
@@ -0,0 +1,176 @@
+
+ */
+class xoctPublicationSubUsageTableGUI extends ilTable2GUI
+{
+ public const TBL_ID = 'tbl_xoct_pub_sub_u';
+ /**
+ * @var array
+ */
+ protected $filter = [];
+
+ /**
+ * @var ilOpenCastPlugin
+ */
+ protected $plugin;
+ /**
+ * @var OpencastDIC
+ */
+ protected $container;
+
+ /**
+ * @param xoctPublicationUsageGUI $a_parent_obj
+ * @param string $a_parent_cmd
+ */
+ public function __construct(xoctPublicationUsageGUI $a_parent_obj, $a_parent_cmd)
+ {
+ parent::__construct($a_parent_obj, $a_parent_cmd);
+ $this->container = OpencastDIC::getInstance();
+ $this->plugin = $this->container->plugin();
+ $this->setId(self::TBL_ID);
+ $this->setPrefix(self::TBL_ID);
+ $this->setFormName(self::TBL_ID);
+ $this->ctrl->saveParameter($a_parent_obj, $this->getNavParameter());
+ $this->parent_obj = $a_parent_obj;
+ $this->setTitle($this->parent_obj->txt('table_title_sub_usage'));
+ $this->setRowTemplate(
+ 'tpl.publication_sub_usage.html',
+ 'Customizing/global/plugins/Services/Repository/RepositoryObject/OpenCast'
+ );
+ $this->setFormAction($this->ctrl->getFormAction($a_parent_obj));
+ $this->initColumns();
+ $this->parseData();
+ }
+
+
+ /**
+ * @param array $a_set
+ *
+ * @throws DICException
+ */
+ public function fillRow($a_set)
+ {
+ /**
+ * @var $publication_sub_usage PublicationSubUsage
+ */
+ $publication_sub_usage = PublicationSubUsage::find($a_set['id']);
+ $this->tpl->setVariable('PARENT_USAGE_ID', $publication_sub_usage->getParentUsageId());
+ $this->tpl->setVariable('TITLE', $publication_sub_usage->getTitle());
+ $this->tpl->setVariable('DISPLAY_NAME', $publication_sub_usage->getDisplayName());
+ $this->tpl->setVariable('DESCRIPTION', $publication_sub_usage->getDescription());
+ $this->tpl->setVariable('CHANNEL', $publication_sub_usage->getChannel());
+ $this->tpl->setVariable('MD_TYPE', $this->parent_obj->txt('md_type_' . $publication_sub_usage->getMdType()));
+ if ($publication_sub_usage->getMdType() === PublicationUsage::MD_TYPE_PUBLICATION_ITSELF) {
+ $this->tpl->setVariable('FLAVOR', ' ');
+ $this->tpl->setVariable('TAG', ' ');
+ } elseif ($publication_sub_usage->getSearchKey() == xoctPublicationUsageFormGUI::F_FLAVOR) {
+ $this->tpl->setVariable('FLAVOR', $publication_sub_usage->getFlavor());
+ $this->tpl->setVariable('TAG', ' ');
+ } else {
+ $this->tpl->setVariable('TAG', $publication_sub_usage->getTag());
+ $this->tpl->setVariable('FLAVOR', ' ');
+ }
+ $group_name = '';
+ if (!is_null($publication_sub_usage->getGroupId())) {
+ $publication_usage_group = PublicationUsageGroup::find($publication_sub_usage->getGroupId());
+ $group_name = $publication_usage_group ? $publication_usage_group->getName() : $group_name;
+ }
+ $this->tpl->setVariable('GROUP_NAME', $group_name);
+
+ $extras = [];
+ if ($publication_sub_usage->getParentUsageId() == PublicationUsage::USAGE_DOWNLOAD ||
+ $publication_sub_usage->getParentUsageId() == PublicationUsage::USAGE_DOWNLOAD_FALLBACK) {
+ if ($publication_sub_usage->isExternalDownloadSource()) {
+ $extras[] = $this->parent_obj->txt('ext_dl_source');
+ }
+ }
+ $this->tpl->setVariable('EXTRA_CONFIG', implode('
', $extras));
+
+ $this->addActionMenu($publication_sub_usage);
+ }
+
+
+ protected function initColumns()
+ {
+ $this->addColumn($this->parent_obj->txt('parent_usage_id'));
+ $this->addColumn($this->parent_obj->txt('title'));
+ $this->addColumn($this->parent_obj->txt('display_name'));
+ $this->addColumn($this->parent_obj->txt('description'));
+ $this->addColumn($this->parent_obj->txt('channel'));
+ $this->addColumn($this->parent_obj->txt('md_type'));
+ $this->addColumn($this->parent_obj->txt('flavor'));
+ $this->addColumn($this->parent_obj->txt('tag'));
+ $this->addColumn($this->parent_obj->txt('group_th'));
+ $this->addColumn($this->parent_obj->txt('extra_config'));
+
+ $this->addColumn($this->plugin->txt('common_actions'), '', '150px');
+ }
+
+
+ /**
+ * @param PublicationSubUsage $publication_sub_usage
+ *
+ * @throws DICException
+ */
+ protected function addActionMenu(PublicationSubUsage $publication_sub_usage)
+ {
+ $current_selection_list = new ilAdvancedSelectionListGUI();
+ $current_selection_list->setListTitle($this->plugin->txt('common_actions'));
+ $current_selection_list->setId(self::TBL_ID . '_actions_' . $publication_sub_usage->getId());
+ $current_selection_list->setUseImages(false);
+
+ $this->ctrl->setParameter($this->parent_obj, 'id', $publication_sub_usage->getId());
+ $current_selection_list->addItem(
+ $this->parent_obj->txt(xoctPublicationUsageGUI::CMD_EDIT),
+ xoctPublicationUsageGUI::CMD_EDIT_SUB,
+ $this->ctrl->getLinkTarget($this->parent_obj, xoctPublicationUsageGUI::CMD_EDIT_SUB)
+ );
+ $current_selection_list->addItem(
+ $this->parent_obj->txt(xoctPublicationUsageGUI::CMD_DELETE),
+ xoctPublicationUsageGUI::CMD_DELETE_SUB,
+ $this->ctrl->getLinkTarget($this->parent_obj, xoctPublicationUsageGUI::CMD_CONFIRM_DELETE_SUB)
+ );
+
+ $this->tpl->setVariable('ACTIONS', $current_selection_list->getHTML());
+ }
+
+
+ protected function parseData()
+ {
+ $subs = PublicationSubUsage::getArray();
+ // Sorting by parent usage id.
+ usort($subs, function ($sub1, $sub2) {
+ return strcmp($sub1['parent_usage_id'], $sub2['parent_usage_id']);
+ });
+ // Sorting by title.
+ usort($subs, function ($sub1, $sub2) {
+ return strcmp($sub1['title'], $sub2['title']);
+ });
+ $this->setData($subs);
+ }
+
+
+ /**
+ * @param $item
+ */
+ protected function addAndReadFilterItem(ilFormPropertyGUI $item)
+ {
+ $this->addFilterItem($item);
+ $item->readFromSession();
+ if ($item instanceof ilCheckboxInputGUI) {
+ $this->filter[$item->getPostVar()] = $item->getChecked();
+ } else {
+ $this->filter[$item->getPostVar()] = $item->getValue();
+ }
+ }
+}
diff --git a/classes/Conf/PublicationUsage/class.xoctPublicationUsageFormGUI.php b/classes/Conf/PublicationUsage/class.xoctPublicationUsageFormGUI.php
index 583efc1f3..153943038 100644
--- a/classes/Conf/PublicationUsage/class.xoctPublicationUsageFormGUI.php
+++ b/classes/Conf/PublicationUsage/class.xoctPublicationUsageFormGUI.php
@@ -1,6 +1,8 @@
ctrl();
+ $this->container = OpencastDIC::getInstance();
+ $this->plugin = $this->container->plugin();
$DIC->ui()->mainTemplate()->addJavaScript(
- ilOpenCastPlugin::getInstance()->getDirectory() . '/templates/default/publication_usage_form.min.js'
+ $this->plugin->getDirectory() . '/js/opencast/dist/index.js'
);
+ $DIC->ui()->mainTemplate()->addOnLoadCode('il.Opencast.Form.publicationUsage.init()');
parent::__construct();
$this->object = $xoctPublicationUsage;
$this->parent_gui = $parent_gui;
+ $this->parent_gui->setTab();
$ctrl->saveParameter($parent_gui, xoctPublicationUsageGUI::IDENTIFIER);
$this->is_new = ($this->object->getUsageId() == '');
$this->initForm();
@@ -70,9 +89,26 @@ protected function initForm()
$te->setRequired(true);
$this->addItem($te);
+ // F_DISPLAY_NAME
+ $max_lenght = 20;
+ $display_name = (!empty($this->object->getDisplayName()) ? $this->object->getDisplayName() : '{added display name}');
+ $info = sprintf($this->parent_gui->txt(self::F_DISPLAY_NAME . '_info'), $max_lenght, strtolower($display_name));
+ $te = new ilTextInputGUI($this->parent_gui->txt(self::F_DISPLAY_NAME), self::F_DISPLAY_NAME);
+ $te->setInfo($info);
+ $te->setMaxLength($max_lenght);
+ $this->addItem($te);
+
$te = new ilTextAreaInputGUI($this->parent_gui->txt(self::F_DESCRIPTION), self::F_DESCRIPTION);
$this->addItem($te);
+ // F_GROUP_ID
+ $xoctPublicationUsageGroupsArray = PublicationUsageGroup::getArray('id', 'name');
+ $empty_groups = ['' => '-'];
+ $publication_groups = $empty_groups + $xoctPublicationUsageGroupsArray;
+ $te = new ilSelectInputGUI($this->parent_gui->txt(self::F_GROUP_ID), self::F_GROUP_ID);
+ $te->setOptions($publication_groups);
+ $this->addItem($te);
+
$te = new ilTextInputGUI($this->parent_gui->txt(self::F_CHANNEL), self::F_CHANNEL);
$te->setRequired(true);
$this->addItem($te);
@@ -107,19 +143,41 @@ protected function initForm()
$radio->setValue(self::F_FLAVOR);
$this->addItem($radio);
+ //F_MEDIATYPE
+ $te = new ilTextInputGUI($this->parent_gui->txt(self::F_MEDIATYPE), self::F_MEDIATYPE);
+ $te->setInfo($this->parent_gui->txt(self::F_MEDIATYPE . '_info'));
+ $this->addItem($te);
+
if (in_array(
$this->object->getUsageId(),
- [PublicationUsage::USAGE_DOWNLOAD, PublicationUsage::USAGE_DOWNLOAD_FALLBACK]
+ [PublicationUsage::USAGE_DOWNLOAD, PublicationUsage::USAGE_DOWNLOAD_FALLBACK],
+ true
)) {
- $allow_multiple = new ilCheckboxInputGUI(
- $this->parent_gui->txt(self::F_ALLOW_MULTIPLE),
- self::F_ALLOW_MULTIPLE
+ $allow_multiple = new ilCheckboxInputGUI($this->parent_gui->txt(self::F_ALLOW_MULTIPLE), self::F_ALLOW_MULTIPLE);
+ $allow_multiple->setInfo($this->parent_gui->txt(self::F_ALLOW_MULTIPLE . '_info'));
+ //F_IGNORE_OBJECT_SETTINGS
+ $ignore_object_setting = new ilCheckboxInputGUI(
+ $this->parent_gui->txt(self::F_IGNORE_OBJECT_SETTINGS),
+ self::F_IGNORE_OBJECT_SETTINGS
+ );
+ $ignore_object_setting->setInfo($this->parent_gui->txt(self::F_IGNORE_OBJECT_SETTINGS . '_info'));
+ //F_EXT_DL_SOURCE
+ $ext_dl_source = new ilCheckboxInputGUI(
+ $this->parent_gui->txt(self::F_EXT_DL_SOURCE),
+ self::F_EXT_DL_SOURCE
);
+ $ext_dl_source->setInfo($this->parent_gui->txt(self::F_EXT_DL_SOURCE . '_info'));
} else {
$allow_multiple = new ilHiddenInputGUI(self::F_ALLOW_MULTIPLE);
$allow_multiple->setValue(0);
+ $ignore_object_setting = new ilHiddenInputGUI(self::F_IGNORE_OBJECT_SETTINGS);
+ $ignore_object_setting->setValue(0);
+ $ext_dl_source = new ilHiddenInputGUI(self::F_EXT_DL_SOURCE);
+ $ext_dl_source->setValue(0);
}
$this->addItem($allow_multiple);
+ $this->addItem($ignore_object_setting);
+ $this->addItem($ext_dl_source);
}
/**
@@ -130,13 +188,18 @@ public function fillForm(): void
$array = [
self::F_USAGE_ID => $this->object->getUsageId(),
self::F_TITLE => $this->object->getTitle(),
+ self::F_DISPLAY_NAME => $this->object->getDisplayName(),
self::F_DESCRIPTION => $this->object->getDescription(),
+ self::F_GROUP_ID => $this->object->getGroupId(),
self::F_CHANNEL => $this->object->getChannel(),
self::F_SEARCH_KEY => $this->object->getSearchKey(),
self::F_FLAVOR => $this->object->getFlavor(),
self::F_TAG => $this->object->getTag(),
self::F_MD_TYPE => $this->object->getMdType(),
self::F_ALLOW_MULTIPLE => $this->object->isAllowMultiple(),
+ self::F_MEDIATYPE => $this->object->getMediaType(),
+ self::F_IGNORE_OBJECT_SETTINGS => $this->object->ignoreObjectSettings(),
+ self::F_EXT_DL_SOURCE => $this->object->isExternalDownloadSource(),
];
$this->setValuesByArray($array);
@@ -153,13 +216,18 @@ public function fillObject(): bool
$this->object->setUsageId($this->getInput(self::F_USAGE_ID));
$this->object->setTitle($this->getInput(self::F_TITLE));
+ $this->object->setDisplayName($this->getInput(self::F_DISPLAY_NAME));
$this->object->setDescription($this->getInput(self::F_DESCRIPTION));
+ $this->object->setGroupId($this->getInput(self::F_GROUP_ID));
$this->object->setChannel($this->getInput(self::F_CHANNEL));
$this->object->setSearchKey($this->getInput(self::F_SEARCH_KEY));
$this->object->setFlavor($this->getInput(self::F_FLAVOR));
$this->object->setTag($this->getInput(self::F_TAG));
$this->object->setMdType($this->getInput(self::F_MD_TYPE));
$this->object->setAllowMultiple((bool) $this->getInput(self::F_ALLOW_MULTIPLE));
+ $this->object->setMediaType($this->getInput(self::F_MEDIATYPE));
+ $this->object->setIgnoreObjectSettings((bool) $this->getInput(self::F_IGNORE_OBJECT_SETTINGS));
+ $this->object->setExternalDownloadSource((bool)$this->getInput(self::F_EXT_DL_SOURCE));
return true;
}
diff --git a/classes/Conf/PublicationUsage/class.xoctPublicationUsageGUI.php b/classes/Conf/PublicationUsage/class.xoctPublicationUsageGUI.php
index 25c614861..9d274cdf9 100644
--- a/classes/Conf/PublicationUsage/class.xoctPublicationUsageGUI.php
+++ b/classes/Conf/PublicationUsage/class.xoctPublicationUsageGUI.php
@@ -1,7 +1,10 @@
http = $DIC->http();
$this->toolbar = $DIC->toolbar();
$this->main_tpl = $DIC->ui()->mainTemplate();
+ $this->tabs = $DIC->tabs();
+ // Getting Query Parameters
+ $this->pub_subtab_active =
+ $this->http->request()->getQueryParams()['pub_subtab_active'] ?? xoctMainGUI::SUBTAB_PUBLICATION_USAGE;
+ $this->identifier = $this->http->request()->getQueryParams()[self::IDENTIFIER] ?? '';
+ if (!empty($this->http->request()->getParsedBody()[self::IDENTIFIER])) {
+ $this->identifier = $this->http->request()->getParsedBody()[self::IDENTIFIER];
+ }
+ $this->get_id = (int) $this->http->request()->getQueryParams()['id'] ?? null;
+ $this->post_id = (int) $this->http->request()->getParsedBody()['id'] ?? null;
+ $this->channel = $this->http->request()->getParsedBody()[xoctPublicationUsageFormGUI::F_CHANNEL] ?? null;
$this->repository = new PublicationUsageRepository();
+ $this->sub_repository = new PublicationSubUsageRepository();
+ $this->setTab();
}
/**
@@ -44,14 +105,49 @@ public function __construct()
*/
protected function index()
{
- if ($this->repository->getMissingUsageIds() !== []) {
+ $xoctPublicationTabsTableGUI = $this->initTabTableGUI($this->pub_subtab_active);
+ $this->main_tpl->setContent($xoctPublicationTabsTableGUI->getHTML());
+ }
+
+ /**
+ * Helps setting the tabs at all time.
+ */
+ public function setTab()
+ {
+ $this->ctrl->saveParameter($this, 'pub_subtab_active');
+ $this->tabs->setSubTabActive($this->pub_subtab_active);
+ }
+
+
+ /**
+ * Decides which content to display for the current tab.
+ * @return ilTable2GUI
+ */
+ protected function initTabTableGUI($pub_subtab_active): ilTable2GUI
+ {
+ if ($pub_subtab_active === xoctMainGUI::SUBTAB_PUBLICATION_USAGE) {
+ if (count($this->repository->getMissingUsageIds()) > 0) {
+ $b = ilLinkButton::getInstance();
+ $b->setCaption($this->plugin->getPrefix() . '_publication_usage_add_new');
+ $b->setUrl($this->ctrl->getLinkTarget($this, self::CMD_SELECT_PUBLICATION_ID));
+ $this->toolbar->addButtonInstance($b);
+ }
+ return new xoctPublicationUsageTableGUI($this, self::CMD_STANDARD);
+ } elseif ($pub_subtab_active === xoctMainGUI::SUBTAB_PUBLICATION_SUB_USAGE) {
+ if (count($this->repository->getSubAllowedUsageIds()) > 0) {
+ $b = ilLinkButton::getInstance();
+ $b->setCaption($this->plugin->getPrefix() . '_publication_usage_add_new_sub');
+ $b->setUrl($this->ctrl->getLinkTarget($this, self::CMD_SELECT_PUBLICATION_ID_SUB));
+ $this->toolbar->addButtonInstance($b);
+ }
+ return new xoctPublicationSubUsageTableGUI($this, self::CMD_STANDARD);
+ } elseif ($pub_subtab_active === xoctMainGUI::SUBTAB_PUBLICATION_GROUPS) {
$b = ilLinkButton::getInstance();
- $b->setCaption($this->plugin->getPrefix() . '_publication_usage_add_new');
- $b->setUrl($this->ctrl->getLinkTarget($this, self::CMD_SELECT_PUBLICATION_ID));
+ $b->setCaption($this->plugin->getPrefix() . '_publication_usage_add_new_group');
+ $b->setUrl($this->ctrl->getLinkTarget($this, self::CMD_ADD_NEW_GROUP));
$this->toolbar->addButtonInstance($b);
+ return new xoctPublicationGroupTableGUI($this, self::CMD_STANDARD);
}
- $xoctPublicationUsageTableGUI = new xoctPublicationUsageTableGUI($this, self::CMD_STANDARD);
- $this->main_tpl->setContent($xoctPublicationUsageTableGUI->getHTML());
}
/**
@@ -83,12 +179,12 @@ protected function selectPublicationId()
*/
protected function add()
{
- if (!$_POST[xoctPublicationUsageFormGUI::F_CHANNEL]) {
+ if (!$this->channel) {
$this->ctrl->redirect($this, self::CMD_SELECT_PUBLICATION_ID);
}
$xoctPublicationUsage = new PublicationUsage();
- $xoctPublicationUsage->setUsageId($_POST[xoctPublicationUsageFormGUI::F_CHANNEL]);
- $xoctPublicationUsage->setTitle($this->txt('type_' . $_POST[xoctPublicationUsageFormGUI::F_CHANNEL]));
+ $xoctPublicationUsage->setUsageId($this->channel);
+ $xoctPublicationUsage->setTitle($this->txt('type_' . $this->channel));
$xoctPublicationUsageFormGUI = new xoctPublicationUsageFormGUI($this, $xoctPublicationUsage);
$xoctPublicationUsageFormGUI->fillForm();
$this->main_tpl->setContent($xoctPublicationUsageFormGUI->getHTML());
@@ -113,9 +209,13 @@ protected function create()
*/
protected function edit()
{
+ if (empty($this->identifier)) {
+ ilUtil::sendFailure($this->plugin->txt('publication_usage_no_identifier'), true);
+ $this->ctrl->redirect($this);
+ }
$xoctPublicationUsageFormGUI = new xoctPublicationUsageFormGUI(
$this,
- $this->repository->getUsage($_GET[self::IDENTIFIER])
+ $this->repository->getUsage($this->identifier)
);
$xoctPublicationUsageFormGUI->fillForm();
$this->main_tpl->setContent($xoctPublicationUsageFormGUI->getHTML());
@@ -126,10 +226,13 @@ protected function edit()
*/
protected function update()
{
- $usage_id = $_GET[self::IDENTIFIER];
+ $publication_usage = new PublicationUsage();
+ if (!$this->identifier && $this->repository->getUsage($this->identifier)) {
+ $publication_usage = $this->repository->getUsage($this->identifier);
+ }
$xoctPublicationUsageFormGUI = new xoctPublicationUsageFormGUI(
$this,
- $usage_id ? $this->repository->getUsage($_GET[self::IDENTIFIER]) : new PublicationUsage()
+ $publication_usage
);
$xoctPublicationUsageFormGUI->setValuesByPost();
if ($xoctPublicationUsageFormGUI->saveObject()) {
@@ -154,10 +257,14 @@ public function txt($key): string
*/
protected function confirmDelete()
{
+ if (empty($this->identifier)) {
+ ilUtil::sendFailure($this->plugin->txt('publication_usage_no_identifier'), true);
+ $this->ctrl->redirect($this);
+ }
/**
* @var $xoctPublicationUsage PublicationUsage
*/
- $xoctPublicationUsage = $this->repository->getUsage($_GET[self::IDENTIFIER]);
+ $xoctPublicationUsage = $this->repository->getUsage($this->identifier);
$confirm = new ilConfirmationGUI();
$confirm->addItem(self::IDENTIFIER, $xoctPublicationUsage->getUsageId(), $xoctPublicationUsage->getTitle());
$confirm->setFormAction($this->ctrl->getFormAction($this));
@@ -172,7 +279,210 @@ protected function confirmDelete()
*/
protected function delete()
{
- $this->repository->delete($_POST[self::IDENTIFIER]);
+ $this->repository->delete($this->identifier);
+ $this->cancel();
+ }
+
+
+ ### Subs Section ###
+ /**
+ * Helps select the sub usage channel.
+ * INFO: Although there is only Download channel available to select, but there is the capability to extend this feature
+ * for other channels too.
+ */
+ protected function selectPublicationIdForSub()
+ {
+ $form = new ilPropertyFormGUI();
+ $form->setFormAction($this->ctrl->getFormAction($this));
+ $form->setTitle($this->txt('select_sub_usage_id'));
+ $form->setDescription($this->txt('select_sub_usage_id_desc'));
+ $form->addCommandButton(self::CMD_ADD_SUB, $this->txt(self::CMD_ADD));
+ $form->addCommandButton(self::CMD_CANCEL, $this->txt(self::CMD_CANCEL));
+ $sel = new ilSelectInputGUI($this->txt(xoctPublicationUsageFormGUI::F_CHANNEL), xoctPublicationUsageFormGUI::F_CHANNEL);
+ $options = [];
+ foreach ($this->repository->getSubAllowedUsageIds() as $id) {
+ $options[$id] = $this->txt('type_' . $id);
+ }
+ $sel->setOptions($options);
+
+ $form->addItem($sel);
+ $this->main_tpl->setContent($form->getHTML());
+ }
+
+ /**
+ *
+ */
+ protected function addSub()
+ {
+ $channel = $this->channel;
+ if (empty($channel) || !in_array($channel, $this->repository->getSubAllowedUsageIds(), true)) {
+ ilUtil::sendFailure($this->plugin->txt('publication_usage_sub_not_allowed'), true);
+ $this->ctrl->redirect($this, self::CMD_SELECT_PUBLICATION_ID_SUB);
+ }
+ $xoctPublicationSubUsage = new PublicationSubUsage();
+ $xoctPublicationSubUsage->setParentUsageId($channel);
+ $title_text = $this->txt('type_' . $channel);
+ $title = $this->sub_repository->generateTitle($channel, $title_text);
+ $xoctPublicationSubUsage->setTitle($title);
+ $xoctPublicationSubUsageFormGUI = new xoctPublicationSubUsageFormGUI($this, $xoctPublicationSubUsage);
+ $xoctPublicationSubUsageFormGUI->fillForm();
+ $this->main_tpl->setContent($xoctPublicationSubUsageFormGUI->getHTML());
+ }
+
+ /**
+ * @throws DICException
+ */
+ protected function createSub()
+ {
+ $xoctPublicationSubUsageFormGUI = new xoctPublicationSubUsageFormGUI($this, new PublicationSubUsage());
+ $xoctPublicationSubUsageFormGUI->setValuesByPost();
+ if ($xoctPublicationSubUsageFormGUI->saveObject()) {
+ ilUtil::sendSuccess($this->plugin->txt('publication_usage_msg_success_sub'), true);
+ $this->ctrl->redirect($this);
+ }
+ $this->main_tpl->setContent($xoctPublicationSubUsageFormGUI->getHTML());
+ }
+
+ /**
+ *
+ */
+ protected function editSub()
+ {
+ if (!PublicationSubUsage::find($this->get_id)) {
+ ilUtil::sendFailure($this->plugin->txt('publication_usage_sub_not_found'), true);
+ $this->ctrl->redirect($this);
+ }
+ $xoctPublicationSubUsageFormGUI = new xoctPublicationSubUsageFormGUI($this, PublicationSubUsage::find($this->get_id), false);
+ $xoctPublicationSubUsageFormGUI->fillForm();
+ $this->main_tpl->setContent($xoctPublicationSubUsageFormGUI->getHTML());
+ }
+
+
+ /**
+ * @throws DICException
+ */
+ protected function updateSub()
+ {
+ $sub_usage_id = $this->get_id;
+ if (!PublicationSubUsage::find($sub_usage_id)) {
+ ilUtil::sendFailure($this->plugin->txt('publication_usage_sub_not_found'), true);
+ $this->ctrl->redirect($this);
+ }
+ $xoctPublicationSubUsageFormGUI = new xoctPublicationSubUsageFormGUI(
+ $this,
+ PublicationSubUsage::find($sub_usage_id),
+ false
+ );
+ $xoctPublicationSubUsageFormGUI->setValuesByPost();
+ if ($xoctPublicationSubUsageFormGUI->saveObject()) {
+ ilUtil::sendSuccess($this->plugin->txt('publication_usage_msg_success_sub'), true);
+ $this->ctrl->redirect($this);
+ }
+ $this->main_tpl->setContent($xoctPublicationSubUsageFormGUI->getHTML());
+ }
+
+ protected function confirmDeleteSub()
+ {
+ if (!PublicationSubUsage::find($this->get_id)) {
+ ilUtil::sendFailure($this->plugin->txt('publication_usage_sub_not_found'), true);
+ $this->ctrl->redirect($this);
+ }
+ $xoctPublicationSubUsage = PublicationSubUsage::find($this->get_id);
+ $confirm = new ilConfirmationGUI();
+ $confirm->setHeaderText($this->txt('confirm_delete_text_sub'));
+ $confirm->addItem('id', $this->get_id, $xoctPublicationSubUsage->getTitle());
+ $confirm->setFormAction($this->ctrl->getFormAction($this));
+ $confirm->setCancel($this->txt(self::CMD_CANCEL), self::CMD_CANCEL);
+ $confirm->setConfirm($this->txt(self::CMD_DELETE), self::CMD_DELETE_SUB);
+
+ $this->main_tpl->setContent($confirm->getHTML());
+ }
+
+ protected function deleteSub()
+ {
+ if (!PublicationSubUsage::find($this->post_id)) {
+ ilUtil::sendFailure($this->plugin->txt('publication_usage_sub_not_found'), true);
+ $this->ctrl->redirect($this);
+ }
+
+ $xoctPublicationSubUsage = PublicationSubUsage::find($this->post_id);
+ $xoctPublicationSubUsage->delete();
+ $this->cancel();
+ }
+
+ ### End Subs Section ###
+
+ ### Group Section ###
+
+ protected function addNewGroup()
+ {
+ $xoctPublicationUsageGroup = new PublicationUsageGroup();
+ $xoctPublicationGroupFormGUI = new xoctPublicationGroupFormGUI($this, $xoctPublicationUsageGroup);
+ $xoctPublicationGroupFormGUI->setFormAction($this->ctrl->getFormAction($this));
+ $xoctPublicationGroupFormGUI->fillForm();
+ $this->main_tpl->setContent($xoctPublicationGroupFormGUI->getHTML());
+ }
+
+ protected function createGroup()
+ {
+ $xoctPublicationGroupFormGUI = new xoctPublicationGroupFormGUI($this, new PublicationUsageGroup());
+ $xoctPublicationGroupFormGUI->setValuesByPost();
+ if ($xoctPublicationGroupFormGUI->saveObject()) {
+ ilUtil::sendSuccess($this->plugin->txt('publication_usage_msg_success'), true);
+ $this->ctrl->redirect($this);
+ }
+ $this->main_tpl->setContent($xoctPublicationGroupFormGUI->getHTML());
+ }
+
+ protected function editGroup()
+ {
+ if (!PublicationUsageGroup::find($this->get_id)) {
+ ilUtil::sendFailure($this->plugin->txt('publication_usage_group_not_found'), true);
+ $this->ctrl->redirect($this);
+ }
+ $xoctPublicationGroupFormGUI = new xoctPublicationGroupFormGUI($this, PublicationUsageGroup::find($this->get_id), false);
+ $xoctPublicationGroupFormGUI->fillForm();
+ $this->main_tpl->setContent($xoctPublicationGroupFormGUI->getHTML());
+ }
+
+ protected function updateGroup()
+ {
+ $xoctPublicationGroupFormGUI = new xoctPublicationGroupFormGUI($this, PublicationUsageGroup::find($this->get_id), false);
+ $xoctPublicationGroupFormGUI->setValuesByPost();
+ if ($xoctPublicationGroupFormGUI->saveObject()) {
+ ilUtil::sendSuccess($this->plugin->txt('publication_usage_msg_success'), true);
+ $this->ctrl->redirect($this);
+ }
+ $this->main_tpl->setContent($xoctPublicationGroupFormGUI->getHTML());
+ }
+
+ protected function confirmDeleteGroup()
+ {
+ if (!PublicationUsageGroup::find($this->get_id)) {
+ ilUtil::sendFailure($this->plugin->txt('publication_usage_group_not_found'), true);
+ $this->ctrl->redirect($this);
+ }
+ $xoctPublicationUsageGroup = PublicationUsageGroup::find($this->get_id);
+ $confirm = new ilConfirmationGUI();
+ $confirm->setHeaderText($this->txt('confirm_delete_text_group'));
+ $confirm->addItem('id', $this->get_id, $xoctPublicationUsageGroup->getName());
+ $confirm->setFormAction($this->ctrl->getFormAction($this));
+ $confirm->setCancel($this->txt(self::CMD_CANCEL), self::CMD_CANCEL);
+ $confirm->setConfirm($this->txt(self::CMD_DELETE), self::CMD_DELETE_GROUP);
+
+ $this->main_tpl->setContent($confirm->getHTML());
+ }
+
+ protected function deleteGroup()
+ {
+ if (!PublicationUsageGroup::find($this->post_id)) {
+ ilUtil::sendFailure($this->plugin->txt('publication_usage_group_not_found'), true);
+ $this->ctrl->redirect($this);
+ }
+
+ $xoctPublicationUsageGroup = PublicationUsageGroup::find($this->post_id);
+ $xoctPublicationUsageGroup->delete();
$this->cancel();
}
+ ### End Group Section ###
}
diff --git a/classes/Conf/PublicationUsage/class.xoctPublicationUsageTableGUI.php b/classes/Conf/PublicationUsage/class.xoctPublicationUsageTableGUI.php
index 5e8deb034..601779067 100755
--- a/classes/Conf/PublicationUsage/class.xoctPublicationUsageTableGUI.php
+++ b/classes/Conf/PublicationUsage/class.xoctPublicationUsageTableGUI.php
@@ -2,6 +2,7 @@
use srag\Plugins\Opencast\Model\Publication\Config\PublicationUsage;
use srag\Plugins\Opencast\Model\Publication\Config\PublicationUsageRepository;
+use srag\Plugins\Opencast\Model\Publication\Config\PublicationUsageGroup;
use srag\Plugins\Opencast\DI\OpencastDIC;
/**
@@ -49,6 +50,7 @@ public function __construct(xoctPublicationUsageGUI $a_parent_obj, $a_parent_cmd
$this->ctrl->saveParameter($a_parent_obj, $this->getNavParameter());
parent::__construct($a_parent_obj, $a_parent_cmd);
$this->parent_obj = $a_parent_obj;
+ $this->setTitle($this->parent_obj->txt('table_title_usage'));
$this->setRowTemplate(
'tpl.publication_usage.html',
'Customizing/global/plugins/Services/Repository/RepositoryObject/OpenCast'
@@ -66,38 +68,56 @@ public function __construct(xoctPublicationUsageGUI $a_parent_obj, $a_parent_cmd
protected function fillRow($a_set)
{
/**
- * @var $PublicationUsage PublicationUsage
+ * @var $publication_usage PublicationUsage
*/
- $PublicationUsage = $this->repository->getUsage($a_set['usage_id']);
- $this->tpl->setVariable('USAGE_ID', $PublicationUsage->getUsageId());
- $this->tpl->setVariable('TITLE', $PublicationUsage->getTitle());
- $this->tpl->setVariable('DESCRIPTION', $PublicationUsage->getDescription());
- $this->tpl->setVariable('CHANNEL', $PublicationUsage->getChannel());
- $this->tpl->setVariable('MD_TYPE', $this->parent_obj->txt('md_type_' . $PublicationUsage->getMdType()));
- if ($PublicationUsage->getMdType() === PublicationUsage::MD_TYPE_PUBLICATION_ITSELF) {
+ $publication_usage = $this->repository->getUsage($a_set['usage_id']);
+ $this->tpl->setVariable('USAGE_ID', $publication_usage->getUsageId());
+ $this->tpl->setVariable('TITLE', $publication_usage->getTitle());
+ $this->tpl->setVariable('DISPLAY_NAME', $publication_usage->getDisplayName());
+ $this->tpl->setVariable('DESCRIPTION', $publication_usage->getDescription());
+ $this->tpl->setVariable('CHANNEL', $publication_usage->getChannel());
+ $this->tpl->setVariable('MD_TYPE', $this->parent_obj->txt('md_type_' . $publication_usage->getMdType()));
+ if ($publication_usage->getMdType() === PublicationUsage::MD_TYPE_PUBLICATION_ITSELF) {
$this->tpl->setVariable('FLAVOR', ' ');
$this->tpl->setVariable('TAG', ' ');
- } elseif ($PublicationUsage->getSearchKey() == xoctPublicationUsageFormGUI::F_FLAVOR) {
- $this->tpl->setVariable('FLAVOR', $PublicationUsage->getFlavor());
+ } elseif ($publication_usage->getSearchKey() == xoctPublicationUsageFormGUI::F_FLAVOR) {
+ $this->tpl->setVariable('FLAVOR', $publication_usage->getFlavor());
$this->tpl->setVariable('TAG', ' ');
} else {
- $this->tpl->setVariable('TAG', $PublicationUsage->getTag());
+ $this->tpl->setVariable('TAG', $publication_usage->getTag());
$this->tpl->setVariable('FLAVOR', ' ');
}
+ $group_name = '';
+ if (!is_null($publication_usage->getGroupId())) {
+ $publication_usage_group = PublicationUsageGroup::find($publication_usage->getGroupId());
+ $group_name = $publication_usage_group ? $publication_usage_group->getName() : $group_name;
+ }
+ $this->tpl->setVariable('GROUP_NAME', $group_name);
+
+ $extras = [];
+ if ($publication_usage->getUsageId() == PublicationUsage::USAGE_DOWNLOAD ||
+ $publication_usage->getUsageId() == PublicationUsage::USAGE_DOWNLOAD_FALLBACK) {
+ if ($publication_usage->isExternalDownloadSource()) {
+ $extras[] = $this->parent_obj->txt('ext_dl_source');
+ }
+ }
+ $this->tpl->setVariable('EXTRA_CONFIG', implode('
', $extras));
- $this->addActionMenu($PublicationUsage);
+ $this->addActionMenu($publication_usage);
}
protected function initColumns()
{
$this->addColumn($this->parent_obj->txt('usage_id'));
$this->addColumn($this->parent_obj->txt('title'));
+ $this->addColumn($this->parent_obj->txt('display_name'));
$this->addColumn($this->parent_obj->txt('description'));
$this->addColumn($this->parent_obj->txt('channel'));
$this->addColumn($this->parent_obj->txt('md_type'));
$this->addColumn($this->parent_obj->txt('flavor'));
$this->addColumn($this->parent_obj->txt('tag'));
- // $this->addColumn($this->txt('status'));
+ $this->addColumn($this->parent_obj->txt('group_th'));
+ $this->addColumn($this->parent_obj->txt('extra_config'));
$this->addColumn($this->plugin->txt('common_actions'), '', '150px');
}
diff --git a/classes/Conf/class.xoctConfFormGUI.php b/classes/Conf/class.xoctConfFormGUI.php
index ab25c9f4b..b7a531028 100644
--- a/classes/Conf/class.xoctConfFormGUI.php
+++ b/classes/Conf/class.xoctConfFormGUI.php
@@ -44,7 +44,7 @@ public function __construct(xoctConfGUI $parent_gui, $subtab_active)
$container = OpencastDIC::getInstance();
$this->main_tpl = $DIC->ui()->mainTemplate();
$this->plugin = $container->plugin();
- $this->main_tpl->addJavaScript($this->plugin->getDirectory().'/js/opencast/dist/index.js');
+ $this->main_tpl->addJavaScript($this->plugin->getDirectory() . '/js/opencast/dist/index.js');
$this->main_tpl->addCss($this->plugin->getStyleSheetLocation('default/password_toggle.css'));
parent::__construct();
$this->parent_gui = $parent_gui;
@@ -258,13 +258,6 @@ protected function initEventsSection(): void
$cb->setInfo($this->parent_gui->txt(PluginConfig::F_CREATE_SCHEDULED_ALLOWED . '_info'));
$this->addItem($cb);
- $cb = new ilCheckboxInputGUI(
- $this->parent_gui->txt(PluginConfig::F_EXT_DL_SOURCE),
- PluginConfig::F_EXT_DL_SOURCE
- );
- $cb->setInfo($this->parent_gui->txt(PluginConfig::F_EXT_DL_SOURCE . '_info'));
- $this->addItem($cb);
-
$cb = new ilCheckboxInputGUI(
$this->parent_gui->txt(PluginConfig::F_STUDIO_ALLOWED),
PluginConfig::F_STUDIO_ALLOWED
@@ -717,16 +710,19 @@ protected function initAdvancedSection()
);
$cb->addOption($opt);
$opt = new ilRadioOption(
- $this->parent_gui->txt(PluginConfig::F_ACTIVATE_CACHE . '_' . PluginConfig::CACHE_STANDARD),
- PluginConfig::CACHE_STANDARD
+ $this->parent_gui->txt(PluginConfig::F_ACTIVATE_CACHE . '_' . PluginConfig::CACHE_APCU),
+ PluginConfig::CACHE_APCU
);
$opt->setInfo(
$this->parent_gui->txt(
- PluginConfig::F_ACTIVATE_CACHE . '_' . PluginConfig::CACHE_STANDARD . '_info',
+ PluginConfig::F_ACTIVATE_CACHE . '_' . PluginConfig::CACHE_APCU . '_info',
'',
[]
)
);
+ $apc_available = !function_exists('apcu_fetch');
+ $opt->setDisabled($apc_available);
+
$cb->addOption($opt);
$opt = new ilRadioOption(
$this->parent_gui->txt(PluginConfig::F_ACTIVATE_CACHE . '_' . PluginConfig::CACHE_DATABASE),
diff --git a/classes/Event/class.xoctEventGUI.php b/classes/Event/class.xoctEventGUI.php
index 0f2c1f04d..bb3790fa3 100755
--- a/classes/Event/class.xoctEventGUI.php
+++ b/classes/Event/class.xoctEventGUI.php
@@ -4,7 +4,6 @@
use ILIAS\UI\Component\Input\Field\UploadHandler;
use ILIAS\UI\Renderer;
use srag\Plugins\Opencast\Model\ACL\ACLUtils;
-use srag\Plugins\Opencast\Model\Cache\CacheFactory;
use srag\Plugins\Opencast\Model\Config\PluginConfig;
use srag\Plugins\Opencast\Model\Event\Event;
use srag\Plugins\Opencast\Model\Event\EventRepository;
@@ -38,6 +37,7 @@
use srag\Plugins\OpenCast\UI\Component\Input\Field\Loader;
use srag\CustomInputGUIs\OneDrive\Waiter\Waiter;
use srag\Plugins\Opencast\API\OpencastAPI;
+use srag\Plugins\Opencast\Model\Cache\Services;
/**
* Class xoctEventGUI
@@ -73,6 +73,14 @@ class xoctEventGUI extends xoctGUI
* @var ilObjOpenCastGUI
*/
private $parent_gui;
+ /**
+ * @var WaitOverlay
+ */
+ private $wait_overlay;
+ /**
+ * @var Services
+ */
+ private $cache;
/**
* @var \ILIAS\UI\Implementation\DefaultRenderer
*/
@@ -169,7 +177,7 @@ public function __construct(
PaellaConfigServiceFactory $paellaConfigServiceFactory,
Container $dic
) {
- global $DIC;
+ global $DIC, $opencastContainer;
parent::__construct();
$this->user = $DIC->user();
@@ -193,6 +201,8 @@ public function __construct(
$this->ui_renderer = new \ILIAS\UI\Implementation\DefaultRenderer(
new Loader($DIC, ilOpenCastPlugin::getInstance())
);
+ $this->wait_overlay = new WaitOverlay($this->main_tpl);
+ $this->cache = $opencastContainer->get(Services::class);
}
/**
@@ -284,8 +294,7 @@ protected function performCommand($cmd)
*/
protected function prepareContent()
{
- xoctWaiterGUI::initJS();
- xoctWaiterGUI::addLinkOverlay('#rep_robj_xoct_event_clear_cache');
+ $this->wait_overlay->onLinkClick('#rep_robj_xoct_event_clear_cache');
$this->main_tpl->addJavascript("./src/UI/templates/js/Modal/modal.js");
$this->main_tpl->addOnLoadCode(
'xoctEvent.init(\'' . json_encode([
@@ -514,11 +523,11 @@ protected function loadAjaxCodeForList()
url: '{$ajax_link}',
dataType: 'html',
success: function(data){
- xoctWaiter.hide();
+ il.Opencast.UI.waitOverlay.hide();
$('div#xoct_table_placeholder').replaceWith($(data));
}
});";
- $this->main_tpl->addOnLoadCode('xoctWaiter.show();');
+ $this->main_tpl->addOnLoadCode('il.Opencast.UI.waitOverlay.show();');
$this->main_tpl->addOnLoadCode($ajax);
}
@@ -534,11 +543,11 @@ protected function loadAjaxCodeForTiles()
url: '{$ajax_link}',
dataType: 'html',
success: function(data){
- xoctWaiter.hide();
+ il.Opencast.UI.waitOverlay.hide();
$('div#xoct_tiles_placeholder').replaceWith($(data));
}
});";
- $this->main_tpl->addOnLoadCode('xoctWaiter.show();');
+ $this->main_tpl->addOnLoadCode('il.Opencast.UI.waitOverlay.show();');
$this->main_tpl->addOnLoadCode($ajax);
}
@@ -625,12 +634,8 @@ protected function add()
$this->objectSettings->getObjId(),
ilObjOpenCastAccess::hasPermission('edit_videos')
);
- xoctWaiterGUI::initJS();
- $this->main_tpl->addOnLoadCode(
- 'window.onbeforeunload = function(){
- xoctWaiter.show();
- };'
- );
+ $this->wait_overlay->onUnload();
+
$this->main_tpl->setContent($this->ui_renderer->render($form));
}
@@ -674,7 +679,7 @@ protected function create()
$this->ACLUtils->getBaseACLForUser(xoctUser::getInstance($this->user)),
new Processing(
PluginConfig::getConfig(PluginConfig::F_WORKFLOW),
- $this->getDefaultWorkflowParameters($data['workflow_configuration']['object'])
+ $this->getDefaultWorkflowParameters($data['workflow_configuration']['object'] ?? null)
),
xoctUploadFile::getInstanceFromFileArray($data['file']['file'])
)
@@ -906,21 +911,43 @@ public function download(): void
{
$event_id = filter_input(INPUT_GET, 'event_id', FILTER_SANITIZE_STRING);
$publication_id = filter_input(INPUT_GET, 'pub_id', FILTER_SANITIZE_STRING);
+ $usage_type = filter_input(INPUT_GET, 'usage_type', FILTER_SANITIZE_STRING);
+ $usage_id = filter_input(INPUT_GET, 'usage_id', FILTER_SANITIZE_STRING);
$event = $this->event_repository->find($event_id);
$download_publications = $event->publications()->getDownloadPublications();
+ // Now that we have multiple sub-usages, we first check for publication_id which is passed by the multi-dropdowns.
if ($publication_id) {
$publication = array_filter($download_publications, function ($publication) use ($publication_id): bool {
return $publication->getId() === $publication_id;
});
- $publication = array_shift($publication);
+ $publication = reset($publication);
} else {
- $publication = array_shift($download_publications);
+ // If this is not multi-download dropdown, then it has to have the usage_type and usage_id parameters identified.
+ if (!empty($usage_type) && !empty($usage_id)) {
+ $publication = array_filter(
+ $download_publications,
+ function ($publication) use ($usage_type, $usage_id): bool {
+ return $publication->usage_id == $usage_id && $publication->usage_type === $usage_type;
+ }
+ );
+ $publication = reset($publication);
+ } else {
+ // As a fallback we take out the last publication, if non of the above has been met!
+ $publication = reset($download_publications);
+ }
+ }
+
+ if (empty($publication)) {
+ ilUtil::sendFailure($this->txt('msg_no_download_publication'), true);
+ $this->ctrl->redirect($this, self::CMD_STANDARD);
}
+
$url = $publication->getUrl();
$extension = pathinfo($url)['extension'];
$url = PluginConfig::getConfig(PluginConfig::F_SIGN_DOWNLOAD_LINKS) ? xoctSecureLink::signDownload($url) : $url;
- if (PluginConfig::getConfig(PluginConfig::F_EXT_DL_SOURCE)) {
+ // if (PluginConfig::getConfig(PluginConfig::F_EXT_DL_SOURCE)) {
+ if (property_exists($publication, 'ext_dl_source') && $publication->ext_dl_source == true) {
// Open external source page
header('Location: ' . $url);
} else {
@@ -1222,12 +1249,9 @@ private function unpublish(Event $event): bool
return true;
}
- /**
- *
- */
- protected function clearCache()
+ protected function clearCache(): void
{
- CacheFactory::getInstance()->flush();
+ $this->cache->flushAdapter();
$this->ctrl->redirect($this, self::CMD_STANDARD);
}
diff --git a/classes/Event/class.xoctEventRenderer.php b/classes/Event/class.xoctEventRenderer.php
index 3c57e06ab..2ddc28fba 100644
--- a/classes/Event/class.xoctEventRenderer.php
+++ b/classes/Event/class.xoctEventRenderer.php
@@ -9,10 +9,15 @@
use srag\Plugins\Opencast\Model\Object\ObjectSettings;
use srag\Plugins\Opencast\Model\PerVideoPermission\PermissionGrant;
use srag\Plugins\Opencast\Model\Publication\Config\PublicationUsage;
+use srag\Plugins\Opencast\Model\Publication\Config\PublicationUsageGroup;
+use srag\Plugins\Opencast\Model\Publication\Config\PublicationUsageGroupRepository;
use srag\Plugins\Opencast\Model\Publication\Config\PublicationUsageRepository;
+use srag\Plugins\Opencast\Model\Publication\Config\PublicationSubUsageRepository;
use srag\Plugins\Opencast\Model\User\xoctUser;
use srag\Plugins\Opencast\UI\Modal\EventModals;
+use srag\Plugins\Opencast\Model\DTO\DownloadDto;
use srag\Plugins\Opencast\LegacyHelpers\TranslatorTrait;
+use srag\Plugins\Opencast\Util\Locale\LocaleTrait;
/**
* Class xoctEventRenderer
@@ -22,6 +27,7 @@
class xoctEventRenderer
{
use TranslatorTrait;
+ use LocaleTrait;
public const LANG_MODULE = 'event';
/**
@@ -53,6 +59,10 @@ class xoctEventRenderer
* @var EventModals
*/
protected static $modals;
+ /**
+ * @var array
+ */
+ private $dropdowns;
/**
* @var \ilCtrlInterface
*/
@@ -79,6 +89,7 @@ public function __construct(Event $event, ?ObjectSettings $objectSettings = null
$this->objectSettings = $objectSettings;
$this->factory = $ui->factory();
$this->renderer = $ui->renderer();
+ $this->dropdowns = [];
}
public static function initModals(EventModals $modals): void
@@ -105,6 +116,59 @@ public function insert(&$tpl, $variable, $value, $block_title = ''): void
}
}
+ /**
+ * Renders the dropdowns, in case the items to display is in a publication usage group.
+ * If a group has only one item, it renders it as normal that is why tpl is passed as reference.
+ * @param $tpl ilTemplate
+ */
+ public function renderDropdowns(&$tpl): void
+ {
+ $value = '';
+ $sorted_list = [];
+ if (!empty($this->dropdowns)) {
+ $sorted_list = PublicationUsageGroupRepository::getSortedArrayList(array_keys($this->dropdowns));
+ }
+ foreach ($sorted_list as $group_id => $group_data) {
+ $dropdown_contents = $this->dropdowns[$group_id];
+ if (count($dropdown_contents) > 1) {
+ $items = [];
+ foreach ($dropdown_contents as $content) {
+ $items[] = $this->factory->link()->standard(
+ $content['display_name'],
+ $content['link']
+ );
+ }
+ $display_name = $this->getLocaleString(
+ strtolower($group_data['display_name']),
+ PublicationUsageGroup::DISPLAY_NAME_LANG_MODULE,
+ $group_data['display_name']
+ );
+ if (empty($display_name)) {
+ $display_name = $this->getLocaleString('default', PublicationUsageGroup::DISPLAY_NAME_LANG_MODULE);
+ }
+ $dropdown = $this->factory->dropdown()->standard(
+ $items
+ )->withLabel($display_name);
+ $value .= $this->renderer->renderAsync($dropdown);
+ } else {
+ $content = reset($dropdown_contents);
+ $this->insert($tpl, $content['variable'], $content['html'], $content['block_title']);
+ continue;
+ }
+ }
+
+ if (!empty($value)) {
+ $block_title_dpdn = 'dropdown';
+ $variable_dpdb = 'DROPDOWN';
+ $tpl->setCurrentBlock($block_title_dpdn);
+
+ $tpl->setVariable($variable_dpdb, $value);
+
+ $tpl->parseCurrentBlock();
+ }
+ }
+
+
/**
* @param $tpl ilTemplate
* @param string $block_title
@@ -246,18 +310,54 @@ public function getModalLink(): string
* @throws ilTemplateException
* @throws xoctException
*/
- public function insertDownloadLink(
- &$tpl,
- $block_title = 'link',
- $variable = 'LINK',
- $button_type = 'btn-info'
- ): void {
- if ($download_link_html = $this->getDownloadLinkHTML($button_type)) {
- $this->insert($tpl, $variable, $download_link_html, $block_title);
+ public function insertDownloadLink(&$tpl, $block_title = 'link', $variable = 'LINK', $button_type = 'btn-info'): void
+ {
+ $publication_repository = new PublicationUsageRepository();
+ $publication_sub_repository = new PublicationSubUsageRepository();
+ $categorized_download_dtos = $this->event->publications()->getDownloadDtos(false);
+ foreach ($categorized_download_dtos as $usage_type => $content) {
+ foreach ($content as $usage_id => $download_dtos) {
+ $download_pub_usage = null;
+ $display_name = '';
+ if ($usage_type == PublicationUsage::USAGE_TYPE_ORG) {
+ $download_pub_usage = $publication_repository->getUsage($usage_id);
+ $display_name = $publication_repository->getDisplayName($usage_id);
+ } else {
+ $download_pub_usage = $publication_sub_repository->convertSingleSubToUsage($usage_id);
+ $display_name = $publication_sub_repository->getDisplayName($usage_id);
+ }
+
+ if (is_null($download_pub_usage)) {
+ continue;
+ }
+
+ if (empty($display_name)) {
+ $display_name = $this->translate('download', self::LANG_MODULE);
+ }
+
+ $download_html = $this->getDownloadLinkHTML($download_pub_usage, $download_dtos, $display_name, $button_type);
+ if (!empty($download_html)) {
+ $group_id = $download_pub_usage->getGroupId();
+ if (!is_null($group_id) && !$download_pub_usage->isAllowMultiple()) {
+ $this->dropdowns[$group_id][] = [
+ 'variable' => $variable,
+ 'display_name' => $display_name,
+ 'link' => $this->ctrl->getLinkTargetByClass(xoctEventGUI::class, xoctEventGUI::CMD_DOWNLOAD),
+ 'html' => $download_html,
+ 'block_title' => $block_title,
+ ];
+ } else {
+ $this->insert($tpl, $variable, $download_html, $block_title);
+ }
+ }
+ }
}
}
/**
+ * @param PublicationUsage $download_publication_usage
+ * @param DownloadDto[] $download_dtos
+ * @param string $display_name
* @param string $button_type
*
* @return string
@@ -265,17 +365,35 @@ public function insertDownloadLink(
* @throws ilTemplateException
* @throws xoctException
*/
- public function getDownloadLinkHTML($button_type = 'btn_info')
- {
- $download_dtos = $this->event->publications()->getDownloadDtos(false);
- if (($this->event->getProcessingState() == Event::STATE_SUCCEEDED) && ($download_dtos !== [])) {
- if ($this->objectSettings instanceof ObjectSettings && $this->objectSettings->getStreamingOnly()) {
+ public function getDownloadLinkHTML(
+ $download_publication_usage,
+ $download_dtos,
+ $display_name,
+ $button_type = 'btn_info'
+ ): string {
+ $html = '';
+ $ignore_object_settings = $download_publication_usage->ignoreObjectSettings();
+ $has_streaming_only = $this->objectSettings instanceof ObjectSettings && $this->objectSettings->getStreamingOnly();
+ $show_download = true;
+ if ($has_streaming_only && $ignore_object_settings == false) {
+ $show_download = false;
+ }
+ if (($this->event->getProcessingState() == Event::STATE_SUCCEEDED) && (count($download_dtos) > 0)) {
+ if (!$show_download) {
return '';
}
- $multi = (new PublicationUsageRepository())->getUsage(PublicationUsage::USAGE_DOWNLOAD)->isAllowMultiple();
+
+ // Setting event_id is necessary, because we use it for both multi approach with pub_id or subusage approach with usage_type and usage_id.
+ $this->ctrl->setParameterByClass(xoctEventGUI::class, 'event_id', $this->event->getIdentifier());
+
+ // Setting the floowing parameters to null first, so that we get accurate parameters later on in download action.
+ $this->ctrl->setParameterByClass(xoctEventGUI::class, 'pub_id', null);
+ $this->ctrl->setParameterByClass(xoctEventGUI::class, 'usage_type', null);
+ $this->ctrl->setParameterByClass(xoctEventGUI::class, 'usage_id', null);
+
+ $multi = $download_publication_usage->isAllowMultiple();
if ($multi) {
$items = array_map(function ($dto): \ILIAS\UI\Component\Link\Standard {
- $this->ctrl->setParameterByClass(xoctEventGUI::class, 'event_id', $this->event->getIdentifier());
$this->ctrl->setParameterByClass(xoctEventGUI::class, 'pub_id', $dto->getPublicationId());
return $this->factory->link()->standard(
$dto->getResolution(),
@@ -284,22 +402,25 @@ public function getDownloadLinkHTML($button_type = 'btn_info')
}, $download_dtos);
$dropdown = $this->factory->dropdown()->standard(
$items
- )->withLabel($this->plugin->txt(self::LANG_MODULE . '_download'));
- return $this->ui->renderer()->renderAsync($dropdown);
+ )->withLabel($display_name);
+ $html = $this->renderer->renderAsync($dropdown);
} else {
- $this->ctrl->setParameterByClass(xoctEventGUI::class, 'event_id', $this->event->getIdentifier());
+ $usage_type = $download_publication_usage->isSub() ? 'sub' : 'org';
+ $this->ctrl->setParameterByClass(xoctEventGUI::class, 'usage_type', $usage_type);
+ $usage_id = $usage_type === 'sub' ? $download_publication_usage->getSubId() :
+ $download_publication_usage->getUsageId();
+ $this->ctrl->setParameterByClass(xoctEventGUI::class, 'usage_id', $usage_id);
$link = $this->ctrl->getLinkTargetByClass(xoctEventGUI::class, xoctEventGUI::CMD_DOWNLOAD);
$link_tpl = $this->plugin->getTemplate('default/tpl.player_link.html');
$link_tpl->setVariable('TARGET', '_self');
$link_tpl->setVariable('BUTTON_TYPE', $button_type);
- $link_tpl->setVariable('LINK_TEXT', $this->plugin->txt(self::LANG_MODULE . '_download'));
+ $link_tpl->setVariable('LINK_TEXT', $display_name);
$link_tpl->setVariable('LINK_URL', $link);
- return $link_tpl->get();
+ $html = $link_tpl->get();
}
- } else {
- return '';
}
+ return $html;
}
/**
@@ -312,13 +433,21 @@ public function getDownloadLinkHTML($button_type = 'btn_info')
* @throws ilTemplateException
* @throws xoctException
*/
- public function insertAnnotationLink(
- &$tpl,
- $block_title = 'link',
- $variable = 'LINK',
- $button_type = 'btn-info'
- ): void {
- if ($annotation_link_html = $this->getAnnotationLinkHTML($button_type)) {
+ public function insertAnnotationLink(&$tpl, $block_title = 'link', $variable = 'LINK', $button_type = 'btn-info'): void
+ {
+ list($display_name, $annotation_link_html) = $this->getAnnotationLinkHTML($button_type);
+ if (!empty($annotation_link_html)) {
+ $annotatePublicationUsage = (new PublicationUsageRepository())->getUsage(PublicationUsage::USAGE_ANNOTATE);
+ $group_id = $annotatePublicationUsage->getGroupId();
+ if (!is_null($group_id)) {
+ $this->dropdowns[$group_id][] = [
+ 'variable' => $variable,
+ 'display_name' => $display_name,
+ 'link' => $this->ctrl->getLinkTargetByClass(xoctEventGUI::class, xoctEventGUI::CMD_ANNOTATE),
+ 'block_title' => $block_title,
+ ];
+ return;
+ }
$this->insert($tpl, $variable, $annotation_link_html, $block_title);
}
}
@@ -326,13 +455,18 @@ public function insertAnnotationLink(
/**
* @param string $button_type
*
- * @return string
+ * @return array
* @throws DICException
* @throws ilTemplateException
* @throws xoctException
*/
- public function getAnnotationLinkHTML($button_type = 'btn_info')
+ public function getAnnotationLinkHTML($button_type = 'btn_info'): array
{
+ $display_name = (new PublicationUsageRepository())->getDisplayName(PublicationUsage::USAGE_ANNOTATE);
+ if (empty($display_name)) {
+ $display_name = $this->translate('annotate', self::LANG_MODULE);
+ }
+ $html = '';
if (($this->event->getProcessingState() == Event::STATE_SUCCEEDED)
&& ($this->event->publications()->getAnnotationPublication())) {
$this->ctrl->setParameterByClass(
@@ -344,13 +478,12 @@ public function getAnnotationLinkHTML($button_type = 'btn_info')
$link_tpl = $this->plugin->getTemplate('default/tpl.player_link.html');
$link_tpl->setVariable('TARGET', '_blank');
$link_tpl->setVariable('BUTTON_TYPE', $button_type);
- $link_tpl->setVariable('LINK_TEXT', $this->plugin->txt(self::LANG_MODULE . '_annotate'));
+ $link_tpl->setVariable('LINK_TEXT', $display_name);
$link_tpl->setVariable('LINK_URL', $annotations_link);
- return $link_tpl->get();
- } else {
- return '';
+ $html = $link_tpl->get();
}
+ return [$display_name, $html];
}
/**
@@ -671,7 +804,8 @@ public function getActions(): array
$this->plugin->txt('event_startworkflow'),
self::$modals->getStartworkflowModal()->getShowSignal()
)->withOnLoadCode(function ($id) {
- return "$({$id}).on('click', function(event){ $('input#startworkflow_event_id').val('{$this->event->getIdentifier()}'); $('.startworkflow-form select#workflow_id').val(''); $('.startworkflow-form select#workflow_id').trigger('change');});";
+ return "$({$id}).on('click'," .
+ "function(event){ $('input#republish_event_id').val('{$this->event->getIdentifier()}'); });";
});
}
@@ -723,7 +857,9 @@ public function getActions(): array
$this->plugin->txt('event_report_quality_problem'),
self::$modals->getReportQualityModal()->getShowSignal()
)->withOnLoadCode(function ($id) {
- return "$({$id}).on('click', function(event){ $('input#xoct_report_quality_event_id').val('{$this->event->getIdentifier()}');$('#xoct_report_quality_modal textarea#message').focus(); });";
+ return "$({$id}).on('click', function(event){ " .
+ "$('input#xoct_report_quality_event_id').val('{$this->event->getIdentifier()}');" .
+ "$('#xoct_report_quality_modal textarea#message').focus(); });";
});
}
diff --git a/classes/Event/class.xoctEventTableGUI.php b/classes/Event/class.xoctEventTableGUI.php
index 6c62b8f22..7937fc68a 100755
--- a/classes/Event/class.xoctEventTableGUI.php
+++ b/classes/Event/class.xoctEventTableGUI.php
@@ -165,9 +165,8 @@ protected function fillRow($a_set)
$renderer->insertPreviewImage($this->tpl, null);
$renderer->insertPlayerLink($this->tpl);
- if (!$this->object_settings->getStreamingOnly()) {
- $renderer->insertDownloadLink($this->tpl);
- }
+ // The object settings will be checked based from within the insertDownloadLink method!
+ $renderer->insertDownloadLink($this->tpl);
if ($this->object_settings->getUseAnnotations()) {
$renderer->insertAnnotationLink($this->tpl);
@@ -195,6 +194,10 @@ protected function fillRow($a_set)
$renderer->insertUnprotectedLink($this->tpl, 'generic', 'VALUE');
}
+ // In order to render dropdowns, we have to call its method here (at the end),
+ // because the dropdown list gets its value during the call of download and annotate insertion.
+ $renderer->renderDropdowns($this->tpl);
+
$this->addActionMenu($event);
}
diff --git a/classes/Event/class.xoctEventTileGUI.php b/classes/Event/class.xoctEventTileGUI.php
index bc0ca4cf0..fe006ad75 100644
--- a/classes/Event/class.xoctEventTileGUI.php
+++ b/classes/Event/class.xoctEventTileGUI.php
@@ -126,12 +126,18 @@ public function getHTML()
$buttons_tpl = $this->plugin->getTemplate('default/tpl.event_buttons.html');
$event_renderer->insertPlayerLink($buttons_tpl, 'link', 'LINK', 'btn-default');
- if (!$this->objectSettings->getStreamingOnly()) {
- $event_renderer->insertDownloadLink($buttons_tpl, 'link', 'LINK', 'btn-default');
- }
+
+ // The object settings will be checked based from within the insertDownloadLink method!
+ $event_renderer->insertDownloadLink($buttons_tpl, 'link', 'LINK', 'btn-default');
+
if ($this->objectSettings->getUseAnnotations()) {
$event_renderer->insertAnnotationLink($buttons_tpl, 'link', 'LINK', 'btn-default');
}
+
+ // In order to render dropdowns, we have to call its method here (at the end),
+ // because the dropdown list gets its value during the call of download and annotate insertion.
+ $event_renderer->renderDropdowns($buttons_tpl);
+
$tile_tpl->setVariable('EVENT_BUTTONS', $buttons_tpl->get());
$card = $this->factory->card()->repositoryObject(
diff --git a/classes/IVTGroup/class.xoctPermissionGroupGUI.php b/classes/IVTGroup/class.xoctPermissionGroupGUI.php
index 102222f54..36c016b01 100644
--- a/classes/IVTGroup/class.xoctPermissionGroupGUI.php
+++ b/classes/IVTGroup/class.xoctPermissionGroupGUI.php
@@ -42,8 +42,9 @@ public function __construct(?ObjectSettings $objectSettings = null)
$this->objectSettings = new ObjectSettings();
}
$tabs->setTabActive(ilObjOpenCastGUI::TAB_GROUPS);
- // xoctGroup::installDB();
- xoctWaiterGUI::loadLib();
+
+ new WaitOverlay($this->main_tpl); // TODO check if needed
+
$main_tpl->addCss($this->plugin->getStyleSheetLocation('default/groups.css'));
$main_tpl->addJavaScript($this->plugin->getStyleSheetLocation('default/groups.js'));
}
diff --git a/classes/IVTGroup/class.xoctPermissionGroupParticipantGUI.php b/classes/IVTGroup/class.xoctPermissionGroupParticipantGUI.php
index 6ed3e8b67..181b1484a 100644
--- a/classes/IVTGroup/class.xoctPermissionGroupParticipantGUI.php
+++ b/classes/IVTGroup/class.xoctPermissionGroupParticipantGUI.php
@@ -35,7 +35,9 @@ public function __construct(?ObjectSettings $objectSettings = null)
$this->objectSettings = new ObjectSettings();
}
$tabs->setTabActive(ilObjOpenCastGUI::TAB_GROUPS);
- xoctWaiterGUI::loadLib();
+
+ new WaitOverlay($main_tpl); // TODO check if needed
+
$main_tpl->addJavaScript(
$this->plugin->getStyleSheetLocation('default/group_participants.js')
);
diff --git a/classes/Invitations/class.xoctGrantPermissionGUI.php b/classes/Invitations/class.xoctGrantPermissionGUI.php
index 1dfc8d8b7..00a2c61ce 100644
--- a/classes/Invitations/class.xoctGrantPermissionGUI.php
+++ b/classes/Invitations/class.xoctGrantPermissionGUI.php
@@ -51,7 +51,7 @@ public function __construct(ObjectSettings $objectSettings, EventRepository $eve
$tabs->clearTargets();
$tabs->setBackTarget($this->plugin->txt('tab_back'), $this->ctrl->getLinkTargetByClass(xoctEventGUI::class));
- xoctWaiterGUI::loadLib();
+ new WaitOverlay($this->main_tpl); // TODO check if needed
$main_tpl->addCss($this->plugin->getStyleSheetLocation('default/invitations.css'));
$main_tpl->addJavaScript($this->plugin->getStyleSheetLocation('default/invitations.js'));
$this->ctrl->saveParameter($this, xoctEventGUI::IDENTIFIER);
diff --git a/classes/Owner/class.xoctChangeOwnerGUI.php b/classes/Owner/class.xoctChangeOwnerGUI.php
index 68290d3b2..a7f43471e 100644
--- a/classes/Owner/class.xoctChangeOwnerGUI.php
+++ b/classes/Owner/class.xoctChangeOwnerGUI.php
@@ -60,7 +60,9 @@ public function __construct(ObjectSettings $objectSettings, EventRepository $eve
$this->plugin->txt('tab_back'),
$ctrl->getLinkTargetByClass(xoctEventGUI::class)
);
- xoctWaiterGUI::loadLib();
+
+ new WaitOverlay($this->main_tpl); // TODO check if needed
+
$main_tpl->addCss($this->plugin->getStyleSheetLocation('default/change_owner.css'));
$main_tpl->addJavaScript($this->plugin->getStyleSheetLocation('default/change_owner.js'));
$ctrl->saveParameter($this, xoctEventGUI::IDENTIFIER);
diff --git a/classes/Service/class.xoctEventAPI.php b/classes/Service/class.xoctEventAPI.php
index 0cd1326cb..beabdb14f 100644
--- a/classes/Service/class.xoctEventAPI.php
+++ b/classes/Service/class.xoctEventAPI.php
@@ -47,8 +47,9 @@ class xoctEventAPI
public function __construct()
{
+ global $opencastContainer;
+ $this->event_repository = $opencastContainer[EventAPIRepository::class];
$opencastDIC = OpencastDIC::getInstance();
- $this->event_repository = $opencastDIC->event_repository();
$this->md_factory = $opencastDIC->metadata()->metadataFactory();
$this->acl_utils = $opencastDIC->acl_utils();
$this->workflow_param_repository = $opencastDIC->workflow_parameter_series_repository();
diff --git a/classes/Service/class.xoctSeriesAPI.php b/classes/Service/class.xoctSeriesAPI.php
index fa3aee56b..e0504bcb4 100644
--- a/classes/Service/class.xoctSeriesAPI.php
+++ b/classes/Service/class.xoctSeriesAPI.php
@@ -15,6 +15,7 @@
use srag\Plugins\Opencast\Model\Series\SeriesRepository;
use srag\Plugins\Opencast\Model\User\xoctUser;
use srag\Plugins\Opencast\Model\WorkflowParameter\Series\SeriesWorkflowParameterRepository;
+use srag\Plugins\Opencast\Model\Series\SeriesAPIRepository;
/**
* Class xoctSeriesAPI
@@ -51,8 +52,9 @@ class xoctSeriesAPI
*/
public function __construct()
{
+ global $opencastContainer;
+ $this->series_repository = $opencastContainer->get(SeriesAPIRepository::class);
$opencastDIC = OpencastDIC::getInstance();
- $this->series_repository = $opencastDIC->series_repository();
$this->seriesWorkflowParameterRepository = $opencastDIC->workflow_parameter_series_repository();
$this->metadataFactory = $opencastDIC->metadata()->metadataFactory();
$this->aclUtils = $opencastDIC->acl_utils();
diff --git a/classes/class.ilObjOpenCastGUI.php b/classes/class.ilObjOpenCastGUI.php
index d5c8298ff..e9846a3b4 100755
--- a/classes/class.ilObjOpenCastGUI.php
+++ b/classes/class.ilObjOpenCastGUI.php
@@ -16,6 +16,8 @@
use srag\Plugins\Opencast\Model\Series\Request\CreateSeriesRequestPayload;
use srag\Plugins\Opencast\Model\User\xoctUser;
use srag\Plugins\Opencast\UI\LegacyFormWrapper;
+use srag\Plugins\Opencast\Model\Event\EventAPIRepository;
+use srag\Plugins\Opencast\Model\Series\SeriesAPIRepository;
/**
* User Interface class for example repository object.
@@ -30,6 +32,9 @@
*/
class ilObjOpenCastGUI extends ilObjectPluginGUI
{
+ /**
+ * @var mixed
+ */
public $creation_mode;
public const PLUGIN_CLASS_NAME = ilOpenCastPlugin::class;
@@ -61,16 +66,16 @@ class ilObjOpenCastGUI extends ilObjectPluginGUI
* @var Container
*/
private $ilias_dic;
+ /**
+ * @var \srag\Plugins\Opencast\Container\Container
+ */
+ private $container;
- private function cleanUpDBCache(): void
+ public function __construct($a_ref_id = 0, $a_id_type = self::REPOSITORY_NODE_ID, $a_parent_node_id = 0)
{
- if (PluginConfig::getConfig(PluginConfig::F_ACTIVATE_CACHE) == PluginConfig::CACHE_DATABASE) {
- $bm = microtime(true);
- DBCacheService::cleanup($this->ilias_dic->database());
- $this->ilias_dic->logger()->root()->info(
- 'cache cleanup done in ' . round((microtime(true) - $bm) * 1000) . 'ms'
- );
- }
+ parent::__construct($a_ref_id, $a_id_type, $a_parent_node_id);
+ global $opencastContainer;
+ $this->container = $opencastContainer;
}
protected function afterConstructor()
@@ -120,7 +125,7 @@ public function executeCommand(): void
$this->setTabs();
$xoctGrantPermissionGUI = new xoctGrantPermissionGUI(
$objectSettings,
- $this->opencast_dic->event_repository(),
+ $this->container[EventAPIRepository::class],
$this->opencast_dic->acl_utils()
);
$this->ilias_dic->ctrl()->forwardCommand($xoctGrantPermissionGUI);
@@ -131,7 +136,7 @@ public function executeCommand(): void
$this->setTabs();
$xoctChangeOwnerGUI = new xoctChangeOwnerGUI(
$objectSettings,
- $this->opencast_dic->event_repository(),
+ $this->container[EventAPIRepository::class],
$this->opencast_dic->acl_utils()
);
$this->ilias_dic->ctrl()->forwardCommand($xoctChangeOwnerGUI);
@@ -143,7 +148,7 @@ public function executeCommand(): void
$xoctSeriesGUI = new xoctSeriesGUI(
$this->object,
$this->opencast_dic->series_form_builder(),
- $this->opencast_dic->series_repository(),
+ $this->container->get(SeriesAPIRepository::class),
$this->opencast_dic->workflow_parameter_series_repository(),
$this->opencast_dic->workflow_parameter_conf_repository()
);
@@ -156,12 +161,12 @@ public function executeCommand(): void
$xoctEventGUI = new xoctEventGUI(
$this,
$objectSettings,
- $this->opencast_dic->event_repository(),
+ $this->container[EventAPIRepository::class],
$this->opencast_dic->event_form_builder(),
$this->opencast_dic->event_table_builder(),
$this->opencast_dic->workflow_repository(),
$this->opencast_dic->acl_utils(),
- $this->opencast_dic->series_repository(),
+ $this->container->get(SeriesAPIRepository::class),
$this->opencast_dic->upload_handler(),
$this->opencast_dic->paella_config_storage_service(),
$this->opencast_dic->paella_config_service_factory(),
@@ -199,8 +204,6 @@ public function executeCommand(): void
$this->showMainTemplate();
}
}
-
- $this->cleanUpDBCache();
}
public function getObject(): ilObjOpenCast
@@ -438,7 +441,7 @@ public function afterSave(ilObject $newObj): void
}
// TODO: do we need contributor / organizer?
if (!$series_id) {
- $series_id = $this->opencast_dic->series_repository()->create(
+ $series_id = $this->container->get(SeriesAPIRepository::class)->create(
new CreateSeriesRequest(
new CreateSeriesRequestPayload(
$metadata,
@@ -447,7 +450,7 @@ public function afterSave(ilObject $newObj): void
)
);
} else {
- $metadata = $this->opencast_dic->series_repository()->find($series_id)->getMetadata();
+ $metadata = $this->container->get(SeriesAPIRepository::class)->find($series_id)->getMetadata();
}
if ($series_id !== null) {
@@ -500,7 +503,6 @@ protected function initHeader($render_locator = true)
$this->ilias_dic->ui()->mainTemplate()->setTitle($this->object->getTitle());
$this->ilias_dic->ui()->mainTemplate()->setDescription($this->object->getDescription());
if ($this->ilias_dic->access()->checkAccess('read', '', $_GET['ref_id'])) {
- // TODO: remove self::dic
$DIC['ilNavigationHistory']->addItem(
$_GET['ref_id'],
$this->ilias_dic->ctrl()->getLinkTarget($this, $this->getStandardCmd()),
@@ -557,7 +559,7 @@ public function infoScreen(): void
}
if ($objectSettings->getVideoPortalLink()
- && $this->opencast_dic->series_repository()->find(
+ && $this->container->get(SeriesAPIRepository::class)->find(
$objectSettings->getSeriesIdentifier()
)->isPublishedOnVideoPortal()) {
$info->addSection($this->plugin->txt('series_links'));
diff --git a/classes/class.xoctMainGUI.php b/classes/class.xoctMainGUI.php
index 5b06786f6..b9616ecf5 100644
--- a/classes/class.xoctMainGUI.php
+++ b/classes/class.xoctMainGUI.php
@@ -36,6 +36,10 @@ class xoctMainGUI extends xoctGUI
*/
private $tabs;
+ public const SUBTAB_PUBLICATION_USAGE = 'publication_usage';
+ public const SUBTAB_PUBLICATION_SUB_USAGE = 'publication_sub_usage';
+ public const SUBTAB_PUBLICATION_GROUPS = 'publication_groups';
+
public function __construct()
{
global $DIC;
@@ -100,6 +104,7 @@ public function executeCommand(): void
switch ($nextClass) {
case strtolower(xoctPublicationUsageGUI::class):
$this->tabs->activateTab(self::TAB_PUBLICATION_USAGE);
+ $this->setPublicationSubTabs();
$xoctPublicationUsageGUI = new xoctPublicationUsageGUI();
$this->ctrl->forwardCommand($xoctPublicationUsageGUI);
break;
@@ -197,6 +202,30 @@ protected function setSubTabs()
$this->ctrl->clearParametersByClass(xoctConfGUI::class);
}
+ protected function setPublicationSubTabs()
+ {
+ $this->ctrl->setParameterByClass(xoctPublicationUsageGUI::class, 'pub_subtab_active', self::SUBTAB_PUBLICATION_USAGE);
+ $this->tabs->addSubTab(
+ self::SUBTAB_PUBLICATION_USAGE,
+ $this->plugin->txt('subtab_' . self::SUBTAB_PUBLICATION_USAGE),
+ $this->ctrl->getLinkTargetByClass(xoctPublicationUsageGUI::class)
+ );
+ $this->ctrl->setParameterByClass(xoctPublicationUsageGUI::class, 'pub_subtab_active', self::SUBTAB_PUBLICATION_SUB_USAGE);
+ $this->tabs->addSubTab(
+ self::SUBTAB_PUBLICATION_SUB_USAGE,
+ $this->plugin->txt('subtab_' . self::SUBTAB_PUBLICATION_SUB_USAGE),
+ $this->ctrl->getLinkTargetByClass(xoctPublicationUsageGUI::class)
+ );
+ $this->ctrl->setParameterByClass(xoctPublicationUsageGUI::class, 'pub_subtab_active', self::SUBTAB_PUBLICATION_GROUPS);
+ $this->tabs->addSubTab(
+ self::SUBTAB_PUBLICATION_GROUPS,
+ $this->plugin->txt('subtab_' . self::SUBTAB_PUBLICATION_GROUPS),
+ $this->ctrl->getLinkTargetByClass(xoctPublicationUsageGUI::class)
+ );
+ $this->ctrl->clearParametersByClass(xoctPublicationUsageGUI::class);
+ }
+
+
protected function setWorkflowsSubTabs()
{
$this->ctrl->setParameterByClass(xoctWorkflowGUI::class, 'wf_subtab_active', self::SUBTAB_WORKFLOWS_SETTINGS);
diff --git a/classes/class.xoctWaiterGUI.php b/classes/class.xoctWaiterGUI.php
deleted file mode 100644
index 8e99a3d32..000000000
--- a/classes/class.xoctWaiterGUI.php
+++ /dev/null
@@ -1,85 +0,0 @@
-
- * @version 1.0.0
- */
-class xoctWaiterGUI
-{
- public const PLUGIN_CLASS_NAME = ilOpenCastPlugin::class;
-
- /**
- * @var bool
- */
- protected static $init = false;
- /**
- * @var bool
- */
- protected static $init_js = false;
-
- /**
- *
- */
- public static function loadLib(): void
- {
- global $DIC;
- $main_tpl = $DIC->ui()->mainTemplate();
- if (!self::$init) {
- $main_tpl->addJavaScript(
- './Customizing/global/plugins/Services/Repository/RepositoryObject/OpenCast/templates/default/waiter.min.js'
- );
- $main_tpl->addCss(
- './Customizing/global/plugins/Services/Repository/RepositoryObject/OpenCast/templates/default/waiter.css'
- );
- self::$init = true;
- }
- }
-
- /**
- * @param string $type
- */
- public static function initJS($type = 'waiter'): void
- {
- global $DIC;
- $main_tpl = $DIC->ui()->mainTemplate();
- self::loadLib();
- if (!self::$init_js) {
- $code = 'xoctWaiter.init(\'' . $type . '\');';
- $main_tpl->addOnLoadCode($code);
- self::$init_js = true;
- }
- }
-
- /**
- * @param $dom_selector_string
- */
- public static function addListener($dom_selector_string): void
- {
- global $DIC;
- $main_tpl = $DIC->ui()->mainTemplate();
- $code = 'xoctWaiter.addListener("' . $dom_selector_string . '");';
- $main_tpl->addOnLoadCode($code);
- }
-
- /**
- * @param $dom_selector_string
- */
- public static function addLinkOverlay($dom_selector_string): void
- {
- global $DIC;
- $main_tpl = $DIC->ui()->mainTemplate();
- $code = 'xoctWaiter.addLinkOverlay("' . $dom_selector_string . '");';
- $main_tpl->addOnLoadCode($code);
- }
-
- public static function show(): void
- {
- global $DIC;
- $main_tpl = $DIC->ui()->mainTemplate();
- self::initJS();
- $code = 'xoctWaiter.show();';
- $main_tpl->addOnLoadCode($code);
- }
-}
diff --git a/composer.json b/composer.json
index 78a693678..e1926aae8 100644
--- a/composer.json
+++ b/composer.json
@@ -18,7 +18,7 @@
"prefer-stable": true,
"require": {
"php": ">=7.3",
- "elan-ev/opencast-api": "1.4",
+ "elan-ev/opencast-api": "1.5",
"srag/custominputguis": ">=0.1.0",
"srag/datatable": ">=0.1.0",
"srag/dic": ">=0.1.0",
diff --git a/composer.lock b/composer.lock
index a6a5891bd..8f9a9930d 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,20 +4,20 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "3ec6035552927b2808b955c9ba4217c5",
+ "content-hash": "c514e8f9e82f7cdff520698cb95baa64",
"packages": [
{
"name": "elan-ev/opencast-api",
- "version": "1.4.0",
+ "version": "1.5.0",
"source": {
"type": "git",
"url": "https://github.com/elan-ev/opencast-php-library.git",
- "reference": "34b46fb9c0986fc7e4ecd05a45038612da7409c9"
+ "reference": "dfcfa0789c8a670623ed27434ced88f595941b73"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/elan-ev/opencast-php-library/zipball/34b46fb9c0986fc7e4ecd05a45038612da7409c9",
- "reference": "34b46fb9c0986fc7e4ecd05a45038612da7409c9",
+ "url": "https://api.github.com/repos/elan-ev/opencast-php-library/zipball/dfcfa0789c8a670623ed27434ced88f595941b73",
+ "reference": "dfcfa0789c8a670623ed27434ced88f595941b73",
"shasum": ""
},
"require": {
@@ -61,9 +61,9 @@
],
"support": {
"issues": "https://github.com/elan-ev/opencast-php-library/issues",
- "source": "https://github.com/elan-ev/opencast-php-library/tree/1.4.0"
+ "source": "https://github.com/elan-ev/opencast-php-library/tree/1.5.0"
},
- "time": "2023-07-21T11:58:16+00:00"
+ "time": "2023-11-13T16:47:55+00:00"
},
{
"name": "guzzlehttp/guzzle",
@@ -3227,8 +3227,8 @@
"prefer-stable": true,
"prefer-lowest": false,
"platform": {
- "php": ">=7.0"
+ "php": ">=7.3"
},
"platform-dev": [],
- "plugin-api-version": "2.3.0"
+ "plugin-api-version": "2.6.0"
}
diff --git a/configuration/default_config.xml b/configuration/default_config.xml
index e7ab0afc1..016645a60 100644
--- a/configuration/default_config.xml
+++ b/configuration/default_config.xml
@@ -262,10 +262,6 @@
workflow_unpublish
-
- external_download_source
-
-
presenter-mandatory
diff --git a/doc/codestyle/run-code-format.sh b/doc/codestyle/run-code-format.sh
index 4f5c3195a..f3923a129 100755
--- a/doc/codestyle/run-code-format.sh
+++ b/doc/codestyle/run-code-format.sh
@@ -5,7 +5,7 @@ if [[ ! -z "$1" ]]
then
PATHS=$1
else
- PATHS=$(git diff --name-only --cached | tr -u '\n' ' ')
+ PATHS=$(git diff --name-only --cached | xargs ls -d 2>/dev/null | tr -u '\n' ' ')
if [[ -z "$PATHS" ]]
then
PATHS=$TOP_LEVEL
diff --git a/js/opencast/dist/index.js b/js/opencast/dist/index.js
index ae7febd83..0a5485656 100644
--- a/js/opencast/dist/index.js
+++ b/js/opencast/dist/index.js
@@ -1 +1 @@
-!function(t,e){"use strict";function n(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var r=n(t),o=n(e);"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;function i(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var a=i(function(t,e,n){return t(n={path:e,exports:{},require:function(t,e){return function(){throw new Error("Dynamic requires are not currently supported by @rollup/plugin-commonjs")}(null==e&&n.path)}},n.exports),n.exports}((function(t,e){var n;n=()=>(()=>{var t={383:(t,e,n)=>{n.r(e),n.d(e,{default:()=>f});var r=n(622),o=n(689),i=n.n(o);function a(t){return(a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function s(){s=function(){return t};var t={},e=Object.prototype,n=e.hasOwnProperty,r=Object.defineProperty||function(t,e,n){t[e]=n.value},o="function"==typeof Symbol?Symbol:{},i=o.iterator||"@@iterator",c=o.asyncIterator||"@@asyncIterator",u=o.toStringTag||"@@toStringTag";function l(t,e,n){return Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}),t[e]}try{l({},"")}catch(t){l=function(t,e,n){return t[e]=n}}function f(t,e,n,o){var i=e&&e.prototype instanceof d?e:d,a=Object.create(i.prototype),s=new L(o||[]);return r(a,"_invoke",{value:E(t,n,s)}),a}function h(t,e,n){try{return{type:"normal",arg:t.call(e,n)}}catch(t){return{type:"throw",arg:t}}}t.wrap=f;var p={};function d(){}function y(){}function v(){}var g={};l(g,i,(function(){return this}));var m=Object.getPrototypeOf,b=m&&m(m(S([])));b&&b!==e&&n.call(b,i)&&(g=b);var w=v.prototype=d.prototype=Object.create(g);function A(t){["next","throw","return"].forEach((function(e){l(t,e,(function(t){return this._invoke(e,t)}))}))}function x(t,e){function o(r,i,s,c){var u=h(t[r],t,i);if("throw"!==u.type){var l=u.arg,f=l.value;return f&&"object"==a(f)&&n.call(f,"__await")?e.resolve(f.__await).then((function(t){o("next",t,s,c)}),(function(t){o("throw",t,s,c)})):e.resolve(f).then((function(t){l.value=t,s(l)}),(function(t){return o("throw",t,s,c)}))}c(u.arg)}var i;r(this,"_invoke",{value:function(t,n){function r(){return new e((function(e,r){o(t,n,e,r)}))}return i=i?i.then(r,r):r()}})}function E(t,e,n){var r="suspendedStart";return function(o,i){if("executing"===r)throw new Error("Generator is already running");if("completed"===r){if("throw"===o)throw i;return{value:void 0,done:!0}}for(n.method=o,n.arg=i;;){var a=n.delegate;if(a){var s=C(a,n);if(s){if(s===p)continue;return s}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if("suspendedStart"===r)throw r="completed",n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);r="executing";var c=h(t,e,n);if("normal"===c.type){if(r=n.done?"completed":"suspendedYield",c.arg===p)continue;return{value:c.arg,done:n.done}}"throw"===c.type&&(r="completed",n.method="throw",n.arg=c.arg)}}}function C(t,e){var n=e.method,r=t.iterator[n];if(void 0===r)return e.delegate=null,"throw"===n&&t.iterator.return&&(e.method="return",e.arg=void 0,C(t,e),"throw"===e.method)||"return"!==n&&(e.method="throw",e.arg=new TypeError("The iterator does not provide a '"+n+"' method")),p;var o=h(r,t.iterator,e.arg);if("throw"===o.type)return e.method="throw",e.arg=o.arg,e.delegate=null,p;var i=o.arg;return i?i.done?(e[t.resultName]=i.value,e.next=t.nextLoc,"return"!==e.method&&(e.method="next",e.arg=void 0),e.delegate=null,p):i:(e.method="throw",e.arg=new TypeError("iterator result is not an object"),e.delegate=null,p)}function k(t){var e={tryLoc:t[0]};1 in t&&(e.catchLoc=t[1]),2 in t&&(e.finallyLoc=t[2],e.afterLoc=t[3]),this.tryEntries.push(e)}function _(t){var e=t.completion||{};e.type="normal",delete e.arg,t.completion=e}function L(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(k,this),this.reset(!0)}function S(t){if(t){var e=t[i];if(e)return e.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var r=-1,o=function e(){for(;++r=0;--o){var i=this.tryEntries[o],a=i.completion;if("root"===i.tryLoc)return r("end");if(i.tryLoc<=this.prev){var s=n.call(i,"catchLoc"),c=n.call(i,"finallyLoc");if(s&&c){if(this.prev=0;--r){var o=this.tryEntries[r];if(o.tryLoc<=this.prev&&n.call(o,"finallyLoc")&&this.prev=0;--e){var n=this.tryEntries[e];if(n.finallyLoc===t)return this.complete(n.completion,n.afterLoc),_(n),p}},catch:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var n=this.tryEntries[e];if(n.tryLoc===t){var r=n.completion;if("throw"===r.type){var o=r.arg;_(n)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(t,e,n){return this.delegate={iterator:S(t),resultName:e,nextLoc:n},"next"===this.method&&(this.arg=void 0),p}},t}function c(t,e,n,r,o,i,a){try{var s=t[i](a),c=s.value}catch(t){return void n(t)}s.done?e(c):Promise.resolve(c).then(r,o)}function u(t,e){return(u=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t})(t,e)}function l(t){return(l=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}var f=function(t){!function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),Object.defineProperty(t,"prototype",{writable:!1}),e&&u(t,e)}(d,t);var e,n,r,o,f,h,p=(f=d,h=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(t){return!1}}(),function(){var t,e=l(f);if(h){var n=l(this).constructor;t=Reflect.construct(e,arguments,n)}else t=e.apply(this,arguments);return function(t,e){if(e&&("object"===a(e)||"function"==typeof e))return e;if(void 0!==e)throw new TypeError("Derived constructors may only return object or undefined");return function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t)}(this,t)});function d(){return function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,d),p.apply(this,arguments)}return e=d,(n=[{key:"load",value:(r=s().mark((function t(){return s().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:this.icon=this.player.getCustomPluginIcon(this.name,"buttonIcon")||i();case 1:case"end":return t.stop()}}),t,this)})),o=function(){var t=this,e=arguments;return new Promise((function(n,o){var i=r.apply(t,e);function a(t){c(i,n,o,a,s,"next",t)}function s(t){c(i,n,o,a,s,"throw",t)}a(void 0)}))},function(){return o.apply(this,arguments)})}])&&function(t,e){for(var n=0;n0&&e-1 in t)}function L(t,e){return t.nodeName&&t.nodeName.toLowerCase()===e.toLowerCase()}k.fn=k.prototype={jquery:E,constructor:k,length:0,toArray:function(){return s.call(this)},get:function(t){return null==t?s.call(this):t<0?this[t+this.length]:this[t]},pushStack:function(t){var e=k.merge(this.constructor(),t);return e.prevObject=this,e},each:function(t){return k.each(this,t)},map:function(t){return this.pushStack(k.map(this,(function(e,n){return t.call(e,n,e)})))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(k.grep(this,(function(t,e){return(e+1)%2})))},odd:function(){return this.pushStack(k.grep(this,(function(t,e){return e%2})))},eq:function(t){var e=this.length,n=+t+(t<0?e:0);return this.pushStack(n>=0&&n+~]|"+O+")"+O+"*"),G=new RegExp(O+"|>"),H=new RegExp(N),$=new RegExp("^"+I+"$"),V={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+j),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+O+"*(even|odd|(([+-]|)(\\d*)n|)"+O+"*(?:([+-]|)"+O+"*(\\d+)|))"+O+"*\\)|)","i"),bool:new RegExp("^(?:"+_+")$","i"),needsContext:new RegExp("^"+O+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+O+"*((?:-\\d)?\\d*)"+O+"*\\)|)(?=[^-]|$)","i")},Z=/^(?:input|select|textarea|button)$/i,z=/^h\d$/i,K=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,Y=/[+~]/,W=new RegExp("\\\\[\\da-fA-F]{1,6}"+O+"?|\\\\([^\\r\\n\\f])","g"),q=function(t,e){var n="0x"+t.slice(1)-65536;return e||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},X=function(){ct()},Q=ht((function(t){return!0===t.disabled&&L(t,"fieldset")}),{dir:"parentNode",next:"legend"});try{y.apply(i=s.call(D.childNodes),D.childNodes),i[D.childNodes.length].nodeType}catch(t){y={apply:function(t,e){B.apply(t,s.call(e))},call:function(t){B.apply(t,s.call(arguments,1))}}}function J(t,e,n,r){var o,i,a,s,u,l,p,d=e&&e.ownerDocument,m=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==m&&9!==m&&11!==m)return n;if(!r&&(ct(e),e=e||c,f)){if(11!==m&&(u=K.exec(t)))if(o=u[1]){if(9===m){if(!(a=e.getElementById(o)))return n;if(a.id===o)return y.call(n,a),n}else if(d&&(a=d.getElementById(o))&&J.contains(e,a)&&a.id===o)return y.call(n,a),n}else{if(u[2])return y.apply(n,e.getElementsByTagName(t)),n;if((o=u[3])&&e.getElementsByClassName)return y.apply(n,e.getElementsByClassName(o)),n}if(!(E[t+" "]||h&&h.test(t))){if(p=t,d=e,1===m&&(G.test(t)||U.test(t))){for((d=Y.test(t)&&st(e.parentNode)||e)==e&&v.scope||((s=e.getAttribute("id"))?s=k.escapeSelector(s):e.setAttribute("id",s=g)),i=(l=lt(t)).length;i--;)l[i]=(s?"#"+s:":scope")+" "+ft(l[i]);p=l.join(",")}try{return y.apply(n,d.querySelectorAll(p)),n}catch(e){E(t,!0)}finally{s===g&&e.removeAttribute("id")}}}return mt(t.replace(R,"$1"),e,n,r)}function tt(){var t=[];return function n(r,o){return t.push(r+" ")>e.cacheLength&&delete n[t.shift()],n[r+" "]=o}}function et(t){return t[g]=!0,t}function nt(t){var e=c.createElement("fieldset");try{return!!t(e)}catch(t){return!1}finally{e.parentNode&&e.parentNode.removeChild(e),e=null}}function rt(t){return function(e){return L(e,"input")&&e.type===t}}function ot(t){return function(e){return(L(e,"input")||L(e,"button"))&&e.type===t}}function it(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&Q(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function at(t){return et((function(e){return e=+e,et((function(n,r){for(var o,i=t([],n.length,e),a=i.length;a--;)n[o=i[a]]&&(n[o]=!(r[o]=n[o]))}))}))}function st(t){return t&&void 0!==t.getElementsByTagName&&t}function ct(t){var n,r=t?t.ownerDocument||t:D;return r!=c&&9===r.nodeType&&r.documentElement?(u=(c=r).documentElement,f=!k.isXMLDoc(c),d=u.matches||u.webkitMatchesSelector||u.msMatchesSelector,D!=c&&(n=c.defaultView)&&n.top!==n&&n.addEventListener("unload",X),v.getById=nt((function(t){return u.appendChild(t).id=k.expando,!c.getElementsByName||!c.getElementsByName(k.expando).length})),v.disconnectedMatch=nt((function(t){return d.call(t,"*")})),v.scope=nt((function(){return c.querySelectorAll(":scope")})),v.cssHas=nt((function(){try{return c.querySelector(":has(*,:jqfake)"),!1}catch(t){return!0}})),v.getById?(e.filter.ID=function(t){var e=t.replace(W,q);return function(t){return t.getAttribute("id")===e}},e.find.ID=function(t,e){if(void 0!==e.getElementById&&f){var n=e.getElementById(t);return n?[n]:[]}}):(e.filter.ID=function(t){var e=t.replace(W,q);return function(t){var n=void 0!==t.getAttributeNode&&t.getAttributeNode("id");return n&&n.value===e}},e.find.ID=function(t,e){if(void 0!==e.getElementById&&f){var n,r,o,i=e.getElementById(t);if(i){if((n=i.getAttributeNode("id"))&&n.value===t)return[i];for(o=e.getElementsByName(t),r=0;i=o[r++];)if((n=i.getAttributeNode("id"))&&n.value===t)return[i]}return[]}}),e.find.TAG=function(t,e){return void 0!==e.getElementsByTagName?e.getElementsByTagName(t):e.querySelectorAll(t)},e.find.CLASS=function(t,e){if(void 0!==e.getElementsByClassName&&f)return e.getElementsByClassName(t)},h=[],nt((function(t){var e;u.appendChild(t).innerHTML="",t.querySelectorAll("[selected]").length||h.push("\\["+O+"*(?:value|"+_+")"),t.querySelectorAll("[id~="+g+"-]").length||h.push("~="),t.querySelectorAll("a#"+g+"+*").length||h.push(".#.+[+~]"),t.querySelectorAll(":checked").length||h.push(":checked"),(e=c.createElement("input")).setAttribute("type","hidden"),t.appendChild(e).setAttribute("name","D"),u.appendChild(t).disabled=!0,2!==t.querySelectorAll(":disabled").length&&h.push(":enabled",":disabled"),(e=c.createElement("input")).setAttribute("name",""),t.appendChild(e),t.querySelectorAll("[name='']").length||h.push("\\["+O+"*name"+O+"*="+O+"*(?:''|\"\")")})),v.cssHas||h.push(":has"),h=h.length&&new RegExp(h.join("|")),C=function(t,e){if(t===e)return a=!0,0;var n=!t.compareDocumentPosition-!e.compareDocumentPosition;return n||(1&(n=(t.ownerDocument||t)==(e.ownerDocument||e)?t.compareDocumentPosition(e):1)||!v.sortDetached&&e.compareDocumentPosition(t)===n?t===c||t.ownerDocument==D&&J.contains(D,t)?-1:e===c||e.ownerDocument==D&&J.contains(D,e)?1:o?l.call(o,t)-l.call(o,e):0:4&n?-1:1)},c):c}for(t in J.matches=function(t,e){return J(t,null,null,e)},J.matchesSelector=function(t,e){if(ct(t),f&&!E[e+" "]&&(!h||!h.test(e)))try{var n=d.call(t,e);if(n||v.disconnectedMatch||t.document&&11!==t.document.nodeType)return n}catch(t){E(e,!0)}return J(e,c,null,[t]).length>0},J.contains=function(t,e){return(t.ownerDocument||t)!=c&&ct(t),k.contains(t,e)},J.attr=function(t,n){(t.ownerDocument||t)!=c&&ct(t);var r=e.attrHandle[n.toLowerCase()],o=r&&p.call(e.attrHandle,n.toLowerCase())?r(t,n,!f):void 0;return void 0!==o?o:t.getAttribute(n)},J.error=function(t){throw new Error("Syntax error, unrecognized expression: "+t)},k.uniqueSort=function(t){var e,n=[],r=0,i=0;if(a=!v.sortStable,o=!v.sortStable&&s.call(t,0),T.call(t,C),a){for(;e=t[i++];)e===t[i]&&(r=n.push(i));for(;r--;)P.call(t,n[r],1)}return o=null,t},k.fn.uniqueSort=function(){return this.pushStack(k.uniqueSort(s.apply(this)))},(e=k.expr={cacheLength:50,createPseudo:et,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(t){return t[1]=t[1].replace(W,q),t[3]=(t[3]||t[4]||t[5]||"").replace(W,q),"~="===t[2]&&(t[3]=" "+t[3]+" "),t.slice(0,4)},CHILD:function(t){return t[1]=t[1].toLowerCase(),"nth"===t[1].slice(0,3)?(t[3]||J.error(t[0]),t[4]=+(t[4]?t[5]+(t[6]||1):2*("even"===t[3]||"odd"===t[3])),t[5]=+(t[7]+t[8]||"odd"===t[3])):t[3]&&J.error(t[0]),t},PSEUDO:function(t){var e,n=!t[6]&&t[2];return V.CHILD.test(t[0])?null:(t[3]?t[2]=t[4]||t[5]||"":n&&H.test(n)&&(e=lt(n,!0))&&(e=n.indexOf(")",n.length-e)-n.length)&&(t[0]=t[0].slice(0,e),t[2]=n.slice(0,e)),t.slice(0,3))}},filter:{TAG:function(t){var e=t.replace(W,q).toLowerCase();return"*"===t?function(){return!0}:function(t){return L(t,e)}},CLASS:function(t){var e=w[t+" "];return e||(e=new RegExp("(^|"+O+")"+t+"("+O+"|$)"))&&w(t,(function(t){return e.test("string"==typeof t.className&&t.className||void 0!==t.getAttribute&&t.getAttribute("class")||"")}))},ATTR:function(t,e,n){return function(r){var o=J.attr(r,t);return null==o?"!="===e:!e||(o+="","="===e?o===n:"!="===e?o!==n:"^="===e?n&&0===o.indexOf(n):"*="===e?n&&o.indexOf(n)>-1:"$="===e?n&&o.slice(-n.length)===n:"~="===e?(" "+o.replace(F," ")+" ").indexOf(n)>-1:"|="===e&&(o===n||o.slice(0,n.length+1)===n+"-"))}},CHILD:function(t,e,n,r,o){var i="nth"!==t.slice(0,3),a="last"!==t.slice(-4),s="of-type"===e;return 1===r&&0===o?function(t){return!!t.parentNode}:function(e,n,c){var u,l,f,h,p,d=i!==a?"nextSibling":"previousSibling",y=e.parentNode,v=s&&e.nodeName.toLowerCase(),b=!c&&!s,w=!1;if(y){if(i){for(;d;){for(f=e;f=f[d];)if(s?L(f,v):1===f.nodeType)return!1;p=d="only"===t&&!p&&"nextSibling"}return!0}if(p=[a?y.firstChild:y.lastChild],a&&b){for(w=(h=(u=(l=y[g]||(y[g]={}))[t]||[])[0]===m&&u[1])&&u[2],f=h&&y.childNodes[h];f=++h&&f&&f[d]||(w=h=0)||p.pop();)if(1===f.nodeType&&++w&&f===e){l[t]=[m,h,w];break}}else if(b&&(w=h=(u=(l=e[g]||(e[g]={}))[t]||[])[0]===m&&u[1]),!1===w)for(;(f=++h&&f&&f[d]||(w=h=0)||p.pop())&&(!(s?L(f,v):1===f.nodeType)||!++w||(b&&((l=f[g]||(f[g]={}))[t]=[m,w]),f!==e)););return(w-=o)===r||w%r==0&&w/r>=0}}},PSEUDO:function(t,n){var r,o=e.pseudos[t]||e.setFilters[t.toLowerCase()]||J.error("unsupported pseudo: "+t);return o[g]?o(n):o.length>1?(r=[t,t,"",n],e.setFilters.hasOwnProperty(t.toLowerCase())?et((function(t,e){for(var r,i=o(t,n),a=i.length;a--;)t[r=l.call(t,i[a])]=!(e[r]=i[a])})):function(t){return o(t,0,r)}):o}},pseudos:{not:et((function(t){var e=[],n=[],r=gt(t.replace(R,"$1"));return r[g]?et((function(t,e,n,o){for(var i,a=r(t,null,o,[]),s=t.length;s--;)(i=a[s])&&(t[s]=!(e[s]=i))})):function(t,o,i){return e[0]=t,r(e,null,i,n),e[0]=null,!n.pop()}})),has:et((function(t){return function(e){return J(t,e).length>0}})),contains:et((function(t){return t=t.replace(W,q),function(e){return(e.textContent||k.text(e)).indexOf(t)>-1}})),lang:et((function(t){return $.test(t||"")||J.error("unsupported lang: "+t),t=t.replace(W,q).toLowerCase(),function(e){var n;do{if(n=f?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(n=n.toLowerCase())===t||0===n.indexOf(t+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}})),target:function(t){var e=r.location&&r.location.hash;return e&&e.slice(1)===t.id},root:function(t){return t===u},focus:function(t){return t===function(){try{return c.activeElement}catch(t){}}()&&c.hasFocus()&&!!(t.type||t.href||~t.tabIndex)},enabled:it(!1),disabled:it(!0),checked:function(t){return L(t,"input")&&!!t.checked||L(t,"option")&&!!t.selected},selected:function(t){return t.parentNode&&t.parentNode.selectedIndex,!0===t.selected},empty:function(t){for(t=t.firstChild;t;t=t.nextSibling)if(t.nodeType<6)return!1;return!0},parent:function(t){return!e.pseudos.empty(t)},header:function(t){return z.test(t.nodeName)},input:function(t){return Z.test(t.nodeName)},button:function(t){return L(t,"input")&&"button"===t.type||L(t,"button")},text:function(t){var e;return L(t,"input")&&"text"===t.type&&(null==(e=t.getAttribute("type"))||"text"===e.toLowerCase())},first:at((function(){return[0]})),last:at((function(t,e){return[e-1]})),eq:at((function(t,e,n){return[n<0?n+e:n]})),even:at((function(t,e){for(var n=0;ne?e:n;--r>=0;)t.push(r);return t})),gt:at((function(t,e,n){for(var r=n<0?n+e:n;++r1?function(e,n,r){for(var o=t.length;o--;)if(!t[o](e,n,r))return!1;return!0}:t[0]}function dt(t,e,n,r,o){for(var i,a=[],s=0,c=t.length,u=null!=e;s-1&&(i[u]=!(a[u]=h))}}else p=dt(p===a?p.splice(g,p.length):p),o?o(null,a,p,c):y.apply(a,p)}))}function vt(t){for(var r,o,i,a=t.length,s=e.relative[t[0].type],c=s||e.relative[" "],u=s?1:0,f=ht((function(t){return t===r}),c,!0),h=ht((function(t){return l.call(r,t)>-1}),c,!0),p=[function(t,e,o){var i=!s&&(o||e!=n)||((r=e).nodeType?f(t,e,o):h(t,e,o));return r=null,i}];u1&&pt(p),u>1&&ft(t.slice(0,u-1).concat({value:" "===t[u-2].type?"*":""})).replace(R,"$1"),o,u0,i=t.length>0,a=function(a,s,u,l,h){var p,d,v,g=0,b="0",w=a&&[],A=[],x=n,E=a||i&&e.find.TAG("*",h),C=m+=null==x?1:Math.random()||.1,_=E.length;for(h&&(n=s==c||s||h);b!==_&&null!=(p=E[b]);b++){if(i&&p){for(d=0,s||p.ownerDocument==c||(ct(p),u=!f);v=t[d++];)if(v(p,s||c,u)){y.call(l,p);break}h&&(m=C)}o&&((p=!v&&p)&&g--,a&&w.push(p))}if(g+=b,o&&b!==g){for(d=0;v=r[d++];)v(w,A,s,u);if(a){if(g>0)for(;b--;)w[b]||A[b]||(A[b]=S.call(l));A=dt(A)}y.apply(l,A),h&&!a&&A.length>0&&g+r.length>1&&k.uniqueSort(l)}return h&&(m=C,n=x),w};return o?et(a):a}(a,i))).selector=t}return s}function mt(t,n,r,o){var i,a,s,c,u,l="function"==typeof t&&t,h=!o&<(t=l.selector||t);if(r=r||[],1===h.length){if((a=h[0]=h[0].slice(0)).length>2&&"ID"===(s=a[0]).type&&9===n.nodeType&&f&&e.relative[a[1].type]){if(!(n=(e.find.ID(s.matches[0].replace(W,q),n)||[])[0]))return r;l&&(n=n.parentNode),t=t.slice(a.shift().value.length)}for(i=V.needsContext.test(t)?0:a.length;i--&&(s=a[i],!e.relative[c=s.type]);)if((u=e.find[c])&&(o=u(s.matches[0].replace(W,q),Y.test(a[0].type)&&st(n.parentNode)||n))){if(a.splice(i,1),!(t=o.length&&ft(a)))return y.apply(r,o),r;break}}return(l||gt(t,h))(o,n,!f,r,!n||Y.test(t)&&st(n.parentNode)||n),r}ut.prototype=e.filters=e.pseudos,e.setFilters=new ut,v.sortStable=g.split("").sort(C).join("")===g,ct(),v.sortDetached=nt((function(t){return 1&t.compareDocumentPosition(c.createElement("fieldset"))})),k.find=J,k.expr[":"]=k.expr.pseudos,k.unique=k.uniqueSort,J.compile=gt,J.select=mt,J.setDocument=ct,J.escape=k.escapeSelector,J.getText=k.text,J.isXML=k.isXMLDoc,J.selectors=k.expr,J.support=k.support,J.uniqueSort=k.uniqueSort}();var N=function(t,e,n){for(var r=[],o=void 0!==n;(t=t[e])&&9!==t.nodeType;)if(1===t.nodeType){if(o&&k(t).is(n))break;r.push(t)}return r},F=function(t,e){for(var n=[];t;t=t.nextSibling)1===t.nodeType&&t!==e&&n.push(t);return n},M=k.expr.match.needsContext,U=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function G(t,e,n){return g(e)?k.grep(t,(function(t,r){return!!e.call(t,r,t)!==n})):e.nodeType?k.grep(t,(function(t){return t===e!==n})):"string"!=typeof e?k.grep(t,(function(t){return l.call(e,t)>-1!==n})):k.filter(e,t,n)}k.filter=function(t,e,n){var r=e[0];return n&&(t=":not("+t+")"),1===e.length&&1===r.nodeType?k.find.matchesSelector(r,t)?[r]:[]:k.find.matches(t,k.grep(e,(function(t){return 1===t.nodeType})))},k.fn.extend({find:function(t){var e,n,r=this.length,o=this;if("string"!=typeof t)return this.pushStack(k(t).filter((function(){for(e=0;e1?k.uniqueSort(n):n},filter:function(t){return this.pushStack(G(this,t||[],!1))},not:function(t){return this.pushStack(G(this,t||[],!0))},is:function(t){return!!G(this,"string"==typeof t&&M.test(t)?k(t):t||[],!1).length}});var H,$=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(k.fn.init=function(t,e,n){var r,o;if(!t)return this;if(n=n||H,"string"==typeof t){if(!(r="<"===t[0]&&">"===t[t.length-1]&&t.length>=3?[null,t,null]:$.exec(t))||!r[1]&&e)return!e||e.jquery?(e||n).find(t):this.constructor(e).find(t);if(r[1]){if(e=e instanceof k?e[0]:e,k.merge(this,k.parseHTML(r[1],e&&e.nodeType?e.ownerDocument||e:b,!0)),U.test(r[1])&&k.isPlainObject(e))for(r in e)g(this[r])?this[r](e[r]):this.attr(r,e[r]);return this}return(o=b.getElementById(r[2]))&&(this[0]=o,this.length=1),this}return t.nodeType?(this[0]=t,this.length=1,this):g(t)?void 0!==n.ready?n.ready(t):t(k):k.makeArray(t,this)}).prototype=k.fn,H=k(b);var V=/^(?:parents|prev(?:Until|All))/,Z={children:!0,contents:!0,next:!0,prev:!0};function z(t,e){for(;(t=t[e])&&1!==t.nodeType;);return t}k.fn.extend({has:function(t){var e=k(t,this),n=e.length;return this.filter((function(){for(var t=0;t-1:1===n.nodeType&&k.find.matchesSelector(n,t))){i.push(n);break}return this.pushStack(i.length>1?k.uniqueSort(i):i)},index:function(t){return t?"string"==typeof t?l.call(k(t),this[0]):l.call(this,t.jquery?t[0]:t):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(t,e){return this.pushStack(k.uniqueSort(k.merge(this.get(),k(t,e))))},addBack:function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}}),k.each({parent:function(t){var e=t.parentNode;return e&&11!==e.nodeType?e:null},parents:function(t){return N(t,"parentNode")},parentsUntil:function(t,e,n){return N(t,"parentNode",n)},next:function(t){return z(t,"nextSibling")},prev:function(t){return z(t,"previousSibling")},nextAll:function(t){return N(t,"nextSibling")},prevAll:function(t){return N(t,"previousSibling")},nextUntil:function(t,e,n){return N(t,"nextSibling",n)},prevUntil:function(t,e,n){return N(t,"previousSibling",n)},siblings:function(t){return F((t.parentNode||{}).firstChild,t)},children:function(t){return F(t.firstChild)},contents:function(t){return null!=t.contentDocument&&a(t.contentDocument)?t.contentDocument:(L(t,"template")&&(t=t.content||t),k.merge([],t.childNodes))}},(function(t,e){k.fn[t]=function(n,r){var o=k.map(this,e,n);return"Until"!==t.slice(-5)&&(r=n),r&&"string"==typeof r&&(o=k.filter(r,o)),this.length>1&&(Z[t]||k.uniqueSort(o),V.test(t)&&o.reverse()),this.pushStack(o)}}));var K=/[^\x20\t\r\n\f]+/g;function Y(t){return t}function W(t){throw t}function q(t,e,n,r){var o;try{t&&g(o=t.promise)?o.call(t).done(e).fail(n):t&&g(o=t.then)?o.call(t,e,n):e.apply(void 0,[t].slice(r))}catch(t){n.apply(void 0,[t])}}k.Callbacks=function(t){t="string"==typeof t?function(t){var e={};return k.each(t.match(K)||[],(function(t,n){e[n]=!0})),e}(t):k.extend({},t);var e,n,r,o,i=[],a=[],s=-1,c=function(){for(o=o||t.once,r=e=!0;a.length;s=-1)for(n=a.shift();++s-1;)i.splice(n,1),n<=s&&s--})),this},has:function(t){return t?k.inArray(t,i)>-1:i.length>0},empty:function(){return i&&(i=[]),this},disable:function(){return o=a=[],i=n="",this},disabled:function(){return!i},lock:function(){return o=a=[],n||e||(i=n=""),this},locked:function(){return!!o},fireWith:function(t,n){return o||(n=[t,(n=n||[]).slice?n.slice():n],a.push(n),e||c()),this},fire:function(){return u.fireWith(this,arguments),this},fired:function(){return!!r}};return u},k.extend({Deferred:function(t){var e=[["notify","progress",k.Callbacks("memory"),k.Callbacks("memory"),2],["resolve","done",k.Callbacks("once memory"),k.Callbacks("once memory"),0,"resolved"],["reject","fail",k.Callbacks("once memory"),k.Callbacks("once memory"),1,"rejected"]],n="pending",o={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},catch:function(t){return o.then(null,t)},pipe:function(){var t=arguments;return k.Deferred((function(n){k.each(e,(function(e,r){var o=g(t[r[4]])&&t[r[4]];i[r[1]]((function(){var t=o&&o.apply(this,arguments);t&&g(t.promise)?t.promise().progress(n.notify).done(n.resolve).fail(n.reject):n[r[0]+"With"](this,o?[t]:arguments)}))})),t=null})).promise()},then:function(t,n,o){var i=0;function a(t,e,n,o){return function(){var s=this,c=arguments,u=function(){var r,u;if(!(t=i&&(n!==W&&(s=void 0,c=[r]),e.rejectWith(s,c))}};t?l():(k.Deferred.getErrorHook?l.error=k.Deferred.getErrorHook():k.Deferred.getStackHook&&(l.error=k.Deferred.getStackHook()),r.setTimeout(l))}}return k.Deferred((function(r){e[0][3].add(a(0,r,g(o)?o:Y,r.notifyWith)),e[1][3].add(a(0,r,g(t)?t:Y)),e[2][3].add(a(0,r,g(n)?n:W))})).promise()},promise:function(t){return null!=t?k.extend(t,o):o}},i={};return k.each(e,(function(t,r){var a=r[2],s=r[5];o[r[1]]=a.add,s&&a.add((function(){n=s}),e[3-t][2].disable,e[3-t][3].disable,e[0][2].lock,e[0][3].lock),a.add(r[3].fire),i[r[0]]=function(){return i[r[0]+"With"](this===i?void 0:this,arguments),this},i[r[0]+"With"]=a.fireWith})),o.promise(i),t&&t.call(i,i),i},when:function(t){var e=arguments.length,n=e,r=Array(n),o=s.call(arguments),i=k.Deferred(),a=function(t){return function(n){r[t]=this,o[t]=arguments.length>1?s.call(arguments):n,--e||i.resolveWith(r,o)}};if(e<=1&&(q(t,i.done(a(n)).resolve,i.reject,!e),"pending"===i.state()||g(o[n]&&o[n].then)))return i.then();for(;n--;)q(o[n],a(n),i.reject);return i.promise()}});var X=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;k.Deferred.exceptionHook=function(t,e){r.console&&r.console.warn&&t&&X.test(t.name)&&r.console.warn("jQuery.Deferred exception: "+t.message,t.stack,e)},k.readyException=function(t){r.setTimeout((function(){throw t}))};var Q=k.Deferred();function J(){b.removeEventListener("DOMContentLoaded",J),r.removeEventListener("load",J),k.ready()}k.fn.ready=function(t){return Q.then(t).catch((function(t){k.readyException(t)})),this},k.extend({isReady:!1,readyWait:1,ready:function(t){(!0===t?--k.readyWait:k.isReady)||(k.isReady=!0,!0!==t&&--k.readyWait>0||Q.resolveWith(b,[k]))}}),k.ready.then=Q.then,"complete"===b.readyState||"loading"!==b.readyState&&!b.documentElement.doScroll?r.setTimeout(k.ready):(b.addEventListener("DOMContentLoaded",J),r.addEventListener("load",J));var tt=function(t,e,n,r,o,i,a){var s=0,c=t.length,u=null==n;if("object"===x(n))for(s in o=!0,n)tt(t,e,s,n[s],!0,i,a);else if(void 0!==r&&(o=!0,g(r)||(a=!0),u&&(a?(e.call(t,r),e=null):(u=e,e=function(t,e,n){return u.call(k(t),n)})),e))for(;s1,null,!0)},removeData:function(t){return this.each((function(){ct.remove(this,t)}))}}),k.extend({queue:function(t,e,n){var r;if(t)return e=(e||"fx")+"queue",r=st.get(t,e),n&&(!r||Array.isArray(n)?r=st.access(t,e,k.makeArray(n)):r.push(n)),r||[]},dequeue:function(t,e){e=e||"fx";var n=k.queue(t,e),r=n.length,o=n.shift(),i=k._queueHooks(t,e);"inprogress"===o&&(o=n.shift(),r--),o&&("fx"===e&&n.unshift("inprogress"),delete i.stop,o.call(t,(function(){k.dequeue(t,e)}),i)),!r&&i&&i.empty.fire()},_queueHooks:function(t,e){var n=e+"queueHooks";return st.get(t,n)||st.access(t,n,{empty:k.Callbacks("once memory").add((function(){st.remove(t,[e+"queue",n])}))})}}),k.fn.extend({queue:function(t,e){var n=2;return"string"!=typeof t&&(e=t,t="fx",n--),arguments.length\x20\t\r\n\f]*)/i,Lt=/^$|^module$|\/(?:java|ecma)script/i;Et=b.createDocumentFragment().appendChild(b.createElement("div")),(Ct=b.createElement("input")).setAttribute("type","radio"),Ct.setAttribute("checked","checked"),Ct.setAttribute("name","t"),Et.appendChild(Ct),v.checkClone=Et.cloneNode(!0).cloneNode(!0).lastChild.checked,Et.innerHTML="",v.noCloneChecked=!!Et.cloneNode(!0).lastChild.defaultValue,Et.innerHTML="",v.option=!!Et.lastChild;var St={thead:[1,""],col:[2,""],tr:[2,""],td:[3,""],_default:[0,"",""]};function Tt(t,e){var n;return n=void 0!==t.getElementsByTagName?t.getElementsByTagName(e||"*"):void 0!==t.querySelectorAll?t.querySelectorAll(e||"*"):[],void 0===e||e&&L(t,e)?k.merge([t],n):n}function Pt(t,e){for(var n=0,r=t.length;n",""]);var Ot=/<|?\w+;/;function Rt(t,e,n,r,o){for(var i,a,s,c,u,l,f=e.createDocumentFragment(),h=[],p=0,d=t.length;p-1)o&&o.push(i);else if(u=vt(i),a=Tt(f.appendChild(i),"script"),u&&Pt(a),n)for(l=0;i=a[l++];)Lt.test(i.type||"")&&n.push(i);return f}var It=/^([^.]*)(?:\.(.+)|)/;function jt(){return!0}function Dt(){return!1}function Bt(t,e,n,r,o,i){var a,s;if("object"==typeof e){for(s in"string"!=typeof n&&(r=r||n,n=void 0),e)Bt(t,s,n,r,e[s],i);return t}if(null==r&&null==o?(o=n,r=n=void 0):null==o&&("string"==typeof n?(o=r,r=void 0):(o=r,r=n,n=void 0)),!1===o)o=Dt;else if(!o)return t;return 1===i&&(a=o,(o=function(t){return k().off(t),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),t.each((function(){k.event.add(this,e,o,r,n)}))}function Nt(t,e,n){n?(st.set(t,e,!1),k.event.add(t,e,{namespace:!1,handler:function(t){var n,r=st.get(this,e);if(1&t.isTrigger&&this[e]){if(r)(k.event.special[e]||{}).delegateType&&t.stopPropagation();else if(r=s.call(arguments),st.set(this,e,r),this[e](),n=st.get(this,e),st.set(this,e,!1),r!==n)return t.stopImmediatePropagation(),t.preventDefault(),n}else r&&(st.set(this,e,k.event.trigger(r[0],r.slice(1),this)),t.stopPropagation(),t.isImmediatePropagationStopped=jt)}})):void 0===st.get(t,e)&&k.event.add(t,e,jt)}k.event={global:{},add:function(t,e,n,r,o){var i,a,s,c,u,l,f,h,p,d,y,v=st.get(t);if(it(t))for(n.handler&&(n=(i=n).handler,o=i.selector),o&&k.find.matchesSelector(yt,o),n.guid||(n.guid=k.guid++),(c=v.events)||(c=v.events=Object.create(null)),(a=v.handle)||(a=v.handle=function(e){return void 0!==k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),u=(e=(e||"").match(K)||[""]).length;u--;)p=y=(s=It.exec(e[u])||[])[1],d=(s[2]||"").split(".").sort(),p&&(f=k.event.special[p]||{},p=(o?f.delegateType:f.bindType)||p,f=k.event.special[p]||{},l=k.extend({type:p,origType:y,data:r,handler:n,guid:n.guid,selector:o,needsContext:o&&k.expr.match.needsContext.test(o),namespace:d.join(".")},i),(h=c[p])||((h=c[p]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,d,a)||t.addEventListener&&t.addEventListener(p,a)),f.add&&(f.add.call(t,l),l.handler.guid||(l.handler.guid=n.guid)),o?h.splice(h.delegateCount++,0,l):h.push(l),k.event.global[p]=!0)},remove:function(t,e,n,r,o){var i,a,s,c,u,l,f,h,p,d,y,v=st.hasData(t)&&st.get(t);if(v&&(c=v.events)){for(u=(e=(e||"").match(K)||[""]).length;u--;)if(p=y=(s=It.exec(e[u])||[])[1],d=(s[2]||"").split(".").sort(),p){for(f=k.event.special[p]||{},h=c[p=(r?f.delegateType:f.bindType)||p]||[],s=s[2]&&new RegExp("(^|\\.)"+d.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=i=h.length;i--;)l=h[i],!o&&y!==l.origType||n&&n.guid!==l.guid||s&&!s.test(l.namespace)||r&&r!==l.selector&&("**"!==r||!l.selector)||(h.splice(i,1),l.selector&&h.delegateCount--,f.remove&&f.remove.call(t,l));a&&!h.length&&(f.teardown&&!1!==f.teardown.call(t,d,v.handle)||k.removeEvent(t,p,v.handle),delete c[p])}else for(p in c)k.event.remove(t,p+e[u],n,r,!0);k.isEmptyObject(c)&&st.remove(t,"handle events")}},dispatch:function(t){var e,n,r,o,i,a,s=new Array(arguments.length),c=k.event.fix(t),u=(st.get(this,"events")||Object.create(null))[c.type]||[],l=k.event.special[c.type]||{};for(s[0]=c,e=1;e=1))for(;u!==this;u=u.parentNode||this)if(1===u.nodeType&&("click"!==t.type||!0!==u.disabled)){for(i=[],a={},n=0;n-1:k.find(o,this,null,[u]).length),a[o]&&i.push(r);i.length&&s.push({elem:u,handlers:i})}return u=this,c\s*$/g;function Gt(t,e){return L(t,"table")&&L(11!==e.nodeType?e:e.firstChild,"tr")&&k(t).children("tbody")[0]||t}function Ht(t){return t.type=(null!==t.getAttribute("type"))+"/"+t.type,t}function $t(t){return"true/"===(t.type||"").slice(0,5)?t.type=t.type.slice(5):t.removeAttribute("type"),t}function Vt(t,e){var n,r,o,i,a,s;if(1===e.nodeType){if(st.hasData(t)&&(s=st.get(t).events))for(o in st.remove(e,"handle events"),s)for(n=0,r=s[o].length;n1&&"string"==typeof d&&!v.checkClone&&Mt.test(d))return t.each((function(o){var i=t.eq(o);y&&(e[0]=d.call(this,o,i.html())),zt(i,e,n,r)}));if(h&&(i=(o=Rt(e,t[0].ownerDocument,!1,t,r)).firstChild,1===o.childNodes.length&&(o=i),i||r)){for(s=(a=k.map(Tt(o,"script"),Ht)).length;f0&&Pt(a,!c&&Tt(t,"script")),s},cleanData:function(t){for(var e,n,r,o=k.event.special,i=0;void 0!==(n=t[i]);i++)if(it(n)){if(e=n[st.expando]){if(e.events)for(r in e.events)o[r]?k.event.remove(n,r):k.removeEvent(n,r,e.handle);n[st.expando]=void 0}n[ct.expando]&&(n[ct.expando]=void 0)}}}),k.fn.extend({detach:function(t){return Kt(this,t,!0)},remove:function(t){return Kt(this,t)},text:function(t){return tt(this,(function(t){return void 0===t?k.text(this):this.empty().each((function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=t)}))}),null,t,arguments.length)},append:function(){return zt(this,arguments,(function(t){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Gt(this,t).appendChild(t)}))},prepend:function(){return zt(this,arguments,(function(t){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var e=Gt(this,t);e.insertBefore(t,e.firstChild)}}))},before:function(){return zt(this,arguments,(function(t){this.parentNode&&this.parentNode.insertBefore(t,this)}))},after:function(){return zt(this,arguments,(function(t){this.parentNode&&this.parentNode.insertBefore(t,this.nextSibling)}))},empty:function(){for(var t,e=0;null!=(t=this[e]);e++)1===t.nodeType&&(k.cleanData(Tt(t,!1)),t.textContent="");return this},clone:function(t,e){return t=null!=t&&t,e=null==e?t:e,this.map((function(){return k.clone(this,t,e)}))},html:function(t){return tt(this,(function(t){var e=this[0]||{},n=0,r=this.length;if(void 0===t&&1===e.nodeType)return e.innerHTML;if("string"==typeof t&&!Ft.test(t)&&!St[(_t.exec(t)||["",""])[1].toLowerCase()]){t=k.htmlPrefilter(t);try{for(;n=0&&(c+=Math.max(0,Math.ceil(t["offset"+e[0].toUpperCase()+e.slice(1)]-i-c-s-.5))||0),c+u}function le(t,e,n){var r=qt(t),o=(!v.boxSizingReliable()||n)&&"border-box"===k.css(t,"boxSizing",!1,r),i=o,a=Jt(t,e,r),s="offset"+e[0].toUpperCase()+e.slice(1);if(Yt.test(a)){if(!n)return a;a="auto"}return(!v.boxSizingReliable()&&o||!v.reliableTrDimensions()&&L(t,"tr")||"auto"===a||!parseFloat(a)&&"inline"===k.css(t,"display",!1,r))&&t.getClientRects().length&&(o="border-box"===k.css(t,"boxSizing",!1,r),(i=s in t)&&(a=t[s])),(a=parseFloat(a)||0)+ue(t,e,n||(o?"border":"content"),i,r,a)+"px"}function fe(t,e,n,r,o){return new fe.prototype.init(t,e,n,r,o)}k.extend({cssHooks:{opacity:{get:function(t,e){if(e){var n=Jt(t,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,aspectRatio:!0,borderImageSlice:!0,columnCount:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,scale:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeMiterlimit:!0,strokeOpacity:!0},cssProps:{},style:function(t,e,n,r){if(t&&3!==t.nodeType&&8!==t.nodeType&&t.style){var o,i,a,s=ot(e),c=Wt.test(e),u=t.style;if(c||(e=oe(s)),a=k.cssHooks[e]||k.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(o=a.get(t,!1,r))?o:u[e];"string"==(i=typeof n)&&(o=pt.exec(n))&&o[1]&&(n=bt(t,e,o),i="number"),null!=n&&n==n&&("number"!==i||c||(n+=o&&o[3]||(k.cssNumber[s]?"":"px")),v.clearCloneStyle||""!==n||0!==e.indexOf("background")||(u[e]="inherit"),a&&"set"in a&&void 0===(n=a.set(t,n,r))||(c?u.setProperty(e,n):u[e]=n))}},css:function(t,e,n,r){var o,i,a,s=ot(e);return Wt.test(e)||(e=oe(s)),(a=k.cssHooks[e]||k.cssHooks[s])&&"get"in a&&(o=a.get(t,!0,n)),void 0===o&&(o=Jt(t,e,r)),"normal"===o&&e in se&&(o=se[e]),""===n||n?(i=parseFloat(o),!0===n||isFinite(i)?i||0:o):o}}),k.each(["height","width"],(function(t,e){k.cssHooks[e]={get:function(t,n,r){if(n)return!ie.test(k.css(t,"display"))||t.getClientRects().length&&t.getBoundingClientRect().width?le(t,e,r):Xt(t,ae,(function(){return le(t,e,r)}))},set:function(t,n,r){var o,i=qt(t),a=!v.scrollboxSize()&&"absolute"===i.position,s=(a||r)&&"border-box"===k.css(t,"boxSizing",!1,i),c=r?ue(t,e,r,s,i):0;return s&&a&&(c-=Math.ceil(t["offset"+e[0].toUpperCase()+e.slice(1)]-parseFloat(i[e])-ue(t,e,"border",!1,i)-.5)),c&&(o=pt.exec(n))&&"px"!==(o[3]||"px")&&(t.style[e]=n,n=k.css(t,e)),ce(0,n,c)}}})),k.cssHooks.marginLeft=te(v.reliableMarginLeft,(function(t,e){if(e)return(parseFloat(Jt(t,"marginLeft"))||t.getBoundingClientRect().left-Xt(t,{marginLeft:0},(function(){return t.getBoundingClientRect().left})))+"px"})),k.each({margin:"",padding:"",border:"Width"},(function(t,e){k.cssHooks[t+e]={expand:function(n){for(var r=0,o={},i="string"==typeof n?n.split(" "):[n];r<4;r++)o[t+dt[r]+e]=i[r]||i[r-2]||i[0];return o}},"margin"!==t&&(k.cssHooks[t+e].set=ce)})),k.fn.extend({css:function(t,e){return tt(this,(function(t,e,n){var r,o,i={},a=0;if(Array.isArray(e)){for(r=qt(t),o=e.length;a1)}}),k.Tween=fe,fe.prototype={constructor:fe,init:function(t,e,n,r,o,i){this.elem=t,this.prop=n,this.easing=o||k.easing._default,this.options=e,this.start=this.now=this.cur(),this.end=r,this.unit=i||(k.cssNumber[n]?"":"px")},cur:function(){var t=fe.propHooks[this.prop];return t&&t.get?t.get(this):fe.propHooks._default.get(this)},run:function(t){var e,n=fe.propHooks[this.prop];return this.options.duration?this.pos=e=k.easing[this.easing](t,this.options.duration*t,0,1,this.options.duration):this.pos=e=t,this.now=(this.end-this.start)*e+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):fe.propHooks._default.set(this),this}},fe.prototype.init.prototype=fe.prototype,fe.propHooks={_default:{get:function(t){var e;return 1!==t.elem.nodeType||null!=t.elem[t.prop]&&null==t.elem.style[t.prop]?t.elem[t.prop]:(e=k.css(t.elem,t.prop,""))&&"auto"!==e?e:0},set:function(t){k.fx.step[t.prop]?k.fx.step[t.prop](t):1!==t.elem.nodeType||!k.cssHooks[t.prop]&&null==t.elem.style[oe(t.prop)]?t.elem[t.prop]=t.now:k.style(t.elem,t.prop,t.now+t.unit)}}},fe.propHooks.scrollTop=fe.propHooks.scrollLeft={set:function(t){t.elem.nodeType&&t.elem.parentNode&&(t.elem[t.prop]=t.now)}},k.easing={linear:function(t){return t},swing:function(t){return.5-Math.cos(t*Math.PI)/2},_default:"swing"},k.fx=fe.prototype.init,k.fx.step={};var he,pe,de=/^(?:toggle|show|hide)$/,ye=/queueHooks$/;function ve(){pe&&(!1===b.hidden&&r.requestAnimationFrame?r.requestAnimationFrame(ve):r.setTimeout(ve,k.fx.interval),k.fx.tick())}function ge(){return r.setTimeout((function(){he=void 0})),he=Date.now()}function me(t,e){var n,r=0,o={height:t};for(e=e?1:0;r<4;r+=2-e)o["margin"+(n=dt[r])]=o["padding"+n]=t;return e&&(o.opacity=o.width=t),o}function be(t,e,n){for(var r,o=(we.tweeners[e]||[]).concat(we.tweeners["*"]),i=0,a=o.length;i1)},removeAttr:function(t){return this.each((function(){k.removeAttr(this,t)}))}}),k.extend({attr:function(t,e,n){var r,o,i=t.nodeType;if(3!==i&&8!==i&&2!==i)return void 0===t.getAttribute?k.prop(t,e,n):(1===i&&k.isXMLDoc(t)||(o=k.attrHooks[e.toLowerCase()]||(k.expr.match.bool.test(e)?Ae:void 0)),void 0!==n?null===n?void k.removeAttr(t,e):o&&"set"in o&&void 0!==(r=o.set(t,n,e))?r:(t.setAttribute(e,n+""),n):o&&"get"in o&&null!==(r=o.get(t,e))?r:null==(r=k.find.attr(t,e))?void 0:r)},attrHooks:{type:{set:function(t,e){if(!v.radioValue&&"radio"===e&&L(t,"input")){var n=t.value;return t.setAttribute("type",e),n&&(t.value=n),e}}}},removeAttr:function(t,e){var n,r=0,o=e&&e.match(K);if(o&&1===t.nodeType)for(;n=o[r++];)t.removeAttribute(n)}}),Ae={set:function(t,e,n){return!1===e?k.removeAttr(t,n):t.setAttribute(n,n),n}},k.each(k.expr.match.bool.source.match(/\w+/g),(function(t,e){var n=xe[e]||k.find.attr;xe[e]=function(t,e,r){var o,i,a=e.toLowerCase();return r||(i=xe[a],xe[a]=o,o=null!=n(t,e,r)?a:null,xe[a]=i),o}}));var Ee=/^(?:input|select|textarea|button)$/i,Ce=/^(?:a|area)$/i;function ke(t){return(t.match(K)||[]).join(" ")}function _e(t){return t.getAttribute&&t.getAttribute("class")||""}function Le(t){return Array.isArray(t)?t:"string"==typeof t&&t.match(K)||[]}k.fn.extend({prop:function(t,e){return tt(this,k.prop,t,e,arguments.length>1)},removeProp:function(t){return this.each((function(){delete this[k.propFix[t]||t]}))}}),k.extend({prop:function(t,e,n){var r,o,i=t.nodeType;if(3!==i&&8!==i&&2!==i)return 1===i&&k.isXMLDoc(t)||(e=k.propFix[e]||e,o=k.propHooks[e]),void 0!==n?o&&"set"in o&&void 0!==(r=o.set(t,n,e))?r:t[e]=n:o&&"get"in o&&null!==(r=o.get(t,e))?r:t[e]},propHooks:{tabIndex:{get:function(t){var e=k.find.attr(t,"tabindex");return e?parseInt(e,10):Ee.test(t.nodeName)||Ce.test(t.nodeName)&&t.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),v.optSelected||(k.propHooks.selected={get:function(t){var e=t.parentNode;return e&&e.parentNode&&e.parentNode.selectedIndex,null},set:function(t){var e=t.parentNode;e&&(e.selectedIndex,e.parentNode&&e.parentNode.selectedIndex)}}),k.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],(function(){k.propFix[this.toLowerCase()]=this})),k.fn.extend({addClass:function(t){var e,n,r,o,i,a;return g(t)?this.each((function(e){k(this).addClass(t.call(this,e,_e(this)))})):(e=Le(t)).length?this.each((function(){if(r=_e(this),n=1===this.nodeType&&" "+ke(r)+" "){for(i=0;i-1;)n=n.replace(" "+o+" "," ");a=ke(n),r!==a&&this.setAttribute("class",a)}})):this:this.attr("class","")},toggleClass:function(t,e){var n,r,o,i,a=typeof t,s="string"===a||Array.isArray(t);return g(t)?this.each((function(n){k(this).toggleClass(t.call(this,n,_e(this),e),e)})):"boolean"==typeof e&&s?e?this.addClass(t):this.removeClass(t):(n=Le(t),this.each((function(){if(s)for(i=k(this),o=0;o-1)return!0;return!1}});var Se=/\r/g;k.fn.extend({val:function(t){var e,n,r,o=this[0];return arguments.length?(r=g(t),this.each((function(n){var o;1===this.nodeType&&(null==(o=r?t.call(this,n,k(this).val()):t)?o="":"number"==typeof o?o+="":Array.isArray(o)&&(o=k.map(o,(function(t){return null==t?"":t+""}))),(e=k.valHooks[this.type]||k.valHooks[this.nodeName.toLowerCase()])&&"set"in e&&void 0!==e.set(this,o,"value")||(this.value=o))}))):o?(e=k.valHooks[o.type]||k.valHooks[o.nodeName.toLowerCase()])&&"get"in e&&void 0!==(n=e.get(o,"value"))?n:"string"==typeof(n=o.value)?n.replace(Se,""):null==n?"":n:void 0}}),k.extend({valHooks:{option:{get:function(t){var e=k.find.attr(t,"value");return null!=e?e:ke(k.text(t))}},select:{get:function(t){var e,n,r,o=t.options,i=t.selectedIndex,a="select-one"===t.type,s=a?null:[],c=a?i+1:o.length;for(r=i<0?c:a?i:0;r-1)&&(n=!0);return n||(t.selectedIndex=-1),i}}}}),k.each(["radio","checkbox"],(function(){k.valHooks[this]={set:function(t,e){if(Array.isArray(e))return t.checked=k.inArray(k(t).val(),e)>-1}},v.checkOn||(k.valHooks[this].get=function(t){return null===t.getAttribute("value")?"on":t.value})}));var Te=r.location,Pe={guid:Date.now()},Oe=/\?/;k.parseXML=function(t){var e,n;if(!t||"string"!=typeof t)return null;try{e=(new r.DOMParser).parseFromString(t,"text/xml")}catch(t){}return n=e&&e.getElementsByTagName("parsererror")[0],e&&!n||k.error("Invalid XML: "+(n?k.map(n.childNodes,(function(t){return t.textContent})).join("\n"):t)),e};var Re=/^(?:focusinfocus|focusoutblur)$/,Ie=function(t){t.stopPropagation()};k.extend(k.event,{trigger:function(t,e,n,o){var i,a,s,c,u,l,f,h,d=[n||b],y=p.call(t,"type")?t.type:t,v=p.call(t,"namespace")?t.namespace.split("."):[];if(a=h=s=n=n||b,3!==n.nodeType&&8!==n.nodeType&&!Re.test(y+k.event.triggered)&&(y.indexOf(".")>-1&&(v=y.split("."),y=v.shift(),v.sort()),u=y.indexOf(":")<0&&"on"+y,(t=t[k.expando]?t:new k.Event(y,"object"==typeof t&&t)).isTrigger=o?2:3,t.namespace=v.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+v.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=n),e=null==e?[t]:k.makeArray(e,[t]),f=k.event.special[y]||{},o||!f.trigger||!1!==f.trigger.apply(n,e))){if(!o&&!f.noBubble&&!m(n)){for(c=f.delegateType||y,Re.test(c+y)||(a=a.parentNode);a;a=a.parentNode)d.push(a),s=a;s===(n.ownerDocument||b)&&d.push(s.defaultView||s.parentWindow||r)}for(i=0;(a=d[i++])&&!t.isPropagationStopped();)h=a,t.type=i>1?c:f.bindType||y,(l=(st.get(a,"events")||Object.create(null))[t.type]&&st.get(a,"handle"))&&l.apply(a,e),(l=u&&a[u])&&l.apply&&it(a)&&(t.result=l.apply(a,e),!1===t.result&&t.preventDefault());return t.type=y,o||t.isDefaultPrevented()||f._default&&!1!==f._default.apply(d.pop(),e)||!it(n)||u&&g(n[y])&&!m(n)&&((s=n[u])&&(n[u]=null),k.event.triggered=y,t.isPropagationStopped()&&h.addEventListener(y,Ie),n[y](),t.isPropagationStopped()&&h.removeEventListener(y,Ie),k.event.triggered=void 0,s&&(n[u]=s)),t.result}},simulate:function(t,e,n){var r=k.extend(new k.Event,n,{type:t,isSimulated:!0});k.event.trigger(r,null,e)}}),k.fn.extend({trigger:function(t,e){return this.each((function(){k.event.trigger(t,e,this)}))},triggerHandler:function(t,e){var n=this[0];if(n)return k.event.trigger(t,e,n,!0)}});var je=/\[\]$/,De=/\r?\n/g,Be=/^(?:submit|button|image|reset|file)$/i,Ne=/^(?:input|select|textarea|keygen)/i;function Fe(t,e,n,r){var o;if(Array.isArray(e))k.each(e,(function(e,o){n||je.test(t)?r(t,o):Fe(t+"["+("object"==typeof o&&null!=o?e:"")+"]",o,n,r)}));else if(n||"object"!==x(e))r(t,e);else for(o in e)Fe(t+"["+o+"]",e[o],n,r)}k.param=function(t,e){var n,r=[],o=function(t,e){var n=g(e)?e():e;r[r.length]=encodeURIComponent(t)+"="+encodeURIComponent(null==n?"":n)};if(null==t)return"";if(Array.isArray(t)||t.jquery&&!k.isPlainObject(t))k.each(t,(function(){o(this.name,this.value)}));else for(n in t)Fe(n,t[n],e,o);return r.join("&")},k.fn.extend({serialize:function(){return k.param(this.serializeArray())},serializeArray:function(){return this.map((function(){var t=k.prop(this,"elements");return t?k.makeArray(t):this})).filter((function(){var t=this.type;return this.name&&!k(this).is(":disabled")&&Ne.test(this.nodeName)&&!Be.test(t)&&(this.checked||!kt.test(t))})).map((function(t,e){var n=k(this).val();return null==n?null:Array.isArray(n)?k.map(n,(function(t){return{name:e.name,value:t.replace(De,"\r\n")}})):{name:e.name,value:n.replace(De,"\r\n")}})).get()}});var Me=/%20/g,Ue=/#.*$/,Ge=/([?&])_=[^&]*/,He=/^(.*?):[ \t]*([^\r\n]*)$/gm,$e=/^(?:GET|HEAD)$/,Ve=/^\/\//,Ze={},ze={},Ke="*/".concat("*"),Ye=b.createElement("a");function We(t){return function(e,n){"string"!=typeof e&&(n=e,e="*");var r,o=0,i=e.toLowerCase().match(K)||[];if(g(n))for(;r=i[o++];)"+"===r[0]?(r=r.slice(1)||"*",(t[r]=t[r]||[]).unshift(n)):(t[r]=t[r]||[]).push(n)}}function qe(t,e,n,r){var o={},i=t===ze;function a(s){var c;return o[s]=!0,k.each(t[s]||[],(function(t,s){var u=s(e,n,r);return"string"!=typeof u||i||o[u]?i?!(c=u):void 0:(e.dataTypes.unshift(u),a(u),!1)})),c}return a(e.dataTypes[0])||!o["*"]&&a("*")}function Xe(t,e){var n,r,o=k.ajaxSettings.flatOptions||{};for(n in e)void 0!==e[n]&&((o[n]?t:r||(r={}))[n]=e[n]);return r&&k.extend(!0,t,r),t}Ye.href=Te.href,k.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Te.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(Te.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Ke,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":k.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(t,e){return e?Xe(Xe(t,k.ajaxSettings),e):Xe(k.ajaxSettings,t)},ajaxPrefilter:We(Ze),ajaxTransport:We(ze),ajax:function(t,e){"object"==typeof t&&(e=t,t=void 0),e=e||{};var n,o,i,a,s,c,u,l,f,h,p=k.ajaxSetup({},e),d=p.context||p,y=p.context&&(d.nodeType||d.jquery)?k(d):k.event,v=k.Deferred(),g=k.Callbacks("once memory"),m=p.statusCode||{},w={},A={},x="canceled",E={readyState:0,getResponseHeader:function(t){var e;if(u){if(!a)for(a={};e=He.exec(i);)a[e[1].toLowerCase()+" "]=(a[e[1].toLowerCase()+" "]||[]).concat(e[2]);e=a[t.toLowerCase()+" "]}return null==e?null:e.join(", ")},getAllResponseHeaders:function(){return u?i:null},setRequestHeader:function(t,e){return null==u&&(t=A[t.toLowerCase()]=A[t.toLowerCase()]||t,w[t]=e),this},overrideMimeType:function(t){return null==u&&(p.mimeType=t),this},statusCode:function(t){var e;if(t)if(u)E.always(t[E.status]);else for(e in t)m[e]=[m[e],t[e]];return this},abort:function(t){var e=t||x;return n&&n.abort(e),C(0,e),this}};if(v.promise(E),p.url=((t||p.url||Te.href)+"").replace(Ve,Te.protocol+"//"),p.type=e.method||e.type||p.method||p.type,p.dataTypes=(p.dataType||"*").toLowerCase().match(K)||[""],null==p.crossDomain){c=b.createElement("a");try{c.href=p.url,c.href=c.href,p.crossDomain=Ye.protocol+"//"+Ye.host!=c.protocol+"//"+c.host}catch(t){p.crossDomain=!0}}if(p.data&&p.processData&&"string"!=typeof p.data&&(p.data=k.param(p.data,p.traditional)),qe(Ze,p,e,E),u)return E;for(f in(l=k.event&&p.global)&&0==k.active++&&k.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!$e.test(p.type),o=p.url.replace(Ue,""),p.hasContent?p.data&&p.processData&&0===(p.contentType||"").indexOf("application/x-www-form-urlencoded")&&(p.data=p.data.replace(Me,"+")):(h=p.url.slice(o.length),p.data&&(p.processData||"string"==typeof p.data)&&(o+=(Oe.test(o)?"&":"?")+p.data,delete p.data),!1===p.cache&&(o=o.replace(Ge,"$1"),h=(Oe.test(o)?"&":"?")+"_="+Pe.guid+++h),p.url=o+h),p.ifModified&&(k.lastModified[o]&&E.setRequestHeader("If-Modified-Since",k.lastModified[o]),k.etag[o]&&E.setRequestHeader("If-None-Match",k.etag[o])),(p.data&&p.hasContent&&!1!==p.contentType||e.contentType)&&E.setRequestHeader("Content-Type",p.contentType),E.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+Ke+"; q=0.01":""):p.accepts["*"]),p.headers)E.setRequestHeader(f,p.headers[f]);if(p.beforeSend&&(!1===p.beforeSend.call(d,E,p)||u))return E.abort();if(x="abort",g.add(p.complete),E.done(p.success),E.fail(p.error),n=qe(ze,p,e,E)){if(E.readyState=1,l&&y.trigger("ajaxSend",[E,p]),u)return E;p.async&&p.timeout>0&&(s=r.setTimeout((function(){E.abort("timeout")}),p.timeout));try{u=!1,n.send(w,C)}catch(t){if(u)throw t;C(-1,t)}}else C(-1,"No Transport");function C(t,e,a,c){var f,h,b,w,A,x=e;u||(u=!0,s&&r.clearTimeout(s),n=void 0,i=c||"",E.readyState=t>0?4:0,f=t>=200&&t<300||304===t,a&&(w=function(t,e,n){for(var r,o,i,a,s=t.contents,c=t.dataTypes;"*"===c[0];)c.shift(),void 0===r&&(r=t.mimeType||e.getResponseHeader("Content-Type"));if(r)for(o in s)if(s[o]&&s[o].test(r)){c.unshift(o);break}if(c[0]in n)i=c[0];else{for(o in n){if(!c[0]||t.converters[o+" "+c[0]]){i=o;break}a||(a=o)}i=i||a}if(i)return i!==c[0]&&c.unshift(i),n[i]}(p,E,a)),!f&&k.inArray("script",p.dataTypes)>-1&&k.inArray("json",p.dataTypes)<0&&(p.converters["text script"]=function(){}),w=function(t,e,n,r){var o,i,a,s,c,u={},l=t.dataTypes.slice();if(l[1])for(a in t.converters)u[a.toLowerCase()]=t.converters[a];for(i=l.shift();i;)if(t.responseFields[i]&&(n[t.responseFields[i]]=e),!c&&r&&t.dataFilter&&(e=t.dataFilter(e,t.dataType)),c=i,i=l.shift())if("*"===i)i=c;else if("*"!==c&&c!==i){if(!(a=u[c+" "+i]||u["* "+i]))for(o in u)if((s=o.split(" "))[1]===i&&(a=u[c+" "+s[0]]||u["* "+s[0]])){!0===a?a=u[o]:!0!==u[o]&&(i=s[0],l.unshift(s[1]));break}if(!0!==a)if(a&&t.throws)e=a(e);else try{e=a(e)}catch(t){return{state:"parsererror",error:a?t:"No conversion from "+c+" to "+i}}}return{state:"success",data:e}}(p,w,E,f),f?(p.ifModified&&((A=E.getResponseHeader("Last-Modified"))&&(k.lastModified[o]=A),(A=E.getResponseHeader("etag"))&&(k.etag[o]=A)),204===t||"HEAD"===p.type?x="nocontent":304===t?x="notmodified":(x=w.state,h=w.data,f=!(b=w.error))):(b=x,!t&&x||(x="error",t<0&&(t=0))),E.status=t,E.statusText=(e||x)+"",f?v.resolveWith(d,[h,x,E]):v.rejectWith(d,[E,x,b]),E.statusCode(m),m=void 0,l&&y.trigger(f?"ajaxSuccess":"ajaxError",[E,p,f?h:b]),g.fireWith(d,[E,x]),l&&(y.trigger("ajaxComplete",[E,p]),--k.active||k.event.trigger("ajaxStop")))}return E},getJSON:function(t,e,n){return k.get(t,e,n,"json")},getScript:function(t,e){return k.get(t,void 0,e,"script")}}),k.each(["get","post"],(function(t,e){k[e]=function(t,n,r,o){return g(n)&&(o=o||r,r=n,n=void 0),k.ajax(k.extend({url:t,type:e,dataType:o,data:n,success:r},k.isPlainObject(t)&&t))}})),k.ajaxPrefilter((function(t){var e;for(e in t.headers)"content-type"===e.toLowerCase()&&(t.contentType=t.headers[e]||"")})),k._evalUrl=function(t,e,n){return k.ajax({url:t,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(t){k.globalEval(t,e,n)}})},k.fn.extend({wrapAll:function(t){var e;return this[0]&&(g(t)&&(t=t.call(this[0])),e=k(t,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&e.insertBefore(this[0]),e.map((function(){for(var t=this;t.firstElementChild;)t=t.firstElementChild;return t})).append(this)),this},wrapInner:function(t){return g(t)?this.each((function(e){k(this).wrapInner(t.call(this,e))})):this.each((function(){var e=k(this),n=e.contents();n.length?n.wrapAll(t):e.append(t)}))},wrap:function(t){var e=g(t);return this.each((function(n){k(this).wrapAll(e?t.call(this,n):t)}))},unwrap:function(t){return this.parent(t).not("body").each((function(){k(this).replaceWith(this.childNodes)})),this}}),k.expr.pseudos.hidden=function(t){return!k.expr.pseudos.visible(t)},k.expr.pseudos.visible=function(t){return!!(t.offsetWidth||t.offsetHeight||t.getClientRects().length)},k.ajaxSettings.xhr=function(){try{return new r.XMLHttpRequest}catch(t){}};var Qe={0:200,1223:204},Je=k.ajaxSettings.xhr();v.cors=!!Je&&"withCredentials"in Je,v.ajax=Je=!!Je,k.ajaxTransport((function(t){var e,n;if(v.cors||Je&&!t.crossDomain)return{send:function(o,i){var a,s=t.xhr();if(s.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(a in t.xhrFields)s[a]=t.xhrFields[a];for(a in t.mimeType&&s.overrideMimeType&&s.overrideMimeType(t.mimeType),t.crossDomain||o["X-Requested-With"]||(o["X-Requested-With"]="XMLHttpRequest"),o)s.setRequestHeader(a,o[a]);e=function(t){return function(){e&&(e=n=s.onload=s.onerror=s.onabort=s.ontimeout=s.onreadystatechange=null,"abort"===t?s.abort():"error"===t?"number"!=typeof s.status?i(0,"error"):i(s.status,s.statusText):i(Qe[s.status]||s.status,s.statusText,"text"!==(s.responseType||"text")||"string"!=typeof s.responseText?{binary:s.response}:{text:s.responseText},s.getAllResponseHeaders()))}},s.onload=e(),n=s.onerror=s.ontimeout=e("error"),void 0!==s.onabort?s.onabort=n:s.onreadystatechange=function(){4===s.readyState&&r.setTimeout((function(){e&&n()}))},e=e("abort");try{s.send(t.hasContent&&t.data||null)}catch(t){if(e)throw t}},abort:function(){e&&e()}}})),k.ajaxPrefilter((function(t){t.crossDomain&&(t.contents.script=!1)})),k.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(t){return k.globalEval(t),t}}}),k.ajaxPrefilter("script",(function(t){void 0===t.cache&&(t.cache=!1),t.crossDomain&&(t.type="GET")})),k.ajaxTransport("script",(function(t){var e,n;if(t.crossDomain||t.scriptAttrs)return{send:function(r,o){e=k("