diff --git a/.eslintrc b/.eslintrc
index 14f4397ffbe..cf49ebceb0f 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -1,8 +1,12 @@
{
'plugins': [
- 'babel',
+ '@babel',
'promise',
- 'jsdoc',
+ 'jsdoc'
+ ],
+ 'extends': [
+ 'eslint:recommended',
+ 'plugin:promise/recommended'
],
'env': {
'browser': true,
@@ -16,42 +20,19 @@
'M': true,
'Y': true
},
+ // Warn about unused eslint-disable statements.
+ 'reportUnusedDisableDirectives': true,
'rules': {
// See http://eslint.org/docs/rules/ for all rules and explanations of all
// rules.
// === Possible Errors ===
'comma-dangle': 'off',
- 'no-compare-neg-zero': 'error',
- 'no-cond-assign': 'error',
'no-console': 'error',
- 'no-constant-condition': 'error',
- 'no-control-regex': 'error',
- 'no-debugger': 'error',
- 'no-dupe-args': 'error',
- 'no-dupe-keys': 'error',
- 'no-duplicate-case': 'error',
'no-empty': 'warn',
- 'no-empty-character-class': 'error',
- 'no-ex-assign': 'error',
- 'no-extra-boolean-cast': 'error',
'no-extra-parens': 'off',
- 'no-extra-semi': 'error',
- 'no-func-assign': 'error',
- 'no-inner-declarations': 'error',
- 'no-invalid-regexp': 'error',
- 'no-irregular-whitespace': 'error',
- 'no-obj-calls': 'error',
'no-prototype-builtins': 'off',
- 'no-regex-spaces': 'error',
- 'no-sparse-arrays': 'error',
- 'no-unexpected-multiline': 'error',
'no-unreachable': 'warn',
- 'no-unsafe-finally': 'error',
- 'no-unsafe-negation': 'error',
- 'use-isnan': 'error',
- 'valid-jsdoc': ['warn', { 'requireReturn': false, 'requireParamDescription': false, 'requireReturnDescription': false }],
- 'valid-typeof': 'error',
// === Best Practices ===
// (these mostly match our jshint config)
@@ -63,15 +44,12 @@
'dot-notation': 'warn',
'no-alert': 'warn',
'no-caller': 'error',
- 'no-case-declarations': 'error',
'no-div-regex': 'error',
- 'no-empty-pattern': 'error',
'no-empty-function': 'warn',
'no-eq-null': 'error',
'no-eval': 'error',
'no-extend-native': 'error',
'no-extra-bind': 'warn',
- 'no-fallthrough': 'error',
'no-floating-decimal': 'warn',
'no-global-assign': 'warn',
'no-implied-eval': 'error',
@@ -83,28 +61,22 @@
'no-multi-str': 'error',
'no-new-func': 'error',
'no-new-wrappers': 'error',
- 'no-octal': 'error',
'no-octal-escape': 'error',
'no-proto': 'error',
'no-redeclare': 'warn',
'no-restricted-globals': ['error', { 'name': 'Notification' }],
'no-return-assign': 'error',
'no-script-url': 'error',
- 'no-self-assign': 'error',
'no-self-compare': 'error',
'no-sequences': 'warn',
'no-throw-literal': 'warn',
'no-unmodified-loop-condition': 'error',
'no-unused-expressions': 'error',
- 'no-unused-labels': 'error',
'no-useless-call': 'warn',
'no-useless-escape': 'warn',
- 'no-with': 'error',
'wrap-iife': ['error', 'any'],
// === Variables ===
- 'no-delete-var': 'error',
- 'no-undef': 'error',
'no-undef-init': 'error',
'no-unused-vars': ['error', { 'caughtErrors': 'none' }],
@@ -137,8 +109,6 @@
'max-statements-per-line': ['warn', { max: 2 }],
'new-cap': ['warn', { 'properties': false }],
'new-parens': 'warn',
- 'newline-after-var': 'off',
- 'newline-before-return': 'off',
'newline-per-chained-call': 'off',
'no-array-constructor': 'off',
'no-bitwise': 'error',
@@ -146,7 +116,6 @@
'no-inline-comments': 'off',
'no-lonely-if': 'off',
'no-mixed-operators': 'off',
- 'no-mixed-spaces-and-tabs': 'error',
'no-multiple-empty-lines': 'warn',
'no-negated-condition': 'off',
'no-nested-ternary': 'warn',
@@ -168,7 +137,6 @@
'padded-blocks': 'off',
'quote-props': ['warn', 'as-needed', {'unnecessary': false, 'keywords': true, 'numbers': true}],
'quotes': 'off',
- 'require-jsdoc': 'warn',
'semi': 'error',
'semi-spacing': ['warn', {'before': false, 'after': true}],
'sort-vars': 'off',
@@ -181,21 +149,19 @@
'unicode-bom': 'error',
'wrap-regex': 'off',
- // === Promises ===
+ // === Promises (override plugin:promise/recommended) ===
'promise/always-return': 'warn',
'promise/no-return-wrap': 'warn',
'promise/param-names': 'warn',
'promise/catch-or-return': ['warn', {terminationMethod: ['catch', 'fail', 'always'], allowFinally: true}],
'promise/no-native': 'warn',
- 'promise/no-promise-in-callback': 'warn',
- 'promise/no-callback-in-promise': 'warn',
'promise/avoid-new': 'warn',
// === Deprecations ===
"no-restricted-properties": ['warn', {
'object': 'M',
'property': 'str',
- 'message': 'Use AMD module "core/str" or M.util.get_string()'
+ 'message': 'Use "core/str" module or M.util.get_string()'
}],
},
overrides: [
@@ -235,7 +201,6 @@
parser: '@babel/eslint-parser',
// Check AMD with some slightly stricter rules.
rules: {
- 'no-unused-vars': 'error',
'no-implicit-globals': 'error',
// Disable all of the rules that have babel versions.
'new-cap': 'off',
@@ -247,65 +212,37 @@
'semi': 'off',
'no-unused-expressions': 'off',
// Enable all of the babel version of these rules.
- 'babel/new-cap': ['warn', { 'properties': false }],
+ '@babel/new-cap': ['warn', { 'properties': false }],
// Not using this rule for the time being because it isn't
// compatible with jQuery and ES6.
- 'babel/no-invalid-this': 'off',
- 'babel/object-curly-spacing': 'warn',
- // This is off in the original style int.
- 'babel/quotes': 'off',
- 'babel/semi': 'error',
- 'babel/no-unused-expressions': 'error',
+ '@babel/no-invalid-this': 'off',
+ '@babel/object-curly-spacing': 'warn',
+ '@babel/semi': 'error',
+ '@babel/no-unused-expressions': 'error',
// === Promises ===
// We have Promise now that we're using ES6.
'promise/no-native': 'off',
'promise/avoid-new': 'off',
// === JSDocs ===
- "jsdoc/check-access": [
- 'error',
- ],
- "jsdoc/check-alignment": 1, // Recommended.
- "jsdoc/check-param-names": [
- 'error',
- ],
- "jsdoc/check-property-names": [
- 'error',
- ],
- "jsdoc/empty-tags": [
- 'error',
- ],
- "jsdoc/implements-on-classes": [
- 'error',
- ],
- "jsdoc/multiline-blocks": [
- 'error',
- ],
- "jsdoc/require-jsdoc": [
- 'error',
- ],
- "jsdoc/require-param": [
- 'error',
- ],
- "jsdoc/require-param-name": [
- 'error',
- ],
- "jsdoc/require-param-type": [
- 'error',
- ],
- "jsdoc/require-property": [
- 'error',
- ],
- "jsdoc/require-property-name": [
- 'error',
- ],
- "jsdoc/require-property-type": [
- 'error',
- ],
+ 'jsdoc/check-access': 'error',
+ 'jsdoc/check-alignment': 1, // Recommended.
+ 'jsdoc/check-param-names': 'error',
+ 'jsdoc/check-property-names': 'error',
+ 'jsdoc/empty-tags': 'error',
+ 'jsdoc/implements-on-classes': 'error',
+ 'jsdoc/multiline-blocks': 'error',
+ 'jsdoc/require-jsdoc': 'error',
+ 'jsdoc/require-param': 'error',
+ 'jsdoc/require-param-name': 'error',
+ 'jsdoc/require-param-type': 'error',
+ 'jsdoc/require-property': 'error',
+ 'jsdoc/require-property-name': 'error',
+ 'jsdoc/require-property-type': 'error'
},
parserOptions: {
'sourceType': 'module',
- 'requireConfigFile': false,
+ 'requireConfigFile': false
}
}
]
diff --git a/.grunt/tasks/javascript.js b/.grunt/tasks/javascript.js
index 19ece75d5b2..34b57bc755b 100644
--- a/.grunt/tasks/javascript.js
+++ b/.grunt/tasks/javascript.js
@@ -151,11 +151,7 @@ module.exports = grunt => {
//
// It also adds the Moodle plugin name to the AMD module definition
// so that it can be imported as expected in other modules.
- path.resolve('.grunt/babel-plugin-add-module-to-define.js'),
- '@babel/plugin-syntax-dynamic-import',
- '@babel/plugin-syntax-import-meta',
- ['@babel/plugin-proposal-class-properties', {'loose': false}],
- '@babel/plugin-proposal-json-strings'
+ path.resolve('.grunt/babel-plugin-add-module-to-define.js')
],
presets: [
['@babel/preset-env', {
diff --git a/admin/tool/lp/amd/build/competency_rule.min.js.map b/admin/tool/lp/amd/build/competency_rule.min.js.map
index 863fade449a..728f4bc2040 100644
--- a/admin/tool/lp/amd/build/competency_rule.min.js.map
+++ b/admin/tool/lp/amd/build/competency_rule.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"competency_rule.min.js","sources":["../src/competency_rule.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Competency rule base module.\n *\n * @module tool_lp/competency_rule\n * @copyright 2015 Frédéric Massart - FMCorz.net\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(['jquery'], function($) {\n\n /**\n * Competency rule abstract class.\n *\n * Any competency rule should extend this object. The event 'change' should be\n * triggered on the instance when the configuration has changed. This will allow\n * the components using the rule to gather the config, or check its validity.\n *\n * this._triggerChange();\n *\n * @param {Tree} tree The competency tree.\n */\n var Rule = function(tree) {\n this._eventNode = $('
');\n this._ready = $.Deferred();\n this._tree = tree;\n };\n\n /** @property {Object} The current competency. */\n Rule.prototype._competency = null;\n /** @property {Node} The node we attach the events to. */\n Rule.prototype._eventNode = null;\n /** @property {Promise} Resolved when the object is ready. */\n Rule.prototype._ready = null;\n /** @property {Tree} The competency tree. */\n Rule.prototype._tree = null;\n\n /**\n * Whether or not the current competency can be configured using this rule.\n *\n * @return {Boolean}\n * @method canConfig\n */\n Rule.prototype.canConfig = function() {\n return this._tree.hasChildren(this._competency.id);\n };\n\n /**\n * The config established by this rule.\n *\n * To override in subclasses when relevant.\n *\n * @return {String|null}\n * @method getConfig\n */\n Rule.prototype.getConfig = function() {\n return null;\n };\n\n // eslint-disable-line valid-jsdoc\n /**\n * Return the type of the module.\n *\n * @return {String}\n * @method getType\n */\n // eslint-enable-line valid-jsdoc\n Rule.prototype.getType = function() {\n throw new Error('Not implemented');\n };\n\n /**\n * The init process.\n *\n * Do not override this, instead override _load.\n *\n * @return {Promise} Revoled when the plugin is initialised.\n * @method init\n */\n Rule.prototype.init = function() {\n return this._load();\n };\n\n /**\n * Callback to inject the template.\n *\n * @returns {Promise} Resolved when done.\n * @method injectTemplate\n */\n Rule.prototype.injectTemplate = function() {\n return $.Deferred().reject().promise();\n };\n\n /**\n * Whether or not the current config is valid.\n *\n * Plugins should override this.\n *\n * @return {Boolean}\n * @method _isValid\n */\n Rule.prototype.isValid = function() {\n return false;\n };\n\n /**\n * Load the class.\n *\n * @return {Promise}\n * @method _load\n * @protected\n */\n Rule.prototype._load = function() {\n return $.when();\n };\n\n /**\n * Register an event listener.\n *\n * @param {String} type The event type.\n * @param {Function} handler The event listener.\n * @method on\n */\n Rule.prototype.on = function(type, handler) {\n this._eventNode.on(type, handler);\n };\n\n /**\n * Sets the current competency.\n *\n * @param {Competency} competency\n * @method setTargetCompetency\n */\n Rule.prototype.setTargetCompetency = function(competency) {\n this._competency = competency;\n };\n\n /**\n * Trigger an event.\n *\n * @param {String} type The type of event.\n * @param {Object} data The data to pass to the listeners.\n * @method _trigger\n * @protected\n */\n Rule.prototype._trigger = function(type, data) {\n this._eventNode.trigger(type, [data]);\n };\n\n /**\n * Trigger the change event.\n *\n * @method _triggerChange\n * @protected\n */\n Rule.prototype._triggerChange = function() {\n this._trigger('change', this);\n };\n\n return /** @alias module:tool_lp/competency_rule */ Rule;\n\n});\n"],"names":["define","$","Rule","tree","_eventNode","_ready","Deferred","_tree","prototype","_competency","canConfig","this","hasChildren","id","getConfig","getType","Error","init","_load","injectTemplate","reject","promise","isValid","when","on","type","handler","setTargetCompetency","competency","_trigger","data","trigger","_triggerChange"],"mappings":";;;;;;;AAuBAA,iCAAO,CAAC,WAAW,SAASC,OAapBC,KAAO,SAASC,WACXC,WAAaH,EAAE,cACfI,OAASJ,EAAEK,gBACXC,MAAQJ,aAIjBD,KAAKM,UAAUC,YAAc,KAE7BP,KAAKM,UAAUJ,WAAa,KAE5BF,KAAKM,UAAUH,OAAS,KAExBH,KAAKM,UAAUD,MAAQ,KAQvBL,KAAKM,UAAUE,UAAY,kBAChBC,KAAKJ,MAAMK,YAAYD,KAAKF,YAAYI,KAWnDX,KAAKM,UAAUM,UAAY,kBAChB,MAWXZ,KAAKM,UAAUO,QAAU,iBACf,IAAIC,MAAM,oBAWpBd,KAAKM,UAAUS,KAAO,kBACXN,KAAKO,SAShBhB,KAAKM,UAAUW,eAAiB,kBACrBlB,EAAEK,WAAWc,SAASC,WAWjCnB,KAAKM,UAAUc,QAAU,kBACd,GAUXpB,KAAKM,UAAUU,MAAQ,kBACZjB,EAAEsB,QAUbrB,KAAKM,UAAUgB,GAAK,SAASC,KAAMC,cAC1BtB,WAAWoB,GAAGC,KAAMC,UAS7BxB,KAAKM,UAAUmB,oBAAsB,SAASC,iBACrCnB,YAAcmB,YAWvB1B,KAAKM,UAAUqB,SAAW,SAASJ,KAAMK,WAChC1B,WAAW2B,QAAQN,KAAM,CAACK,QASnC5B,KAAKM,UAAUwB,eAAiB,gBACvBH,SAAS,SAAUlB,OAGwBT"}
\ No newline at end of file
+{"version":3,"file":"competency_rule.min.js","sources":["../src/competency_rule.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see
.\n\n/**\n * Competency rule base module.\n *\n * @module tool_lp/competency_rule\n * @copyright 2015 Frédéric Massart - FMCorz.net\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(['jquery'], function($) {\n\n /**\n * Competency rule abstract class.\n *\n * Any competency rule should extend this object. The event 'change' should be\n * triggered on the instance when the configuration has changed. This will allow\n * the components using the rule to gather the config, or check its validity.\n *\n * this._triggerChange();\n *\n * @param {Tree} tree The competency tree.\n */\n var Rule = function(tree) {\n this._eventNode = $('
');\n this._ready = $.Deferred();\n this._tree = tree;\n };\n\n /** @property {Object} The current competency. */\n Rule.prototype._competency = null;\n /** @property {Node} The node we attach the events to. */\n Rule.prototype._eventNode = null;\n /** @property {Promise} Resolved when the object is ready. */\n Rule.prototype._ready = null;\n /** @property {Tree} The competency tree. */\n Rule.prototype._tree = null;\n\n /**\n * Whether or not the current competency can be configured using this rule.\n *\n * @return {Boolean}\n * @method canConfig\n */\n Rule.prototype.canConfig = function() {\n return this._tree.hasChildren(this._competency.id);\n };\n\n /**\n * The config established by this rule.\n *\n * To override in subclasses when relevant.\n *\n * @return {String|null}\n * @method getConfig\n */\n Rule.prototype.getConfig = function() {\n return null;\n };\n\n /**\n * Return the type of the module.\n *\n * @return {String}\n * @method getType\n */\n Rule.prototype.getType = function() {\n throw new Error('Not implemented');\n };\n\n /**\n * The init process.\n *\n * Do not override this, instead override _load.\n *\n * @return {Promise} Revoled when the plugin is initialised.\n * @method init\n */\n Rule.prototype.init = function() {\n return this._load();\n };\n\n /**\n * Callback to inject the template.\n *\n * @returns {Promise} Resolved when done.\n * @method injectTemplate\n */\n Rule.prototype.injectTemplate = function() {\n return $.Deferred().reject().promise();\n };\n\n /**\n * Whether or not the current config is valid.\n *\n * Plugins should override this.\n *\n * @return {Boolean}\n * @method _isValid\n */\n Rule.prototype.isValid = function() {\n return false;\n };\n\n /**\n * Load the class.\n *\n * @return {Promise}\n * @method _load\n * @protected\n */\n Rule.prototype._load = function() {\n return $.when();\n };\n\n /**\n * Register an event listener.\n *\n * @param {String} type The event type.\n * @param {Function} handler The event listener.\n * @method on\n */\n Rule.prototype.on = function(type, handler) {\n this._eventNode.on(type, handler);\n };\n\n /**\n * Sets the current competency.\n *\n * @param {Competency} competency\n * @method setTargetCompetency\n */\n Rule.prototype.setTargetCompetency = function(competency) {\n this._competency = competency;\n };\n\n /**\n * Trigger an event.\n *\n * @param {String} type The type of event.\n * @param {Object} data The data to pass to the listeners.\n * @method _trigger\n * @protected\n */\n Rule.prototype._trigger = function(type, data) {\n this._eventNode.trigger(type, [data]);\n };\n\n /**\n * Trigger the change event.\n *\n * @method _triggerChange\n * @protected\n */\n Rule.prototype._triggerChange = function() {\n this._trigger('change', this);\n };\n\n return /** @alias module:tool_lp/competency_rule */ Rule;\n\n});\n"],"names":["define","$","Rule","tree","_eventNode","_ready","Deferred","_tree","prototype","_competency","canConfig","this","hasChildren","id","getConfig","getType","Error","init","_load","injectTemplate","reject","promise","isValid","when","on","type","handler","setTargetCompetency","competency","_trigger","data","trigger","_triggerChange"],"mappings":";;;;;;;AAuBAA,iCAAO,CAAC,WAAW,SAASC,OAapBC,KAAO,SAASC,WACXC,WAAaH,EAAE,cACfI,OAASJ,EAAEK,gBACXC,MAAQJ,aAIjBD,KAAKM,UAAUC,YAAc,KAE7BP,KAAKM,UAAUJ,WAAa,KAE5BF,KAAKM,UAAUH,OAAS,KAExBH,KAAKM,UAAUD,MAAQ,KAQvBL,KAAKM,UAAUE,UAAY,kBAChBC,KAAKJ,MAAMK,YAAYD,KAAKF,YAAYI,KAWnDX,KAAKM,UAAUM,UAAY,kBAChB,MASXZ,KAAKM,UAAUO,QAAU,iBACf,IAAIC,MAAM,oBAWpBd,KAAKM,UAAUS,KAAO,kBACXN,KAAKO,SAShBhB,KAAKM,UAAUW,eAAiB,kBACrBlB,EAAEK,WAAWc,SAASC,WAWjCnB,KAAKM,UAAUc,QAAU,kBACd,GAUXpB,KAAKM,UAAUU,MAAQ,kBACZjB,EAAEsB,QAUbrB,KAAKM,UAAUgB,GAAK,SAASC,KAAMC,cAC1BtB,WAAWoB,GAAGC,KAAMC,UAS7BxB,KAAKM,UAAUmB,oBAAsB,SAASC,iBACrCnB,YAAcmB,YAWvB1B,KAAKM,UAAUqB,SAAW,SAASJ,KAAMK,WAChC1B,WAAW2B,QAAQN,KAAM,CAACK,QASnC5B,KAAKM,UAAUwB,eAAiB,gBACvBH,SAAS,SAAUlB,OAGwBT"}
\ No newline at end of file
diff --git a/admin/tool/lp/amd/src/competency_rule.js b/admin/tool/lp/amd/src/competency_rule.js
index 0784351a1e8..217ca35583d 100644
--- a/admin/tool/lp/amd/src/competency_rule.js
+++ b/admin/tool/lp/amd/src/competency_rule.js
@@ -71,14 +71,12 @@ define(['jquery'], function($) {
return null;
};
- // eslint-disable-line valid-jsdoc
/**
* Return the type of the module.
*
* @return {String}
* @method getType
*/
- // eslint-enable-line valid-jsdoc
Rule.prototype.getType = function() {
throw new Error('Not implemented');
};
diff --git a/admin/tool/moodlenet/amd/build/instance_form.min.js.map b/admin/tool/moodlenet/amd/build/instance_form.min.js.map
index 4d3ccc56ff7..821603c3ba9 100644
--- a/admin/tool/moodlenet/amd/build/instance_form.min.js.map
+++ b/admin/tool/moodlenet/amd/build/instance_form.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"instance_form.min.js","sources":["../src/instance_form.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see
.\n\n/**\n * Our basic form manager for when a user either enters\n * their profile url or just wants to browse.\n *\n * This file is a mishmash of JS functions we need for both the standalone (M3.7, M3.8)\n * plugin & Moodle 3.9 functions. The 3.9 Functions have a base understanding that certain\n * things exist i.e. directory structures for templates. When this feature goes 3.9+ only\n * The goal is that we can quickly gut all AMD modules into bare JS files and use ES6 guidelines.\n * Till then this will have to do.\n *\n * @module tool_moodlenet/instance_form\n * @copyright 2020 Mathew May
\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(['tool_moodlenet/validator',\n 'tool_moodlenet/selectors',\n 'core/loadingicon',\n 'core/templates',\n 'core/notification',\n 'jquery'],\n function(Validator,\n Selectors,\n LoadingIcon,\n Templates,\n Notification,\n $) {\n\n /**\n * Add the event listeners to our form.\n *\n * @method registerListenerEvents\n * @param {HTMLElement} page The whole page element for our form area\n */\n var registerListenerEvents = function registerListenerEvents(page) {\n page.addEventListener('click', function(e) {\n\n // Our fake submit button / browse button.\n if (e.target.matches(Selectors.action.submit)) {\n var input = page.querySelector('[data-var=\"mnet-link\"]');\n var overlay = page.querySelector(Selectors.region.spinner);\n var validationArea = document.querySelector(Selectors.region.validationArea);\n\n overlay.classList.remove('d-none');\n var spinner = LoadingIcon.addIconToContainerWithPromise(overlay);\n Validator.validation(input)\n .then(function(result) {\n spinner.resolve();\n overlay.classList.add('d-none');\n if (result.result) {\n input.classList.remove('is-invalid'); // Just in case the class has been applied already.\n input.classList.add('is-valid');\n validationArea.innerText = result.message;\n validationArea.classList.remove('text-danger');\n validationArea.classList.add('text-success');\n // Give the user some time to see their input is valid.\n setTimeout(function() {\n window.location = result.domain;\n }, 1000);\n } else {\n input.classList.add('is-invalid');\n validationArea.innerText = result.message;\n validationArea.classList.add('text-danger');\n }\n return;\n }).catch();\n }\n });\n };\n\n /**\n * Given a user wishes to see the MoodleNet profile url form transition them there.\n *\n * @method chooserNavigateToMnet\n * @param {HTMLElement} showMoodleNet The chooser's area for ment\n * @param {Object} footerData Our footer object to render out\n * @param {jQuery} carousel Our carousel instance to manage\n * @param {jQuery} modal Our modal instance to manage\n */\n var chooserNavigateToMnet = function(showMoodleNet, footerData, carousel, modal) {\n showMoodleNet.innerHTML = '';\n\n // Add a spinner.\n var spinnerPromise = LoadingIcon.addIconToContainer(showMoodleNet);\n\n // Used later...\n var transitionPromiseResolver = null;\n var transitionPromise = new Promise(resolve => {\n transitionPromiseResolver = resolve;\n });\n\n $.when(\n spinnerPromise,\n transitionPromise\n ).then(function() {\n Templates.replaceNodeContents(showMoodleNet, footerData.customcarouseltemplate, '');\n return;\n }).catch(Notification.exception);\n\n // We apply our handlers in here to minimise plugin dependency in the Chooser.\n registerListenerEvents(showMoodleNet);\n\n // Move to the next slide, and resolve the transition promise when it's done.\n carousel.one('slid.bs.carousel', function() {\n transitionPromiseResolver();\n });\n // Trigger the transition between 'pages'.\n carousel.carousel(2);\n // eslint-disable-next-line max-len\n modal.setFooter(Templates.render('tool_moodlenet/chooser_footer_close_mnet', {}));\n };\n\n /**\n * Given a user no longer wishes to see the MoodleNet profile url form transition them from there.\n *\n * @method chooserNavigateFromMnet\n * @param {jQuery} carousel Our carousel instance to manage\n * @param {jQuery} modal Our modal instance to manage\n * @param {Object} footerData Our footer object to render out\n */\n var chooserNavigateFromMnet = function(carousel, modal, footerData) {\n // Trigger the transition between 'pages'.\n carousel.carousel(0);\n modal.setFooter(footerData.customfootertemplate);\n };\n\n /**\n * Create the custom listener that would handle anything in the footer.\n *\n * @param {Event} e The event being triggered.\n * @param {Object} footerData The data generated from the exporter.\n * @param {Object} modal The chooser modal.\n */\n var footerClickListener = function(e, footerData, modal) {\n if (e.target.matches(Selectors.action.showMoodleNet) || e.target.closest(Selectors.action.showMoodleNet)) {\n e.preventDefault();\n const carousel = $(modal.getBody()[0].querySelector(Selectors.region.carousel));\n const showMoodleNet = carousel.find(Selectors.region.moodleNet)[0];\n\n chooserNavigateToMnet(showMoodleNet, footerData, carousel, modal);\n }\n // From the help screen go back to the module overview.\n if (e.target.matches(Selectors.action.closeOption)) {\n const carousel = $(modal.getBody()[0].querySelector(Selectors.region.carousel));\n\n chooserNavigateFromMnet(carousel, modal, footerData);\n }\n };\n\n return {\n footerClickListener: footerClickListener\n };\n});\n"],"names":["define","Validator","Selectors","LoadingIcon","Templates","Notification","$","chooserNavigateToMnet","showMoodleNet","footerData","carousel","modal","innerHTML","page","spinnerPromise","addIconToContainer","transitionPromiseResolver","transitionPromise","Promise","resolve","when","then","replaceNodeContents","customcarouseltemplate","catch","exception","addEventListener","e","target","matches","action","submit","input","querySelector","overlay","region","spinner","validationArea","document","classList","remove","addIconToContainerWithPromise","validation","result","add","innerText","message","setTimeout","window","location","domain","one","setFooter","render","footerClickListener","closest","preventDefault","getBody","find","moodleNet","closeOption","customfootertemplate","chooserNavigateFromMnet"],"mappings":";;;;;;;;;;;;;;AA8BAA,sCAAO,CAAC,2BACA,2BACA,mBACA,iBACA,oBACA,WACJ,SAASC,UACAC,UACAC,YACAC,UACAC,aACAC,OAqDLC,sBAAwB,SAASC,cAAeC,WAAYC,SAAUC,OACtEH,cAAcI,UAAY,OA9C+BC,KAiDrDC,eAAiBX,YAAYY,mBAAmBP,eAGhDQ,0BAA4B,KAC5BC,kBAAoB,IAAIC,SAAQC,UAChCH,0BAA4BG,WAGhCb,EAAEc,KACEN,eACAG,mBACFI,MAAK,WACCjB,UAAUkB,oBAAoBd,cAAeC,WAAWc,uBAAwB,OAErFC,MAAMnB,aAAaoB,YA/DmCZ,KAkElCL,eAjElBkB,iBAAiB,SAAS,SAASC,MAGhCA,EAAEC,OAAOC,QAAQ3B,UAAU4B,OAAOC,QAAS,KACvCC,MAAQnB,KAAKoB,cAAc,0BAC3BC,QAAUrB,KAAKoB,cAAc/B,UAAUiC,OAAOC,SAC9CC,eAAiBC,SAASL,cAAc/B,UAAUiC,OAAOE,gBAE7DH,QAAQK,UAAUC,OAAO,cACrBJ,QAAUjC,YAAYsC,8BAA8BP,SACxDjC,UAAUyC,WAAWV,OAChBX,MAAK,SAASsB,QACXP,QAAQjB,UACRe,QAAQK,UAAUK,IAAI,UAClBD,OAAOA,QACPX,MAAMO,UAAUC,OAAO,cACvBR,MAAMO,UAAUK,IAAI,YACpBP,eAAeQ,UAAYF,OAAOG,QAClCT,eAAeE,UAAUC,OAAO,eAChCH,eAAeE,UAAUK,IAAI,gBAE7BG,YAAW,WACPC,OAAOC,SAAWN,OAAOO,SAC1B,OAEHlB,MAAMO,UAAUK,IAAI,cACpBP,eAAeQ,UAAYF,OAAOG,QAClCT,eAAeE,UAAUK,IAAI,mBAGtCpB,YAsCXd,SAASyC,IAAI,oBAAoB,WAC7BnC,+BAGJN,SAASA,SAAS,GAElBC,MAAMyC,UAAUhD,UAAUiD,OAAO,2CAA4C,YAwC1E,CACHC,oBAjBsB,SAAS3B,EAAGlB,WAAYE,UAC1CgB,EAAEC,OAAOC,QAAQ3B,UAAU4B,OAAOtB,gBAAkBmB,EAAEC,OAAO2B,QAAQrD,UAAU4B,OAAOtB,eAAgB,CACtGmB,EAAE6B,uBACI9C,SAAWJ,EAAEK,MAAM8C,UAAU,GAAGxB,cAAc/B,UAAUiC,OAAOzB,WAC/DF,cAAgBE,SAASgD,KAAKxD,UAAUiC,OAAOwB,WAAW,GAEhEpD,sBAAsBC,cAAeC,WAAYC,SAAUC,UAG3DgB,EAAEC,OAAOC,QAAQ3B,UAAU4B,OAAO8B,aAAc,EAtB1B,SAASlD,SAAUC,MAAOF,YAEpDC,SAASA,SAAS,GAClBC,MAAMyC,UAAU3C,WAAWoD,sBAsBvBC,CAFiBxD,EAAEK,MAAM8C,UAAU,GAAGxB,cAAc/B,UAAUiC,OAAOzB,WAEnCC,MAAOF"}
\ No newline at end of file
+{"version":3,"file":"instance_form.min.js","sources":["../src/instance_form.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Our basic form manager for when a user either enters\n * their profile url or just wants to browse.\n *\n * This file is a mishmash of JS functions we need for both the standalone (M3.7, M3.8)\n * plugin & Moodle 3.9 functions. The 3.9 Functions have a base understanding that certain\n * things exist i.e. directory structures for templates. When this feature goes 3.9+ only\n * The goal is that we can quickly gut all AMD modules into bare JS files and use ES6 guidelines.\n * Till then this will have to do.\n *\n * @module tool_moodlenet/instance_form\n * @copyright 2020 Mathew May \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(['tool_moodlenet/validator',\n 'tool_moodlenet/selectors',\n 'core/loadingicon',\n 'core/templates',\n 'core/notification',\n 'jquery'],\n function(Validator,\n Selectors,\n LoadingIcon,\n Templates,\n Notification,\n $) {\n\n /**\n * Add the event listeners to our form.\n *\n * @method registerListenerEvents\n * @param {HTMLElement} page The whole page element for our form area\n */\n var registerListenerEvents = function registerListenerEvents(page) {\n page.addEventListener('click', function(e) {\n\n // Our fake submit button / browse button.\n if (e.target.matches(Selectors.action.submit)) {\n var input = page.querySelector('[data-var=\"mnet-link\"]');\n var overlay = page.querySelector(Selectors.region.spinner);\n var validationArea = document.querySelector(Selectors.region.validationArea);\n\n overlay.classList.remove('d-none');\n var spinner = LoadingIcon.addIconToContainerWithPromise(overlay);\n Validator.validation(input)\n .then(function(result) {\n spinner.resolve();\n overlay.classList.add('d-none');\n if (result.result) {\n input.classList.remove('is-invalid'); // Just in case the class has been applied already.\n input.classList.add('is-valid');\n validationArea.innerText = result.message;\n validationArea.classList.remove('text-danger');\n validationArea.classList.add('text-success');\n // Give the user some time to see their input is valid.\n setTimeout(function() {\n window.location = result.domain;\n }, 1000);\n } else {\n input.classList.add('is-invalid');\n validationArea.innerText = result.message;\n validationArea.classList.add('text-danger');\n }\n return;\n }).catch();\n }\n });\n };\n\n /**\n * Given a user wishes to see the MoodleNet profile url form transition them there.\n *\n * @method chooserNavigateToMnet\n * @param {HTMLElement} showMoodleNet The chooser's area for ment\n * @param {Object} footerData Our footer object to render out\n * @param {jQuery} carousel Our carousel instance to manage\n * @param {jQuery} modal Our modal instance to manage\n */\n var chooserNavigateToMnet = function(showMoodleNet, footerData, carousel, modal) {\n showMoodleNet.innerHTML = '';\n\n // Add a spinner.\n var spinnerPromise = LoadingIcon.addIconToContainer(showMoodleNet);\n\n // Used later...\n var transitionPromiseResolver = null;\n var transitionPromise = new Promise(resolve => {\n transitionPromiseResolver = resolve;\n });\n\n $.when(\n spinnerPromise,\n transitionPromise\n ).then(function() {\n Templates.replaceNodeContents(showMoodleNet, footerData.customcarouseltemplate, '');\n return;\n }).catch(Notification.exception);\n\n // We apply our handlers in here to minimise plugin dependency in the Chooser.\n registerListenerEvents(showMoodleNet);\n\n // Move to the next slide, and resolve the transition promise when it's done.\n carousel.one('slid.bs.carousel', function() {\n transitionPromiseResolver();\n });\n // Trigger the transition between 'pages'.\n carousel.carousel(2);\n modal.setFooter(Templates.render('tool_moodlenet/chooser_footer_close_mnet', {}));\n };\n\n /**\n * Given a user no longer wishes to see the MoodleNet profile url form transition them from there.\n *\n * @method chooserNavigateFromMnet\n * @param {jQuery} carousel Our carousel instance to manage\n * @param {jQuery} modal Our modal instance to manage\n * @param {Object} footerData Our footer object to render out\n */\n var chooserNavigateFromMnet = function(carousel, modal, footerData) {\n // Trigger the transition between 'pages'.\n carousel.carousel(0);\n modal.setFooter(footerData.customfootertemplate);\n };\n\n /**\n * Create the custom listener that would handle anything in the footer.\n *\n * @param {Event} e The event being triggered.\n * @param {Object} footerData The data generated from the exporter.\n * @param {Object} modal The chooser modal.\n */\n var footerClickListener = function(e, footerData, modal) {\n if (e.target.matches(Selectors.action.showMoodleNet) || e.target.closest(Selectors.action.showMoodleNet)) {\n e.preventDefault();\n const carousel = $(modal.getBody()[0].querySelector(Selectors.region.carousel));\n const showMoodleNet = carousel.find(Selectors.region.moodleNet)[0];\n\n chooserNavigateToMnet(showMoodleNet, footerData, carousel, modal);\n }\n // From the help screen go back to the module overview.\n if (e.target.matches(Selectors.action.closeOption)) {\n const carousel = $(modal.getBody()[0].querySelector(Selectors.region.carousel));\n\n chooserNavigateFromMnet(carousel, modal, footerData);\n }\n };\n\n return {\n footerClickListener: footerClickListener\n };\n});\n"],"names":["define","Validator","Selectors","LoadingIcon","Templates","Notification","$","chooserNavigateToMnet","showMoodleNet","footerData","carousel","modal","innerHTML","page","spinnerPromise","addIconToContainer","transitionPromiseResolver","transitionPromise","Promise","resolve","when","then","replaceNodeContents","customcarouseltemplate","catch","exception","addEventListener","e","target","matches","action","submit","input","querySelector","overlay","region","spinner","validationArea","document","classList","remove","addIconToContainerWithPromise","validation","result","add","innerText","message","setTimeout","window","location","domain","one","setFooter","render","footerClickListener","closest","preventDefault","getBody","find","moodleNet","closeOption","customfootertemplate","chooserNavigateFromMnet"],"mappings":";;;;;;;;;;;;;;AA8BAA,sCAAO,CAAC,2BACA,2BACA,mBACA,iBACA,oBACA,WACJ,SAASC,UACAC,UACAC,YACAC,UACAC,aACAC,OAqDLC,sBAAwB,SAASC,cAAeC,WAAYC,SAAUC,OACtEH,cAAcI,UAAY,OA9C+BC,KAiDrDC,eAAiBX,YAAYY,mBAAmBP,eAGhDQ,0BAA4B,KAC5BC,kBAAoB,IAAIC,SAAQC,UAChCH,0BAA4BG,WAGhCb,EAAEc,KACEN,eACAG,mBACFI,MAAK,WACCjB,UAAUkB,oBAAoBd,cAAeC,WAAWc,uBAAwB,OAErFC,MAAMnB,aAAaoB,YA/DmCZ,KAkElCL,eAjElBkB,iBAAiB,SAAS,SAASC,MAGhCA,EAAEC,OAAOC,QAAQ3B,UAAU4B,OAAOC,QAAS,KACvCC,MAAQnB,KAAKoB,cAAc,0BAC3BC,QAAUrB,KAAKoB,cAAc/B,UAAUiC,OAAOC,SAC9CC,eAAiBC,SAASL,cAAc/B,UAAUiC,OAAOE,gBAE7DH,QAAQK,UAAUC,OAAO,cACrBJ,QAAUjC,YAAYsC,8BAA8BP,SACxDjC,UAAUyC,WAAWV,OAChBX,MAAK,SAASsB,QACXP,QAAQjB,UACRe,QAAQK,UAAUK,IAAI,UAClBD,OAAOA,QACPX,MAAMO,UAAUC,OAAO,cACvBR,MAAMO,UAAUK,IAAI,YACpBP,eAAeQ,UAAYF,OAAOG,QAClCT,eAAeE,UAAUC,OAAO,eAChCH,eAAeE,UAAUK,IAAI,gBAE7BG,YAAW,WACPC,OAAOC,SAAWN,OAAOO,SAC1B,OAEHlB,MAAMO,UAAUK,IAAI,cACpBP,eAAeQ,UAAYF,OAAOG,QAClCT,eAAeE,UAAUK,IAAI,mBAGtCpB,YAsCXd,SAASyC,IAAI,oBAAoB,WAC7BnC,+BAGJN,SAASA,SAAS,GAClBC,MAAMyC,UAAUhD,UAAUiD,OAAO,2CAA4C,YAwC1E,CACHC,oBAjBsB,SAAS3B,EAAGlB,WAAYE,UAC1CgB,EAAEC,OAAOC,QAAQ3B,UAAU4B,OAAOtB,gBAAkBmB,EAAEC,OAAO2B,QAAQrD,UAAU4B,OAAOtB,eAAgB,CACtGmB,EAAE6B,uBACI9C,SAAWJ,EAAEK,MAAM8C,UAAU,GAAGxB,cAAc/B,UAAUiC,OAAOzB,WAC/DF,cAAgBE,SAASgD,KAAKxD,UAAUiC,OAAOwB,WAAW,GAEhEpD,sBAAsBC,cAAeC,WAAYC,SAAUC,UAG3DgB,EAAEC,OAAOC,QAAQ3B,UAAU4B,OAAO8B,aAAc,EAtB1B,SAASlD,SAAUC,MAAOF,YAEpDC,SAASA,SAAS,GAClBC,MAAMyC,UAAU3C,WAAWoD,sBAsBvBC,CAFiBxD,EAAEK,MAAM8C,UAAU,GAAGxB,cAAc/B,UAAUiC,OAAOzB,WAEnCC,MAAOF"}
\ No newline at end of file
diff --git a/admin/tool/moodlenet/amd/src/instance_form.js b/admin/tool/moodlenet/amd/src/instance_form.js
index 59ab4e921c7..57b4cd50159 100644
--- a/admin/tool/moodlenet/amd/src/instance_form.js
+++ b/admin/tool/moodlenet/amd/src/instance_form.js
@@ -121,7 +121,6 @@ define(['tool_moodlenet/validator',
});
// Trigger the transition between 'pages'.
carousel.carousel(2);
- // eslint-disable-next-line max-len
modal.setFooter(Templates.render('tool_moodlenet/chooser_footer_close_mnet', {}));
};
diff --git a/course/format/amd/build/local/courseeditor/fileuploader.min.js b/course/format/amd/build/local/courseeditor/fileuploader.min.js
index e74631786a9..308e86a85c1 100644
--- a/course/format/amd/build/local/courseeditor/fileuploader.min.js
+++ b/course/format/amd/build/local/courseeditor/fileuploader.min.js
@@ -1,3 +1,3 @@
-define("core_courseformat/local/courseeditor/fileuploader",["exports","core/config","core/modal_factory","core/modal_events","core/templates","core/normalise","core/prefetch","core/str","core_courseformat/courseeditor","core/process_monitor","core/utils"],(function(_exports,_config,_modal_factory,_modal_events,_templates,_normalise,_prefetch,_str,_courseeditor,_process_monitor,_utils){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.uploadFilesToCourse=void 0,_config=_interopRequireDefault(_config),_modal_factory=_interopRequireDefault(_modal_factory),_modal_events=_interopRequireDefault(_modal_events),_templates=_interopRequireDefault(_templates);const UPLOADURL=_config.default.wwwroot+"/course/dndupload.php";let uploadQueue=null,handlerManagers={},courseUpdates=new Map,errors=null;(0,_prefetch.prefetchStrings)("moodle",["addresourceoractivity","upload"]),(0,_prefetch.prefetchStrings)("core_error",["dndmaxbytes","dndread","dndupload","dndunkownfile"]);class FileUploader{constructor(courseId,sectionId,sectionNum,fileInfo,handler){this.courseId=courseId,this.sectionId=sectionId,this.sectionNum=sectionNum,this.fileInfo=fileInfo,this.handler=handler}execute(process){const fileInfo=this.fileInfo,xhr=this._createXhrRequest(process),formData=this._createUploadFormData(),reader=new FileReader;reader.onload=function(){xhr.open("POST",UPLOADURL,!0),xhr.send(formData)},reader.onerror=function(){process.setError(errors.dndread)},fileInfo.size>0?reader.readAsText(fileInfo.slice(0,5)):reader.readAsText(fileInfo)}getExecutionFunction(){return this.execute.bind(this)}_createXhrRequest(process){const xhr=new XMLHttpRequest;return xhr.upload.addEventListener("progress",(event=>{if(event.lengthComputable){const percent=Math.round(100*event.loaded/event.total);process.setPercentage(percent)}}),!1),xhr.onreadystatechange=()=>{if(1==xhr.readyState&&process.setPercentage(1),4==xhr.readyState)if(200==xhr.status){var result=JSON.parse(xhr.responseText);result&&0==result.error?this._finishProcess(process):process.setError(result.error)}else process.setError(errors.dndupload)},xhr}_createUploadFormData(){const formData=new FormData;try{formData.append("repo_upload_file",this.fileInfo)}catch(error){throw Error(error.dndread)}return formData.append("sesskey",_config.default.sesskey),formData.append("course",this.courseId),formData.append("section",this.sectionNum),formData.append("module",this.handler.module),formData.append("type","Files"),formData}_finishProcess(process){!function(courseId,sectionId){let refresh=courseUpdates.get(courseId);refresh||(refresh=new Set);refresh.add(sectionId),courseUpdates.set(courseId,refresh),refreshCourseEditors()}(this.courseId,this.sectionId),process.setPercentage(100),process.finish()}}class HandlerManager{constructor(courseId){var _this$courseEditor$ge,_this$courseEditor$ge2;if(_defineProperty(this,"lastHandlers",{}),_defineProperty(this,"allHandlers",null),this.courseId=courseId,this.lastUploadId=0,this.courseEditor=(0,_courseeditor.getCourseEditor)(courseId),!this.courseEditor)throw Error("Unkown course editor");this.maxbytes=null!==(_this$courseEditor$ge=null===(_this$courseEditor$ge2=this.courseEditor.get("course"))||void 0===_this$courseEditor$ge2?void 0:_this$courseEditor$ge2.maxbytes)&&void 0!==_this$courseEditor$ge?_this$courseEditor$ge:0}async loadHandlers(){this.allHandlers=await this.courseEditor.getFileHandlersPromise()}getFileExtension(fileInfo){let extension="";const dotpos=fileInfo.name.lastIndexOf(".");return-1!=dotpos&&(extension=fileInfo.name.substring(dotpos+1,fileInfo.name.length).toLowerCase()),extension}validateFile(fileInfo){if(-1!==this.maxbytes&&fileInfo.size>this.maxbytes)throw Error(errors.dndmaxbytes)}filterHandlers(fileInfo){const extension=this.getFileExtension(fileInfo);return this.allHandlers.filter((handler=>"*"==handler.extension||handler.extension==extension))}async getFileHandler(fileInfo){const fileHandlers=this.filterHandlers(fileInfo);if(0==fileHandlers.length)throw Error(errors.dndunkownfile);let fileHandler=null;return fileHandler=1==fileHandlers.length?fileHandlers[0]:await this.askHandlerToUser(fileHandlers,fileInfo),fileHandler}async askHandlerToUser(fileHandlers,fileInfo){var _this$lastHandlers$ex;const extension=this.getFileExtension(fileInfo),modalParams={title:(0,_str.get_string)("addresourceoractivity","moodle"),body:_templates.default.render("core_courseformat/fileuploader",this.getModalData(fileHandlers,fileInfo,null!==(_this$lastHandlers$ex=this.lastHandlers[extension])&&void 0!==_this$lastHandlers$ex?_this$lastHandlers$ex:null)),type:_modal_factory.default.types.SAVE_CANCEL,saveButtonText:(0,_str.get_string)("upload","moodle")},modal=await this.modalBodyRenderedPromise(modalParams),selectedHandler=await this.modalUserAnswerPromise(modal,fileHandlers);return null===selectedHandler?null:(this.lastHandlers[extension]=selectedHandler.module,selectedHandler)}getModalData(fileHandlers,fileInfo,defaultModule){const data={filename:fileInfo.name,uploadid:++this.lastUploadId,handlers:[]};let hasDefault=!1;if(fileHandlers.forEach(((handler,index)=>{const isDefault=defaultModule==handler.module;data.handlers.push({...handler,selected:isDefault,labelid:"fileuploader_".concat(data.uploadid),value:index}),hasDefault=hasDefault||isDefault})),!hasDefault&&data.handlers.length>0){const lastHandler=data.handlers.pop();lastHandler.selected=!0,data.handlers.push(lastHandler)}return data}modalUserAnswerPromise(modal,fileHandlers){const modalBody=(0,_normalise.getFirst)(modal.getBody());return new Promise(((resolve,reject)=>{modal.getRoot().on(_modal_events.default.save,(event=>{const index=modalBody.querySelector("input:checked").value;event.preventDefault(),modal.destroy(),fileHandlers[index]||reject("Invalid handler selected"),resolve(fileHandlers[index])})),modal.getRoot().on(_modal_events.default.cancel,(()=>{resolve(null)}))}))}modalBodyRenderedPromise(modalParams){return new Promise(((resolve,reject)=>{_modal_factory.default.create(modalParams).then((modal=>{modal.setRemoveOnClose(!0),modal.getRoot().on(_modal_events.default.bodyRendered,(()=>{resolve(modal)})),void 0!==modalParams.saveButtonText&&modal.setSaveButtonText(modalParams.saveButtonText),modal.show()})).catch((()=>{reject("Cannot load modal content")}))}))}}const refreshCourseEditors=(0,_utils.debounce)((()=>{const refreshes=courseUpdates;courseUpdates=new Map,refreshes.forEach(((sectionIds,courseId)=>{const courseEditor=(0,_courseeditor.getCourseEditor)(courseId);courseEditor&&courseEditor.dispatch("sectionState",[...sectionIds])}))}),500);const queueFileUpload=async function(courseId,sectionId,sectionNum,fileInfo,handlerManager){let handler;uploadQueue=await _process_monitor.processMonitor.createProcessQueue();try{handlerManager.validateFile(fileInfo),handler=await handlerManager.getFileHandler(fileInfo)}catch(error){return void uploadQueue.addError(fileInfo.name,error.message)}if(!handler)return;const fileProcessor=new FileUploader(courseId,sectionId,sectionNum,fileInfo,handler);uploadQueue.addPending(fileInfo.name,fileProcessor.getExecutionFunction())};_exports.uploadFilesToCourse=async function(courseId,sectionId,sectionNum,files){let handlerManager;try{handlerManager=await async function(courseId){if(void 0!==handlerManagers[courseId])return handlerManagers[courseId];try{const handlerManager=new HandlerManager(courseId);await handlerManager.loadHandlers(),handlerManagers[courseId]=handlerManager}catch(error){throw error}return handlerManagers[courseId]}(courseId),await async function(courseId){var _courseEditor$get$max,_courseEditor$get;if(null!==errors)return;const maxbytestext=null!==(_courseEditor$get$max=null===(_courseEditor$get=(0,_courseeditor.getCourseEditor)(courseId).get("course"))||void 0===_courseEditor$get?void 0:_courseEditor$get.maxbytestext)&&void 0!==_courseEditor$get$max?_courseEditor$get$max:"0";errors={};const allStrings=[{key:"dndmaxbytes",component:"core_error",param:{size:maxbytestext}},{key:"dndread",component:"core_error"},{key:"dndupload",component:"core_error"},{key:"dndunkownfile",component:"core_error"}];window.console.log(allStrings);const loadedStrings=await(0,_str.get_strings)(allStrings);allStrings.forEach(((_ref,index)=>{let{key:key}=_ref;errors[key]=loadedStrings[index]}))}(courseId)}catch(error){throw error}for(let index=0;index0?reader.readAsText(fileInfo.slice(0,5)):reader.readAsText(fileInfo)}getExecutionFunction(){return this.execute.bind(this)}_createXhrRequest(process){const xhr=new XMLHttpRequest;return xhr.upload.addEventListener("progress",(event=>{if(event.lengthComputable){const percent=Math.round(100*event.loaded/event.total);process.setPercentage(percent)}}),!1),xhr.onreadystatechange=()=>{if(1==xhr.readyState&&process.setPercentage(1),4==xhr.readyState)if(200==xhr.status){var result=JSON.parse(xhr.responseText);result&&0==result.error?this._finishProcess(process):process.setError(result.error)}else process.setError(errors.dndupload)},xhr}_createUploadFormData(){const formData=new FormData;try{formData.append("repo_upload_file",this.fileInfo)}catch(error){throw Error(error.dndread)}return formData.append("sesskey",_config.default.sesskey),formData.append("course",this.courseId),formData.append("section",this.sectionNum),formData.append("module",this.handler.module),formData.append("type","Files"),formData}_finishProcess(process){!function(courseId,sectionId){let refresh=courseUpdates.get(courseId);refresh||(refresh=new Set);refresh.add(sectionId),courseUpdates.set(courseId,refresh),refreshCourseEditors()}(this.courseId,this.sectionId),process.setPercentage(100),process.finish()}}class HandlerManager{constructor(courseId){var _this$courseEditor$ge,_this$courseEditor$ge2;if(_defineProperty(this,"lastHandlers",{}),_defineProperty(this,"allHandlers",null),this.courseId=courseId,this.lastUploadId=0,this.courseEditor=(0,_courseeditor.getCourseEditor)(courseId),!this.courseEditor)throw Error("Unkown course editor");this.maxbytes=null!==(_this$courseEditor$ge=null===(_this$courseEditor$ge2=this.courseEditor.get("course"))||void 0===_this$courseEditor$ge2?void 0:_this$courseEditor$ge2.maxbytes)&&void 0!==_this$courseEditor$ge?_this$courseEditor$ge:0}async loadHandlers(){this.allHandlers=await this.courseEditor.getFileHandlersPromise()}getFileExtension(fileInfo){let extension="";const dotpos=fileInfo.name.lastIndexOf(".");return-1!=dotpos&&(extension=fileInfo.name.substring(dotpos+1,fileInfo.name.length).toLowerCase()),extension}validateFile(fileInfo){if(-1!==this.maxbytes&&fileInfo.size>this.maxbytes)throw Error(errors.dndmaxbytes)}filterHandlers(fileInfo){const extension=this.getFileExtension(fileInfo);return this.allHandlers.filter((handler=>"*"==handler.extension||handler.extension==extension))}async getFileHandler(fileInfo){const fileHandlers=this.filterHandlers(fileInfo);if(0==fileHandlers.length)throw Error(errors.dndunkownfile);let fileHandler=null;return fileHandler=1==fileHandlers.length?fileHandlers[0]:await this.askHandlerToUser(fileHandlers,fileInfo),fileHandler}async askHandlerToUser(fileHandlers,fileInfo){var _this$lastHandlers$ex;const extension=this.getFileExtension(fileInfo),modalParams={title:(0,_str.get_string)("addresourceoractivity","moodle"),body:_templates.default.render("core_courseformat/fileuploader",this.getModalData(fileHandlers,fileInfo,null!==(_this$lastHandlers$ex=this.lastHandlers[extension])&&void 0!==_this$lastHandlers$ex?_this$lastHandlers$ex:null)),type:_modal_factory.default.types.SAVE_CANCEL,saveButtonText:(0,_str.get_string)("upload","moodle")},modal=await this.modalBodyRenderedPromise(modalParams),selectedHandler=await this.modalUserAnswerPromise(modal,fileHandlers);return null===selectedHandler?null:(this.lastHandlers[extension]=selectedHandler.module,selectedHandler)}getModalData(fileHandlers,fileInfo,defaultModule){const data={filename:fileInfo.name,uploadid:++this.lastUploadId,handlers:[]};let hasDefault=!1;if(fileHandlers.forEach(((handler,index)=>{const isDefault=defaultModule==handler.module;data.handlers.push({...handler,selected:isDefault,labelid:"fileuploader_".concat(data.uploadid),value:index}),hasDefault=hasDefault||isDefault})),!hasDefault&&data.handlers.length>0){const lastHandler=data.handlers.pop();lastHandler.selected=!0,data.handlers.push(lastHandler)}return data}modalUserAnswerPromise(modal,fileHandlers){const modalBody=(0,_normalise.getFirst)(modal.getBody());return new Promise(((resolve,reject)=>{modal.getRoot().on(_modal_events.default.save,(event=>{const index=modalBody.querySelector("input:checked").value;event.preventDefault(),modal.destroy(),fileHandlers[index]||reject("Invalid handler selected"),resolve(fileHandlers[index])})),modal.getRoot().on(_modal_events.default.cancel,(()=>{resolve(null)}))}))}modalBodyRenderedPromise(modalParams){return new Promise(((resolve,reject)=>{_modal_factory.default.create(modalParams).then((modal=>{modal.setRemoveOnClose(!0),modal.getRoot().on(_modal_events.default.bodyRendered,(()=>{resolve(modal)})),void 0!==modalParams.saveButtonText&&modal.setSaveButtonText(modalParams.saveButtonText),modal.show()})).catch((()=>{reject("Cannot load modal content")}))}))}}const refreshCourseEditors=(0,_utils.debounce)((()=>{const refreshes=courseUpdates;courseUpdates=new Map,refreshes.forEach(((sectionIds,courseId)=>{const courseEditor=(0,_courseeditor.getCourseEditor)(courseId);courseEditor&&courseEditor.dispatch("sectionState",[...sectionIds])}))}),500);const queueFileUpload=async function(courseId,sectionId,sectionNum,fileInfo,handlerManager){let handler;uploadQueue=await _process_monitor.processMonitor.createProcessQueue();try{handlerManager.validateFile(fileInfo),handler=await handlerManager.getFileHandler(fileInfo)}catch(error){return void uploadQueue.addError(fileInfo.name,error.message)}if(!handler)return;const fileProcessor=new FileUploader(courseId,sectionId,sectionNum,fileInfo,handler);uploadQueue.addPending(fileInfo.name,fileProcessor.getExecutionFunction())};_exports.uploadFilesToCourse=async function(courseId,sectionId,sectionNum,files){const handlerManager=await async function(courseId){if(void 0!==handlerManagers[courseId])return handlerManagers[courseId];const handlerManager=new HandlerManager(courseId);return await handlerManager.loadHandlers(),handlerManagers[courseId]=handlerManager,handlerManagers[courseId]}(courseId);await async function(courseId){var _courseEditor$get$max,_courseEditor$get;if(null!==errors)return;const maxbytestext=null!==(_courseEditor$get$max=null===(_courseEditor$get=(0,_courseeditor.getCourseEditor)(courseId).get("course"))||void 0===_courseEditor$get?void 0:_courseEditor$get.maxbytestext)&&void 0!==_courseEditor$get$max?_courseEditor$get$max:"0";errors={};const allStrings=[{key:"dndmaxbytes",component:"core_error",param:{size:maxbytestext}},{key:"dndread",component:"core_error"},{key:"dndupload",component:"core_error"},{key:"dndunkownfile",component:"core_error"}];window.console.log(allStrings);const loadedStrings=await(0,_str.get_strings)(allStrings);allStrings.forEach(((_ref,index)=>{let{key:key}=_ref;errors[key]=loadedStrings[index]}))}(courseId);for(let index=0;index.\n\n/**\n * The course file uploader.\n *\n * This module is used to upload files directly into the course.\n *\n * @module core_courseformat/local/courseeditor/fileuploader\n * @copyright 2022 Ferran Recio \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n/**\n * @typedef {Object} Handler\n * @property {String} extension the handled extension or * for any\n * @property {String} message the handler message\n * @property {String} module the module name\n */\n\nimport Config from 'core/config';\nimport ModalFactory from 'core/modal_factory';\nimport ModalEvents from 'core/modal_events';\nimport Templates from 'core/templates';\nimport {getFirst} from 'core/normalise';\nimport {prefetchStrings} from 'core/prefetch';\nimport {get_string as getString, get_strings as getStrings} from 'core/str';\nimport {getCourseEditor} from 'core_courseformat/courseeditor';\nimport {processMonitor} from 'core/process_monitor';\nimport {debounce} from 'core/utils';\n\n// Uploading url.\nconst UPLOADURL = Config.wwwroot + '/course/dndupload.php';\nconst DEBOUNCETIMER = 500;\nconst USERCANIGNOREFILESIZELIMITS = -1;\n\n/** @var {ProcessQueue} uploadQueue the internal uploadQueue instance. */\nlet uploadQueue = null;\n/** @var {Object} handlerManagers the courseId indexed loaded handler managers. */\nlet handlerManagers = {};\n/** @var {Map} courseUpdates the pending course sections updates. */\nlet courseUpdates = new Map();\n/** @var {Object} errors the error messages. */\nlet errors = null;\n\n// Load global strings.\nprefetchStrings('moodle', ['addresourceoractivity', 'upload']);\nprefetchStrings('core_error', ['dndmaxbytes', 'dndread', 'dndupload', 'dndunkownfile']);\n\n/**\n * Class to upload a file into the course.\n * @private\n */\nclass FileUploader {\n /**\n * Class constructor.\n *\n * @param {number} courseId the course id\n * @param {number} sectionId the section id\n * @param {number} sectionNum the section number\n * @param {File} fileInfo the file information object\n * @param {Handler} handler the file selected file handler\n */\n constructor(courseId, sectionId, sectionNum, fileInfo, handler) {\n this.courseId = courseId;\n this.sectionId = sectionId;\n this.sectionNum = sectionNum;\n this.fileInfo = fileInfo;\n this.handler = handler;\n }\n\n /**\n * Execute the file upload and update the state in the given process.\n *\n * @param {LoadingProcess} process the process to store the upload result\n */\n execute(process) {\n const fileInfo = this.fileInfo;\n const xhr = this._createXhrRequest(process);\n const formData = this._createUploadFormData();\n\n // Try reading the file to check it is not a folder, before sending it to the server.\n const reader = new FileReader();\n reader.onload = function() {\n // File was read OK - send it to the server.\n xhr.open(\"POST\", UPLOADURL, true);\n xhr.send(formData);\n };\n reader.onerror = function() {\n // Unable to read the file (it is probably a folder) - display an error message.\n process.setError(errors.dndread);\n };\n if (fileInfo.size > 0) {\n // If this is a non-empty file, try reading the first few bytes.\n // This will trigger reader.onerror() for folders and reader.onload() for ordinary, readable files.\n reader.readAsText(fileInfo.slice(0, 5));\n } else {\n // If you call slice() on a 0-byte folder, before calling readAsText, then Firefox triggers reader.onload(),\n // instead of reader.onerror().\n // So, for 0-byte files, just call readAsText on the whole file (and it will trigger load/error functions as expected).\n reader.readAsText(fileInfo);\n }\n }\n\n /**\n * Returns the bind version of execute function.\n *\n * This method is used to queue the process into a ProcessQueue instance.\n *\n * @returns {Function} the bind function to execute the process\n */\n getExecutionFunction() {\n return this.execute.bind(this);\n }\n\n /**\n * Generate a upload XHR file request.\n *\n * @param {LoadingProcess} process the current process\n * @return {XMLHttpRequest} the XHR request\n */\n _createXhrRequest(process) {\n const xhr = new XMLHttpRequest();\n // Update the progress bar as the file is uploaded.\n xhr.upload.addEventListener(\n 'progress',\n (event) => {\n if (event.lengthComputable) {\n const percent = Math.round((event.loaded * 100) / event.total);\n process.setPercentage(percent);\n }\n },\n false\n );\n // Wait for the AJAX call to complete.\n xhr.onreadystatechange = () => {\n if (xhr.readyState == 1) {\n // Add a 1% just to indicate that it is uploading.\n process.setPercentage(1);\n }\n // State 4 is DONE. Otherwise the connection is still ongoing.\n if (xhr.readyState != 4) {\n return;\n }\n if (xhr.status == 200) {\n var result = JSON.parse(xhr.responseText);\n if (result && result.error == 0) {\n // All OK.\n this._finishProcess(process);\n } else {\n process.setError(result.error);\n }\n } else {\n process.setError(errors.dndupload);\n }\n };\n return xhr;\n }\n\n /**\n * Upload a file into the course.\n *\n * @return {FormData|null} the new form data object\n */\n _createUploadFormData() {\n const formData = new FormData();\n try {\n formData.append('repo_upload_file', this.fileInfo);\n } catch (error) {\n throw Error(error.dndread);\n }\n formData.append('sesskey', Config.sesskey);\n formData.append('course', this.courseId);\n formData.append('section', this.sectionNum);\n formData.append('module', this.handler.module);\n formData.append('type', 'Files');\n return formData;\n }\n\n /**\n * Finishes the current process.\n * @param {LoadingProcess} process the process\n */\n _finishProcess(process) {\n addRefreshSection(this.courseId, this.sectionId);\n process.setPercentage(100);\n process.finish();\n }\n}\n\n/**\n * The file handler manager class.\n *\n * @private\n */\nclass HandlerManager {\n\n /** @var {Object} lastHandlers the last handlers selected per each file extension. */\n lastHandlers = {};\n\n /** @var {Handler[]|null} allHandlers all the available handlers. */\n allHandlers = null;\n\n /**\n * Class constructor.\n *\n * @param {Number} courseId\n */\n constructor(courseId) {\n this.courseId = courseId;\n this.lastUploadId = 0;\n this.courseEditor = getCourseEditor(courseId);\n if (!this.courseEditor) {\n throw Error('Unkown course editor');\n }\n this.maxbytes = this.courseEditor.get('course')?.maxbytes ?? 0;\n }\n\n /**\n * Load the course file handlers.\n */\n async loadHandlers() {\n this.allHandlers = await this.courseEditor.getFileHandlersPromise();\n }\n\n /**\n * Extract the file extension from a fileInfo.\n *\n * @param {File} fileInfo\n * @returns {String} the file extension or an empty string.\n */\n getFileExtension(fileInfo) {\n let extension = '';\n const dotpos = fileInfo.name.lastIndexOf('.');\n if (dotpos != -1) {\n extension = fileInfo.name.substring(dotpos + 1, fileInfo.name.length).toLowerCase();\n }\n return extension;\n }\n\n /**\n * Check if the file is valid.\n *\n * @param {File} fileInfo the file info\n */\n validateFile(fileInfo) {\n if (this.maxbytes !== USERCANIGNOREFILESIZELIMITS && fileInfo.size > this.maxbytes) {\n throw Error(errors.dndmaxbytes);\n }\n }\n\n /**\n * Get the file handlers of an specific file.\n *\n * @param {File} fileInfo the file indo\n * @return {Array} Array of handlers\n */\n filterHandlers(fileInfo) {\n const extension = this.getFileExtension(fileInfo);\n return this.allHandlers.filter(handler => handler.extension == '*' || handler.extension == extension);\n }\n\n /**\n * Get the Handler to upload a specific file.\n *\n * It will ask the used if more than one handler is available.\n *\n * @param {File} fileInfo the file info\n * @returns {Promise} the selected handler or null if the user cancel\n */\n async getFileHandler(fileInfo) {\n const fileHandlers = this.filterHandlers(fileInfo);\n if (fileHandlers.length == 0) {\n throw Error(errors.dndunkownfile);\n }\n let fileHandler = null;\n if (fileHandlers.length == 1) {\n fileHandler = fileHandlers[0];\n } else {\n fileHandler = await this.askHandlerToUser(fileHandlers, fileInfo);\n }\n return fileHandler;\n }\n\n /**\n * Ask the user to select a specific handler.\n *\n * @param {Handler[]} fileHandlers\n * @param {File} fileInfo the file info\n * @return {Promise} the selected handler\n */\n async askHandlerToUser(fileHandlers, fileInfo) {\n const extension = this.getFileExtension(fileInfo);\n // Build the modal parameters from the event data.\n const modalParams = {\n title: getString('addresourceoractivity', 'moodle'),\n body: Templates.render(\n 'core_courseformat/fileuploader',\n this.getModalData(\n fileHandlers,\n fileInfo,\n this.lastHandlers[extension] ?? null\n )\n ),\n type: ModalFactory.types.SAVE_CANCEL,\n saveButtonText: getString('upload', 'moodle'),\n };\n // Create the modal.\n const modal = await this.modalBodyRenderedPromise(modalParams);\n const selectedHandler = await this.modalUserAnswerPromise(modal, fileHandlers);\n // Cancel action.\n if (selectedHandler === null) {\n return null;\n }\n // Save last selected handler.\n this.lastHandlers[extension] = selectedHandler.module;\n return selectedHandler;\n }\n\n /**\n * Generated the modal template data.\n *\n * @param {Handler[]} fileHandlers\n * @param {File} fileInfo the file info\n * @param {String|null} defaultModule the default module if any\n * @return {Object} the modal template data.\n */\n getModalData(fileHandlers, fileInfo, defaultModule) {\n const data = {\n filename: fileInfo.name,\n uploadid: ++this.lastUploadId,\n handlers: [],\n };\n let hasDefault = false;\n fileHandlers.forEach((handler, index) => {\n const isDefault = (defaultModule == handler.module);\n data.handlers.push({\n ...handler,\n selected: isDefault,\n labelid: `fileuploader_${data.uploadid}`,\n value: index,\n });\n hasDefault = hasDefault || isDefault;\n });\n if (!hasDefault && data.handlers.length > 0) {\n const lastHandler = data.handlers.pop();\n lastHandler.selected = true;\n data.handlers.push(lastHandler);\n }\n return data;\n }\n\n /**\n * Get the user handler choice.\n *\n * Wait for the user answer in the modal and resolve with the selected index.\n *\n * @param {Modal} modal the modal instance\n * @param {Handler[]} fileHandlers the availabvle file handlers\n * @return {Promise} with the option selected by the user.\n */\n modalUserAnswerPromise(modal, fileHandlers) {\n const modalBody = getFirst(modal.getBody());\n return new Promise((resolve, reject) => {\n modal.getRoot().on(\n ModalEvents.save,\n event => {\n // Get the selected option.\n const index = modalBody.querySelector('input:checked').value;\n event.preventDefault();\n modal.destroy();\n if (!fileHandlers[index]) {\n reject('Invalid handler selected');\n }\n resolve(fileHandlers[index]);\n\n }\n );\n modal.getRoot().on(\n ModalEvents.cancel,\n () => {\n resolve(null);\n }\n );\n });\n }\n\n /**\n * Create a new modal and return a Promise to the body rendered.\n *\n * @param {Object} modalParams the modal params\n * @returns {Promise} the modal body rendered promise\n */\n modalBodyRenderedPromise(modalParams) {\n return new Promise((resolve, reject) => {\n ModalFactory.create(modalParams).then((modal) => {\n modal.setRemoveOnClose(true);\n // Handle body loading event.\n modal.getRoot().on(ModalEvents.bodyRendered, () => {\n resolve(modal);\n });\n // Configure some extra modal params.\n if (modalParams.saveButtonText !== undefined) {\n modal.setSaveButtonText(modalParams.saveButtonText);\n }\n modal.show();\n return;\n }).catch(() => {\n reject(`Cannot load modal content`);\n });\n });\n }\n}\n\n/**\n * Add a section to refresh.\n *\n * @param {number} courseId the course id\n * @param {number} sectionId the seciton id\n */\nfunction addRefreshSection(courseId, sectionId) {\n let refresh = courseUpdates.get(courseId);\n if (!refresh) {\n refresh = new Set();\n }\n refresh.add(sectionId);\n courseUpdates.set(courseId, refresh);\n refreshCourseEditors();\n}\n\n/**\n * Debounced processing all pending course refreshes.\n * @private\n */\nconst refreshCourseEditors = debounce(\n () => {\n const refreshes = courseUpdates;\n courseUpdates = new Map();\n refreshes.forEach((sectionIds, courseId) => {\n const courseEditor = getCourseEditor(courseId);\n if (!courseEditor) {\n return;\n }\n courseEditor.dispatch('sectionState', [...sectionIds]);\n });\n },\n DEBOUNCETIMER\n);\n\n/**\n * Load and return the course handler manager instance.\n *\n * @param {Number} courseId the course Id to load\n * @returns {Promise} promise of the the loaded handleManager\n */\nasync function loadCourseHandlerManager(courseId) {\n if (handlerManagers[courseId] !== undefined) {\n return handlerManagers[courseId];\n }\n try {\n const handlerManager = new HandlerManager(courseId);\n await handlerManager.loadHandlers();\n handlerManagers[courseId] = handlerManager;\n } catch (error) {\n throw error;\n }\n return handlerManagers[courseId];\n}\n\n/**\n * Load all the erros messages at once in the module \"errors\" variable.\n * @param {Number} courseId the course id\n */\nasync function loadErrorStrings(courseId) {\n if (errors !== null) {\n return;\n }\n const courseEditor = getCourseEditor(courseId);\n const maxbytestext = courseEditor.get('course')?.maxbytestext ?? '0';\n\n errors = {};\n const allStrings = [\n {key: 'dndmaxbytes', component: 'core_error', param: {size: maxbytestext}},\n {key: 'dndread', component: 'core_error'},\n {key: 'dndupload', component: 'core_error'},\n {key: 'dndunkownfile', component: 'core_error'},\n ];\n window.console.log(allStrings);\n const loadedStrings = await getStrings(allStrings);\n allStrings.forEach(({key}, index) => {\n errors[key] = loadedStrings[index];\n });\n}\n\n/**\n * Start a batch file uploading into the course.\n *\n * @private\n * @param {number} courseId the course id.\n * @param {number} sectionId the section id.\n * @param {number} sectionNum the section number.\n * @param {File} fileInfo the file information object\n * @param {HandlerManager} handlerManager the course handler manager\n */\nconst queueFileUpload = async function(courseId, sectionId, sectionNum, fileInfo, handlerManager) {\n let handler;\n uploadQueue = await processMonitor.createProcessQueue();\n try {\n handlerManager.validateFile(fileInfo);\n handler = await handlerManager.getFileHandler(fileInfo);\n } catch (error) {\n uploadQueue.addError(fileInfo.name, error.message);\n return;\n }\n // If we don't have a handler means the user cancel the upload.\n if (!handler) {\n return;\n }\n const fileProcessor = new FileUploader(courseId, sectionId, sectionNum, fileInfo, handler);\n uploadQueue.addPending(fileInfo.name, fileProcessor.getExecutionFunction());\n};\n\n/**\n * Upload a file to the course.\n *\n * This method will show any necesary modal to handle the request.\n *\n * @param {number} courseId the course id\n * @param {number} sectionId the section id\n * @param {number} sectionNum the section number\n * @param {Array} files and array of files\n */\nexport const uploadFilesToCourse = async function(courseId, sectionId, sectionNum, files) {\n // Get the course handlers.\n let handlerManager;\n try {\n handlerManager = await loadCourseHandlerManager(courseId);\n await loadErrorStrings(courseId);\n } catch (error) {\n throw error;\n }\n for (let index = 0; index < files.length; index++) {\n const fileInfo = files[index];\n await queueFileUpload(courseId, sectionId, sectionNum, fileInfo, handlerManager);\n }\n};\n"],"names":["UPLOADURL","Config","wwwroot","uploadQueue","handlerManagers","courseUpdates","Map","errors","FileUploader","constructor","courseId","sectionId","sectionNum","fileInfo","handler","execute","process","this","xhr","_createXhrRequest","formData","_createUploadFormData","reader","FileReader","onload","open","send","onerror","setError","dndread","size","readAsText","slice","getExecutionFunction","bind","XMLHttpRequest","upload","addEventListener","event","lengthComputable","percent","Math","round","loaded","total","setPercentage","onreadystatechange","readyState","status","result","JSON","parse","responseText","error","_finishProcess","dndupload","FormData","append","Error","sesskey","module","refresh","get","Set","add","set","refreshCourseEditors","addRefreshSection","finish","HandlerManager","lastUploadId","courseEditor","maxbytes","_this$courseEditor$ge2","allHandlers","getFileHandlersPromise","getFileExtension","extension","dotpos","name","lastIndexOf","substring","length","toLowerCase","validateFile","dndmaxbytes","filterHandlers","filter","fileHandlers","dndunkownfile","fileHandler","askHandlerToUser","modalParams","title","body","Templates","render","getModalData","lastHandlers","type","ModalFactory","types","SAVE_CANCEL","saveButtonText","modal","modalBodyRenderedPromise","selectedHandler","modalUserAnswerPromise","defaultModule","data","filename","uploadid","handlers","hasDefault","forEach","index","isDefault","push","selected","labelid","value","lastHandler","pop","modalBody","getBody","Promise","resolve","reject","getRoot","on","ModalEvents","save","querySelector","preventDefault","destroy","cancel","create","then","setRemoveOnClose","bodyRendered","undefined","setSaveButtonText","show","catch","refreshes","sectionIds","dispatch","queueFileUpload","async","handlerManager","processMonitor","createProcessQueue","getFileHandler","addError","message","fileProcessor","addPending","files","loadHandlers","loadCourseHandlerManager","maxbytestext","_courseEditor$get","allStrings","key","component","param","window","console","log","loadedStrings","loadErrorStrings"],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"fileuploader.min.js","sources":["../../../src/local/courseeditor/fileuploader.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * The course file uploader.\n *\n * This module is used to upload files directly into the course.\n *\n * @module core_courseformat/local/courseeditor/fileuploader\n * @copyright 2022 Ferran Recio \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n/**\n * @typedef {Object} Handler\n * @property {String} extension the handled extension or * for any\n * @property {String} message the handler message\n * @property {String} module the module name\n */\n\nimport Config from 'core/config';\nimport ModalFactory from 'core/modal_factory';\nimport ModalEvents from 'core/modal_events';\nimport Templates from 'core/templates';\nimport {getFirst} from 'core/normalise';\nimport {prefetchStrings} from 'core/prefetch';\nimport {get_string as getString, get_strings as getStrings} from 'core/str';\nimport {getCourseEditor} from 'core_courseformat/courseeditor';\nimport {processMonitor} from 'core/process_monitor';\nimport {debounce} from 'core/utils';\n\n// Uploading url.\nconst UPLOADURL = Config.wwwroot + '/course/dndupload.php';\nconst DEBOUNCETIMER = 500;\nconst USERCANIGNOREFILESIZELIMITS = -1;\n\n/** @var {ProcessQueue} uploadQueue the internal uploadQueue instance. */\nlet uploadQueue = null;\n/** @var {Object} handlerManagers the courseId indexed loaded handler managers. */\nlet handlerManagers = {};\n/** @var {Map} courseUpdates the pending course sections updates. */\nlet courseUpdates = new Map();\n/** @var {Object} errors the error messages. */\nlet errors = null;\n\n// Load global strings.\nprefetchStrings('moodle', ['addresourceoractivity', 'upload']);\nprefetchStrings('core_error', ['dndmaxbytes', 'dndread', 'dndupload', 'dndunkownfile']);\n\n/**\n * Class to upload a file into the course.\n * @private\n */\nclass FileUploader {\n /**\n * Class constructor.\n *\n * @param {number} courseId the course id\n * @param {number} sectionId the section id\n * @param {number} sectionNum the section number\n * @param {File} fileInfo the file information object\n * @param {Handler} handler the file selected file handler\n */\n constructor(courseId, sectionId, sectionNum, fileInfo, handler) {\n this.courseId = courseId;\n this.sectionId = sectionId;\n this.sectionNum = sectionNum;\n this.fileInfo = fileInfo;\n this.handler = handler;\n }\n\n /**\n * Execute the file upload and update the state in the given process.\n *\n * @param {LoadingProcess} process the process to store the upload result\n */\n execute(process) {\n const fileInfo = this.fileInfo;\n const xhr = this._createXhrRequest(process);\n const formData = this._createUploadFormData();\n\n // Try reading the file to check it is not a folder, before sending it to the server.\n const reader = new FileReader();\n reader.onload = function() {\n // File was read OK - send it to the server.\n xhr.open(\"POST\", UPLOADURL, true);\n xhr.send(formData);\n };\n reader.onerror = function() {\n // Unable to read the file (it is probably a folder) - display an error message.\n process.setError(errors.dndread);\n };\n if (fileInfo.size > 0) {\n // If this is a non-empty file, try reading the first few bytes.\n // This will trigger reader.onerror() for folders and reader.onload() for ordinary, readable files.\n reader.readAsText(fileInfo.slice(0, 5));\n } else {\n // If you call slice() on a 0-byte folder, before calling readAsText, then Firefox triggers reader.onload(),\n // instead of reader.onerror().\n // So, for 0-byte files, just call readAsText on the whole file (and it will trigger load/error functions as expected).\n reader.readAsText(fileInfo);\n }\n }\n\n /**\n * Returns the bind version of execute function.\n *\n * This method is used to queue the process into a ProcessQueue instance.\n *\n * @returns {Function} the bind function to execute the process\n */\n getExecutionFunction() {\n return this.execute.bind(this);\n }\n\n /**\n * Generate a upload XHR file request.\n *\n * @param {LoadingProcess} process the current process\n * @return {XMLHttpRequest} the XHR request\n */\n _createXhrRequest(process) {\n const xhr = new XMLHttpRequest();\n // Update the progress bar as the file is uploaded.\n xhr.upload.addEventListener(\n 'progress',\n (event) => {\n if (event.lengthComputable) {\n const percent = Math.round((event.loaded * 100) / event.total);\n process.setPercentage(percent);\n }\n },\n false\n );\n // Wait for the AJAX call to complete.\n xhr.onreadystatechange = () => {\n if (xhr.readyState == 1) {\n // Add a 1% just to indicate that it is uploading.\n process.setPercentage(1);\n }\n // State 4 is DONE. Otherwise the connection is still ongoing.\n if (xhr.readyState != 4) {\n return;\n }\n if (xhr.status == 200) {\n var result = JSON.parse(xhr.responseText);\n if (result && result.error == 0) {\n // All OK.\n this._finishProcess(process);\n } else {\n process.setError(result.error);\n }\n } else {\n process.setError(errors.dndupload);\n }\n };\n return xhr;\n }\n\n /**\n * Upload a file into the course.\n *\n * @return {FormData|null} the new form data object\n */\n _createUploadFormData() {\n const formData = new FormData();\n try {\n formData.append('repo_upload_file', this.fileInfo);\n } catch (error) {\n throw Error(error.dndread);\n }\n formData.append('sesskey', Config.sesskey);\n formData.append('course', this.courseId);\n formData.append('section', this.sectionNum);\n formData.append('module', this.handler.module);\n formData.append('type', 'Files');\n return formData;\n }\n\n /**\n * Finishes the current process.\n * @param {LoadingProcess} process the process\n */\n _finishProcess(process) {\n addRefreshSection(this.courseId, this.sectionId);\n process.setPercentage(100);\n process.finish();\n }\n}\n\n/**\n * The file handler manager class.\n *\n * @private\n */\nclass HandlerManager {\n\n /** @var {Object} lastHandlers the last handlers selected per each file extension. */\n lastHandlers = {};\n\n /** @var {Handler[]|null} allHandlers all the available handlers. */\n allHandlers = null;\n\n /**\n * Class constructor.\n *\n * @param {Number} courseId\n */\n constructor(courseId) {\n this.courseId = courseId;\n this.lastUploadId = 0;\n this.courseEditor = getCourseEditor(courseId);\n if (!this.courseEditor) {\n throw Error('Unkown course editor');\n }\n this.maxbytes = this.courseEditor.get('course')?.maxbytes ?? 0;\n }\n\n /**\n * Load the course file handlers.\n */\n async loadHandlers() {\n this.allHandlers = await this.courseEditor.getFileHandlersPromise();\n }\n\n /**\n * Extract the file extension from a fileInfo.\n *\n * @param {File} fileInfo\n * @returns {String} the file extension or an empty string.\n */\n getFileExtension(fileInfo) {\n let extension = '';\n const dotpos = fileInfo.name.lastIndexOf('.');\n if (dotpos != -1) {\n extension = fileInfo.name.substring(dotpos + 1, fileInfo.name.length).toLowerCase();\n }\n return extension;\n }\n\n /**\n * Check if the file is valid.\n *\n * @param {File} fileInfo the file info\n */\n validateFile(fileInfo) {\n if (this.maxbytes !== USERCANIGNOREFILESIZELIMITS && fileInfo.size > this.maxbytes) {\n throw Error(errors.dndmaxbytes);\n }\n }\n\n /**\n * Get the file handlers of an specific file.\n *\n * @param {File} fileInfo the file indo\n * @return {Array} Array of handlers\n */\n filterHandlers(fileInfo) {\n const extension = this.getFileExtension(fileInfo);\n return this.allHandlers.filter(handler => handler.extension == '*' || handler.extension == extension);\n }\n\n /**\n * Get the Handler to upload a specific file.\n *\n * It will ask the used if more than one handler is available.\n *\n * @param {File} fileInfo the file info\n * @returns {Promise} the selected handler or null if the user cancel\n */\n async getFileHandler(fileInfo) {\n const fileHandlers = this.filterHandlers(fileInfo);\n if (fileHandlers.length == 0) {\n throw Error(errors.dndunkownfile);\n }\n let fileHandler = null;\n if (fileHandlers.length == 1) {\n fileHandler = fileHandlers[0];\n } else {\n fileHandler = await this.askHandlerToUser(fileHandlers, fileInfo);\n }\n return fileHandler;\n }\n\n /**\n * Ask the user to select a specific handler.\n *\n * @param {Handler[]} fileHandlers\n * @param {File} fileInfo the file info\n * @return {Promise} the selected handler\n */\n async askHandlerToUser(fileHandlers, fileInfo) {\n const extension = this.getFileExtension(fileInfo);\n // Build the modal parameters from the event data.\n const modalParams = {\n title: getString('addresourceoractivity', 'moodle'),\n body: Templates.render(\n 'core_courseformat/fileuploader',\n this.getModalData(\n fileHandlers,\n fileInfo,\n this.lastHandlers[extension] ?? null\n )\n ),\n type: ModalFactory.types.SAVE_CANCEL,\n saveButtonText: getString('upload', 'moodle'),\n };\n // Create the modal.\n const modal = await this.modalBodyRenderedPromise(modalParams);\n const selectedHandler = await this.modalUserAnswerPromise(modal, fileHandlers);\n // Cancel action.\n if (selectedHandler === null) {\n return null;\n }\n // Save last selected handler.\n this.lastHandlers[extension] = selectedHandler.module;\n return selectedHandler;\n }\n\n /**\n * Generated the modal template data.\n *\n * @param {Handler[]} fileHandlers\n * @param {File} fileInfo the file info\n * @param {String|null} defaultModule the default module if any\n * @return {Object} the modal template data.\n */\n getModalData(fileHandlers, fileInfo, defaultModule) {\n const data = {\n filename: fileInfo.name,\n uploadid: ++this.lastUploadId,\n handlers: [],\n };\n let hasDefault = false;\n fileHandlers.forEach((handler, index) => {\n const isDefault = (defaultModule == handler.module);\n data.handlers.push({\n ...handler,\n selected: isDefault,\n labelid: `fileuploader_${data.uploadid}`,\n value: index,\n });\n hasDefault = hasDefault || isDefault;\n });\n if (!hasDefault && data.handlers.length > 0) {\n const lastHandler = data.handlers.pop();\n lastHandler.selected = true;\n data.handlers.push(lastHandler);\n }\n return data;\n }\n\n /**\n * Get the user handler choice.\n *\n * Wait for the user answer in the modal and resolve with the selected index.\n *\n * @param {Modal} modal the modal instance\n * @param {Handler[]} fileHandlers the availabvle file handlers\n * @return {Promise} with the option selected by the user.\n */\n modalUserAnswerPromise(modal, fileHandlers) {\n const modalBody = getFirst(modal.getBody());\n return new Promise((resolve, reject) => {\n modal.getRoot().on(\n ModalEvents.save,\n event => {\n // Get the selected option.\n const index = modalBody.querySelector('input:checked').value;\n event.preventDefault();\n modal.destroy();\n if (!fileHandlers[index]) {\n reject('Invalid handler selected');\n }\n resolve(fileHandlers[index]);\n\n }\n );\n modal.getRoot().on(\n ModalEvents.cancel,\n () => {\n resolve(null);\n }\n );\n });\n }\n\n /**\n * Create a new modal and return a Promise to the body rendered.\n *\n * @param {Object} modalParams the modal params\n * @returns {Promise} the modal body rendered promise\n */\n modalBodyRenderedPromise(modalParams) {\n return new Promise((resolve, reject) => {\n ModalFactory.create(modalParams).then((modal) => {\n modal.setRemoveOnClose(true);\n // Handle body loading event.\n modal.getRoot().on(ModalEvents.bodyRendered, () => {\n resolve(modal);\n });\n // Configure some extra modal params.\n if (modalParams.saveButtonText !== undefined) {\n modal.setSaveButtonText(modalParams.saveButtonText);\n }\n modal.show();\n return;\n }).catch(() => {\n reject(`Cannot load modal content`);\n });\n });\n }\n}\n\n/**\n * Add a section to refresh.\n *\n * @param {number} courseId the course id\n * @param {number} sectionId the seciton id\n */\nfunction addRefreshSection(courseId, sectionId) {\n let refresh = courseUpdates.get(courseId);\n if (!refresh) {\n refresh = new Set();\n }\n refresh.add(sectionId);\n courseUpdates.set(courseId, refresh);\n refreshCourseEditors();\n}\n\n/**\n * Debounced processing all pending course refreshes.\n * @private\n */\nconst refreshCourseEditors = debounce(\n () => {\n const refreshes = courseUpdates;\n courseUpdates = new Map();\n refreshes.forEach((sectionIds, courseId) => {\n const courseEditor = getCourseEditor(courseId);\n if (!courseEditor) {\n return;\n }\n courseEditor.dispatch('sectionState', [...sectionIds]);\n });\n },\n DEBOUNCETIMER\n);\n\n/**\n * Load and return the course handler manager instance.\n *\n * @param {Number} courseId the course Id to load\n * @returns {Promise} promise of the the loaded handleManager\n */\nasync function loadCourseHandlerManager(courseId) {\n if (handlerManagers[courseId] !== undefined) {\n return handlerManagers[courseId];\n }\n const handlerManager = new HandlerManager(courseId);\n await handlerManager.loadHandlers();\n handlerManagers[courseId] = handlerManager;\n return handlerManagers[courseId];\n}\n\n/**\n * Load all the erros messages at once in the module \"errors\" variable.\n * @param {Number} courseId the course id\n */\nasync function loadErrorStrings(courseId) {\n if (errors !== null) {\n return;\n }\n const courseEditor = getCourseEditor(courseId);\n const maxbytestext = courseEditor.get('course')?.maxbytestext ?? '0';\n\n errors = {};\n const allStrings = [\n {key: 'dndmaxbytes', component: 'core_error', param: {size: maxbytestext}},\n {key: 'dndread', component: 'core_error'},\n {key: 'dndupload', component: 'core_error'},\n {key: 'dndunkownfile', component: 'core_error'},\n ];\n window.console.log(allStrings);\n const loadedStrings = await getStrings(allStrings);\n allStrings.forEach(({key}, index) => {\n errors[key] = loadedStrings[index];\n });\n}\n\n/**\n * Start a batch file uploading into the course.\n *\n * @private\n * @param {number} courseId the course id.\n * @param {number} sectionId the section id.\n * @param {number} sectionNum the section number.\n * @param {File} fileInfo the file information object\n * @param {HandlerManager} handlerManager the course handler manager\n */\nconst queueFileUpload = async function(courseId, sectionId, sectionNum, fileInfo, handlerManager) {\n let handler;\n uploadQueue = await processMonitor.createProcessQueue();\n try {\n handlerManager.validateFile(fileInfo);\n handler = await handlerManager.getFileHandler(fileInfo);\n } catch (error) {\n uploadQueue.addError(fileInfo.name, error.message);\n return;\n }\n // If we don't have a handler means the user cancel the upload.\n if (!handler) {\n return;\n }\n const fileProcessor = new FileUploader(courseId, sectionId, sectionNum, fileInfo, handler);\n uploadQueue.addPending(fileInfo.name, fileProcessor.getExecutionFunction());\n};\n\n/**\n * Upload a file to the course.\n *\n * This method will show any necesary modal to handle the request.\n *\n * @param {number} courseId the course id\n * @param {number} sectionId the section id\n * @param {number} sectionNum the section number\n * @param {Array} files and array of files\n */\nexport const uploadFilesToCourse = async function(courseId, sectionId, sectionNum, files) {\n // Get the course handlers.\n const handlerManager = await loadCourseHandlerManager(courseId);\n await loadErrorStrings(courseId);\n for (let index = 0; index < files.length; index++) {\n const fileInfo = files[index];\n await queueFileUpload(courseId, sectionId, sectionNum, fileInfo, handlerManager);\n }\n};\n"],"names":["UPLOADURL","Config","wwwroot","uploadQueue","handlerManagers","courseUpdates","Map","errors","FileUploader","constructor","courseId","sectionId","sectionNum","fileInfo","handler","execute","process","this","xhr","_createXhrRequest","formData","_createUploadFormData","reader","FileReader","onload","open","send","onerror","setError","dndread","size","readAsText","slice","getExecutionFunction","bind","XMLHttpRequest","upload","addEventListener","event","lengthComputable","percent","Math","round","loaded","total","setPercentage","onreadystatechange","readyState","status","result","JSON","parse","responseText","error","_finishProcess","dndupload","FormData","append","Error","sesskey","module","refresh","get","Set","add","set","refreshCourseEditors","addRefreshSection","finish","HandlerManager","lastUploadId","courseEditor","maxbytes","_this$courseEditor$ge2","allHandlers","getFileHandlersPromise","getFileExtension","extension","dotpos","name","lastIndexOf","substring","length","toLowerCase","validateFile","dndmaxbytes","filterHandlers","filter","fileHandlers","dndunkownfile","fileHandler","askHandlerToUser","modalParams","title","body","Templates","render","getModalData","lastHandlers","type","ModalFactory","types","SAVE_CANCEL","saveButtonText","modal","modalBodyRenderedPromise","selectedHandler","modalUserAnswerPromise","defaultModule","data","filename","uploadid","handlers","hasDefault","forEach","index","isDefault","push","selected","labelid","value","lastHandler","pop","modalBody","getBody","Promise","resolve","reject","getRoot","on","ModalEvents","save","querySelector","preventDefault","destroy","cancel","create","then","setRemoveOnClose","bodyRendered","undefined","setSaveButtonText","show","catch","refreshes","sectionIds","dispatch","queueFileUpload","async","handlerManager","processMonitor","createProcessQueue","getFileHandler","addError","message","fileProcessor","addPending","files","loadHandlers","loadCourseHandlerManager","maxbytestext","_courseEditor$get","allStrings","key","component","param","window","console","log","loadedStrings","loadErrorStrings"],"mappings":"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"}
\ No newline at end of file
diff --git a/course/format/amd/build/local/courseindex/cm.min.js b/course/format/amd/build/local/courseindex/cm.min.js
index 45adeaafc39..eecb63244ab 100644
--- a/course/format/amd/build/local/courseindex/cm.min.js
+++ b/course/format/amd/build/local/courseindex/cm.min.js
@@ -8,6 +8,6 @@ define("core_courseformat/local/courseindex/cm",["exports","core_courseformat/lo
* @class core_courseformat/local/courseindex/cm
* @copyright 2021 Ferran Recio
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_dndcmitem=_interopRequireDefault(_dndcmitem),_templates=_interopRequireDefault(_templates),_prefetch=_interopRequireDefault(_prefetch),_config=_interopRequireDefault(_config);_prefetch.default.prefetchTemplate("core_courseformat/local/courseindex/cmcompletion");class Component extends _dndcmitem.default{create(){this.name="courseindex_cm",this.selectors={CM_NAME:"[data-for='cm_name']",CM_COMPLETION:"[data-for='cm_completion']"},this.classes={CMHIDDEN:"dimmed",LOCKED:"editinprogress",RESTRICTIONS:"restrictions",PAGEITEM:"pageitem",INDENTED:"indented"},this.id=this.element.dataset.id}static init(target,selectors){return new this({element:document.getElementById(target),selectors:selectors})}stateReady(state){this.configDragDrop(this.id);const cm=state.cm.get(this.id),course=state.course;this._refreshCompletion({state:state,element:cm});const anchor=new URL(window.location.href).hash.replace("#","");(window.location.href==cm.url||window.location.href.includes(course.baseurl)&&anchor==cm.anchor)&&(this.reactive.dispatch("setPageItem","cm",this.id),this.element.scrollIntoView({block:"center"})),_config.default.contextid!=_config.default.courseContextId&&_config.default.contextInstanceId==this.id&&(this.reactive.dispatch("setPageItem","cm",this.id,!0),this.element.scrollIntoView({block:"center"})),cm.uservisible&&cm.url||this.addEventListener(this.getElement(this.selectors.CM_NAME),"click",this._activityAnchor)}getWatchers(){return[{watch:"cm[".concat(this.id,"]:deleted"),handler:this.remove},{watch:"cm[".concat(this.id,"]:updated"),handler:this._refreshCm},{watch:"cm[".concat(this.id,"].completionstate:updated"),handler:this._refreshCompletion},{watch:"course.pageItem:updated",handler:this._refreshPageItem}]}_refreshCm(_ref){var _element$dragging,_element$locked,_element$hascmrestric;let{element:element}=_ref;this.element.classList.toggle(this.classes.CMHIDDEN,!element.visible),this.getElement(this.selectors.CM_NAME).innerHTML=element.name,this.element.classList.toggle(this.classes.DRAGGING,null!==(_element$dragging=element.dragging)&&void 0!==_element$dragging&&_element$dragging),this.element.classList.toggle(this.classes.LOCKED,null!==(_element$locked=element.locked)&&void 0!==_element$locked&&_element$locked),this.element.classList.toggle(this.classes.RESTRICTIONS,null!==(_element$hascmrestric=element.hascmrestrictions)&&void 0!==_element$hascmrestric&&_element$hascmrestric),this.element.classList.toggle(this.classes.INDENTED,element.indent),this.locked=element.locked}_refreshPageItem(_ref2){let{element:element}=_ref2;if(!element.pageItem)return;const isPageId="cm"==element.pageItem.type&&element.pageItem.id==this.id;this.element.classList.toggle(this.classes.PAGEITEM,isPageId),isPageId&&!this.reactive.isEditing&&this.element.scrollIntoView({block:"nearest"})}async _refreshCompletion(_ref3){let{state:state,element:element}=_ref3;if(this.reactive.isEditing||!element.istrackeduser)return;const completionElement=this.getElement(this.selectors.CM_COMPLETION);if(completionElement.dataset.value==element.completionstate)return;const data=this.reactive.getExporter().cmCompletion(state,element);try{const{html:html,js:js}=await _templates.default.renderForPromise("core_courseformat/local/courseindex/cmcompletion",data);_templates.default.replaceNode(completionElement,html,js)}catch(error){throw error}}_activityAnchor(event){const cm=this.reactive.get("cm",this.id);if(document.getElementById(cm.anchor))return void setTimeout((()=>{this.reactive.dispatch("setPageItem","cm",cm.id)}),50);const course=this.reactive.get("course"),section=this.reactive.get("section",cm.sectionid);if(!section)return;const url="".concat(course.baseurl,"§ion=").concat(section.number,"#").concat(cm.anchor);event.preventDefault(),window.location=url}}return _exports.default=Component,_exports.default}));
+ */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_dndcmitem=_interopRequireDefault(_dndcmitem),_templates=_interopRequireDefault(_templates),_prefetch=_interopRequireDefault(_prefetch),_config=_interopRequireDefault(_config);_prefetch.default.prefetchTemplate("core_courseformat/local/courseindex/cmcompletion");class Component extends _dndcmitem.default{create(){this.name="courseindex_cm",this.selectors={CM_NAME:"[data-for='cm_name']",CM_COMPLETION:"[data-for='cm_completion']"},this.classes={CMHIDDEN:"dimmed",LOCKED:"editinprogress",RESTRICTIONS:"restrictions",PAGEITEM:"pageitem",INDENTED:"indented"},this.id=this.element.dataset.id}static init(target,selectors){return new this({element:document.getElementById(target),selectors:selectors})}stateReady(state){this.configDragDrop(this.id);const cm=state.cm.get(this.id),course=state.course;this._refreshCompletion({state:state,element:cm});const anchor=new URL(window.location.href).hash.replace("#","");(window.location.href==cm.url||window.location.href.includes(course.baseurl)&&anchor==cm.anchor)&&(this.reactive.dispatch("setPageItem","cm",this.id),this.element.scrollIntoView({block:"center"})),_config.default.contextid!=_config.default.courseContextId&&_config.default.contextInstanceId==this.id&&(this.reactive.dispatch("setPageItem","cm",this.id,!0),this.element.scrollIntoView({block:"center"})),cm.uservisible&&cm.url||this.addEventListener(this.getElement(this.selectors.CM_NAME),"click",this._activityAnchor)}getWatchers(){return[{watch:"cm[".concat(this.id,"]:deleted"),handler:this.remove},{watch:"cm[".concat(this.id,"]:updated"),handler:this._refreshCm},{watch:"cm[".concat(this.id,"].completionstate:updated"),handler:this._refreshCompletion},{watch:"course.pageItem:updated",handler:this._refreshPageItem}]}_refreshCm(_ref){var _element$dragging,_element$locked,_element$hascmrestric;let{element:element}=_ref;this.element.classList.toggle(this.classes.CMHIDDEN,!element.visible),this.getElement(this.selectors.CM_NAME).innerHTML=element.name,this.element.classList.toggle(this.classes.DRAGGING,null!==(_element$dragging=element.dragging)&&void 0!==_element$dragging&&_element$dragging),this.element.classList.toggle(this.classes.LOCKED,null!==(_element$locked=element.locked)&&void 0!==_element$locked&&_element$locked),this.element.classList.toggle(this.classes.RESTRICTIONS,null!==(_element$hascmrestric=element.hascmrestrictions)&&void 0!==_element$hascmrestric&&_element$hascmrestric),this.element.classList.toggle(this.classes.INDENTED,element.indent),this.locked=element.locked}_refreshPageItem(_ref2){let{element:element}=_ref2;if(!element.pageItem)return;const isPageId="cm"==element.pageItem.type&&element.pageItem.id==this.id;this.element.classList.toggle(this.classes.PAGEITEM,isPageId),isPageId&&!this.reactive.isEditing&&this.element.scrollIntoView({block:"nearest"})}async _refreshCompletion(_ref3){let{state:state,element:element}=_ref3;if(this.reactive.isEditing||!element.istrackeduser)return;const completionElement=this.getElement(this.selectors.CM_COMPLETION);if(completionElement.dataset.value==element.completionstate)return;const data=this.reactive.getExporter().cmCompletion(state,element),{html:html,js:js}=await _templates.default.renderForPromise("core_courseformat/local/courseindex/cmcompletion",data);_templates.default.replaceNode(completionElement,html,js)}_activityAnchor(event){const cm=this.reactive.get("cm",this.id);if(document.getElementById(cm.anchor))return void setTimeout((()=>{this.reactive.dispatch("setPageItem","cm",cm.id)}),50);const course=this.reactive.get("course"),section=this.reactive.get("section",cm.sectionid);if(!section)return;const url="".concat(course.baseurl,"§ion=").concat(section.number,"#").concat(cm.anchor);event.preventDefault(),window.location=url}}return _exports.default=Component,_exports.default}));
//# sourceMappingURL=cm.min.js.map
\ No newline at end of file
diff --git a/course/format/amd/build/local/courseindex/cm.min.js.map b/course/format/amd/build/local/courseindex/cm.min.js.map
index d88f840507c..b61121fd712 100644
--- a/course/format/amd/build/local/courseindex/cm.min.js.map
+++ b/course/format/amd/build/local/courseindex/cm.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"cm.min.js","sources":["../../../src/local/courseindex/cm.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Course index cm component.\n *\n * This component is used to control specific course modules interactions like drag and drop.\n *\n * @module core_courseformat/local/courseindex/cm\n * @class core_courseformat/local/courseindex/cm\n * @copyright 2021 Ferran Recio \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport DndCmItem from 'core_courseformat/local/courseeditor/dndcmitem';\nimport Templates from 'core/templates';\nimport Prefetch from 'core/prefetch';\nimport Config from 'core/config';\n\n// Prefetch the completion icons template.\nconst completionTemplate = 'core_courseformat/local/courseindex/cmcompletion';\nPrefetch.prefetchTemplate(completionTemplate);\n\nexport default class Component extends DndCmItem {\n\n /**\n * Constructor hook.\n */\n create() {\n // Optional component name for debugging.\n this.name = 'courseindex_cm';\n // Default query selectors.\n this.selectors = {\n CM_NAME: `[data-for='cm_name']`,\n CM_COMPLETION: `[data-for='cm_completion']`,\n };\n // Default classes to toggle on refresh.\n this.classes = {\n CMHIDDEN: 'dimmed',\n LOCKED: 'editinprogress',\n RESTRICTIONS: 'restrictions',\n PAGEITEM: 'pageitem',\n INDENTED: 'indented',\n };\n // We need our id to watch specific events.\n this.id = this.element.dataset.id;\n }\n\n /**\n * Static method to create a component instance form the mustache template.\n *\n * @param {element|string} target the DOM main element or its ID\n * @param {object} selectors optional css selector overrides\n * @return {Component}\n */\n static init(target, selectors) {\n return new this({\n element: document.getElementById(target),\n selectors,\n });\n }\n\n /**\n * Initial state ready method.\n *\n * @param {Object} state the course state.\n */\n stateReady(state) {\n this.configDragDrop(this.id);\n const cm = state.cm.get(this.id);\n const course = state.course;\n // Refresh completion icon.\n this._refreshCompletion({\n state,\n element: cm,\n });\n const url = new URL(window.location.href);\n const anchor = url.hash.replace('#', '');\n // Check if the current url is the cm url.\n if (window.location.href == cm.url\n || (window.location.href.includes(course.baseurl) && anchor == cm.anchor)\n ) {\n this.reactive.dispatch('setPageItem', 'cm', this.id);\n this.element.scrollIntoView({block: \"center\"});\n }\n // Check if this we are displaying this activity page.\n if (Config.contextid != Config.courseContextId && Config.contextInstanceId == this.id) {\n this.reactive.dispatch('setPageItem', 'cm', this.id, true);\n this.element.scrollIntoView({block: \"center\"});\n }\n // Add anchor logic if the element is not user visible or the element hasn't URL.\n if (!cm.uservisible || !cm.url) {\n this.addEventListener(\n this.getElement(this.selectors.CM_NAME),\n 'click',\n this._activityAnchor,\n );\n }\n }\n\n /**\n * Component watchers.\n *\n * @returns {Array} of watchers\n */\n getWatchers() {\n return [\n {watch: `cm[${this.id}]:deleted`, handler: this.remove},\n {watch: `cm[${this.id}]:updated`, handler: this._refreshCm},\n {watch: `cm[${this.id}].completionstate:updated`, handler: this._refreshCompletion},\n {watch: `course.pageItem:updated`, handler: this._refreshPageItem},\n ];\n }\n\n /**\n * Update a course index cm using the state information.\n *\n * @param {object} param\n * @param {Object} param.element details the update details.\n */\n _refreshCm({element}) {\n // Update classes.\n this.element.classList.toggle(this.classes.CMHIDDEN, !element.visible);\n this.getElement(this.selectors.CM_NAME).innerHTML = element.name;\n this.element.classList.toggle(this.classes.DRAGGING, element.dragging ?? false);\n this.element.classList.toggle(this.classes.LOCKED, element.locked ?? false);\n this.element.classList.toggle(this.classes.RESTRICTIONS, element.hascmrestrictions ?? false);\n this.element.classList.toggle(this.classes.INDENTED, element.indent);\n this.locked = element.locked;\n }\n\n /**\n * Handle a page item update.\n *\n * @param {Object} details the update details\n * @param {Object} details.element the course state data.\n */\n _refreshPageItem({element}) {\n if (!element.pageItem) {\n return;\n }\n const isPageId = (element.pageItem.type == 'cm' && element.pageItem.id == this.id);\n this.element.classList.toggle(this.classes.PAGEITEM, isPageId);\n if (isPageId && !this.reactive.isEditing) {\n this.element.scrollIntoView({block: \"nearest\"});\n }\n }\n\n /**\n * Update the activity completion icon.\n *\n * @param {Object} details the update details\n * @param {Object} details.state the state data\n * @param {Object} details.element the element data\n */\n async _refreshCompletion({state, element}) {\n // No completion icons are displayed in edit mode.\n if (this.reactive.isEditing || !element.istrackeduser) {\n return;\n }\n // Check if the completion value has changed.\n const completionElement = this.getElement(this.selectors.CM_COMPLETION);\n if (completionElement.dataset.value == element.completionstate) {\n return;\n }\n\n // Collect section information from the state.\n const exporter = this.reactive.getExporter();\n const data = exporter.cmCompletion(state, element);\n\n try {\n const {html, js} = await Templates.renderForPromise(completionTemplate, data);\n Templates.replaceNode(completionElement, html, js);\n } catch (error) {\n throw error;\n }\n }\n\n /**\n * The activity anchor event.\n *\n * @param {Event} event\n */\n _activityAnchor(event) {\n const cm = this.reactive.get('cm', this.id);\n // If the user cannot access the element but the element is present in the page\n // the new url should be an anchor link.\n const element = document.getElementById(cm.anchor);\n if (element) {\n // Marc the element as page item once the event is handled.\n setTimeout(() => {\n this.reactive.dispatch('setPageItem', 'cm', cm.id);\n }, 50);\n return;\n }\n // If the element is not present in the page we need to go to the specific section.\n const course = this.reactive.get('course');\n const section = this.reactive.get('section', cm.sectionid);\n if (!section) {\n return;\n }\n const url = `${course.baseurl}§ion=${section.number}#${cm.anchor}`;\n event.preventDefault();\n window.location = url;\n }\n}\n"],"names":["prefetchTemplate","Component","DndCmItem","create","name","selectors","CM_NAME","CM_COMPLETION","classes","CMHIDDEN","LOCKED","RESTRICTIONS","PAGEITEM","INDENTED","id","this","element","dataset","target","document","getElementById","stateReady","state","configDragDrop","cm","get","course","_refreshCompletion","anchor","URL","window","location","href","hash","replace","url","includes","baseurl","reactive","dispatch","scrollIntoView","block","Config","contextid","courseContextId","contextInstanceId","uservisible","addEventListener","getElement","_activityAnchor","getWatchers","watch","handler","remove","_refreshCm","_refreshPageItem","classList","toggle","visible","innerHTML","DRAGGING","dragging","locked","hascmrestrictions","indent","pageItem","isPageId","type","isEditing","istrackeduser","completionElement","value","completionstate","data","getExporter","cmCompletion","html","js","Templates","renderForPromise","replaceNode","error","event","setTimeout","section","sectionid","number","preventDefault"],"mappings":";;;;;;;;;;uRAiCSA,iBADkB,0DAGNC,kBAAkBC,mBAKnCC,cAESC,KAAO,sBAEPC,UAAY,CACbC,+BACAC,iDAGCC,QAAU,CACXC,SAAU,SACVC,OAAQ,iBACRC,aAAc,eACdC,SAAU,WACVC,SAAU,iBAGTC,GAAKC,KAAKC,QAAQC,QAAQH,eAUvBI,OAAQb,kBACT,IAAIU,KAAK,CACZC,QAASG,SAASC,eAAeF,QACjCb,UAAAA,YASRgB,WAAWC,YACFC,eAAeR,KAAKD,UACnBU,GAAKF,MAAME,GAAGC,IAAIV,KAAKD,IACvBY,OAASJ,MAAMI,YAEhBC,mBAAmB,CACpBL,MAAAA,MACAN,QAASQ,WAGPI,OADM,IAAIC,IAAIC,OAAOC,SAASC,MACjBC,KAAKC,QAAQ,IAAK,KAEjCJ,OAAOC,SAASC,MAAQR,GAAGW,KACvBL,OAAOC,SAASC,KAAKI,SAASV,OAAOW,UAAYT,QAAUJ,GAAGI,eAE7DU,SAASC,SAAS,cAAe,KAAMxB,KAAKD,SAC5CE,QAAQwB,eAAe,CAACC,MAAO,YAGpCC,gBAAOC,WAAaD,gBAAOE,iBAAmBF,gBAAOG,mBAAqB9B,KAAKD,UAC1EwB,SAASC,SAAS,cAAe,KAAMxB,KAAKD,IAAI,QAChDE,QAAQwB,eAAe,CAACC,MAAO,YAGnCjB,GAAGsB,aAAgBtB,GAAGW,UAClBY,iBACDhC,KAAKiC,WAAWjC,KAAKV,UAAUC,SAC/B,QACAS,KAAKkC,iBAUjBC,oBACW,CACH,CAACC,mBAAapC,KAAKD,gBAAesC,QAASrC,KAAKsC,QAChD,CAACF,mBAAapC,KAAKD,gBAAesC,QAASrC,KAAKuC,YAChD,CAACH,mBAAapC,KAAKD,gCAA+BsC,QAASrC,KAAKY,oBAChE,CAACwB,gCAAkCC,QAASrC,KAAKwC,mBAUzDD,iFAAWtC,QAACA,mBAEHA,QAAQwC,UAAUC,OAAO1C,KAAKP,QAAQC,UAAWO,QAAQ0C,cACzDV,WAAWjC,KAAKV,UAAUC,SAASqD,UAAY3C,QAAQZ,UACvDY,QAAQwC,UAAUC,OAAO1C,KAAKP,QAAQoD,mCAAU5C,QAAQ6C,+DACxD7C,QAAQwC,UAAUC,OAAO1C,KAAKP,QAAQE,+BAAQM,QAAQ8C,yDACtD9C,QAAQwC,UAAUC,OAAO1C,KAAKP,QAAQG,2CAAcK,QAAQ+C,gFAC5D/C,QAAQwC,UAAUC,OAAO1C,KAAKP,QAAQK,SAAUG,QAAQgD,aACxDF,OAAS9C,QAAQ8C,OAS1BP,4BAAiBvC,QAACA,mBACTA,QAAQiD,sBAGPC,SAAqC,MAAzBlD,QAAQiD,SAASE,MAAgBnD,QAAQiD,SAASnD,IAAMC,KAAKD,QAC1EE,QAAQwC,UAAUC,OAAO1C,KAAKP,QAAQI,SAAUsD,UACjDA,WAAanD,KAAKuB,SAAS8B,gBACtBpD,QAAQwB,eAAe,CAACC,MAAO,gDAWnBnB,MAACA,MAADN,QAAQA,kBAEzBD,KAAKuB,SAAS8B,YAAcpD,QAAQqD,2BAIlCC,kBAAoBvD,KAAKiC,WAAWjC,KAAKV,UAAUE,kBACrD+D,kBAAkBrD,QAAQsD,OAASvD,QAAQwD,6BAMzCC,KADW1D,KAAKuB,SAASoC,cACTC,aAAarD,MAAON,mBAGhC4D,KAACA,KAADC,GAAOA,UAAYC,mBAAUC,iBAvJpB,mDAuJyDN,yBAC9DO,YAAYV,kBAAmBM,KAAMC,IACjD,MAAOI,aACCA,OASdhC,gBAAgBiC,aACN1D,GAAKT,KAAKuB,SAASb,IAAI,KAAMV,KAAKD,OAGxBK,SAASC,eAAeI,GAAGI,oBAGvCuD,YAAW,UACF7C,SAASC,SAAS,cAAe,KAAMf,GAAGV,MAChD,UAIDY,OAASX,KAAKuB,SAASb,IAAI,UAC3B2D,QAAUrE,KAAKuB,SAASb,IAAI,UAAWD,GAAG6D,eAC3CD,qBAGCjD,cAAST,OAAOW,4BAAmB+C,QAAQE,mBAAU9D,GAAGI,QAC9DsD,MAAMK,iBACNzD,OAAOC,SAAWI"}
\ No newline at end of file
+{"version":3,"file":"cm.min.js","sources":["../../../src/local/courseindex/cm.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Course index cm component.\n *\n * This component is used to control specific course modules interactions like drag and drop.\n *\n * @module core_courseformat/local/courseindex/cm\n * @class core_courseformat/local/courseindex/cm\n * @copyright 2021 Ferran Recio \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport DndCmItem from 'core_courseformat/local/courseeditor/dndcmitem';\nimport Templates from 'core/templates';\nimport Prefetch from 'core/prefetch';\nimport Config from 'core/config';\n\n// Prefetch the completion icons template.\nconst completionTemplate = 'core_courseformat/local/courseindex/cmcompletion';\nPrefetch.prefetchTemplate(completionTemplate);\n\nexport default class Component extends DndCmItem {\n\n /**\n * Constructor hook.\n */\n create() {\n // Optional component name for debugging.\n this.name = 'courseindex_cm';\n // Default query selectors.\n this.selectors = {\n CM_NAME: `[data-for='cm_name']`,\n CM_COMPLETION: `[data-for='cm_completion']`,\n };\n // Default classes to toggle on refresh.\n this.classes = {\n CMHIDDEN: 'dimmed',\n LOCKED: 'editinprogress',\n RESTRICTIONS: 'restrictions',\n PAGEITEM: 'pageitem',\n INDENTED: 'indented',\n };\n // We need our id to watch specific events.\n this.id = this.element.dataset.id;\n }\n\n /**\n * Static method to create a component instance form the mustache template.\n *\n * @param {element|string} target the DOM main element or its ID\n * @param {object} selectors optional css selector overrides\n * @return {Component}\n */\n static init(target, selectors) {\n return new this({\n element: document.getElementById(target),\n selectors,\n });\n }\n\n /**\n * Initial state ready method.\n *\n * @param {Object} state the course state.\n */\n stateReady(state) {\n this.configDragDrop(this.id);\n const cm = state.cm.get(this.id);\n const course = state.course;\n // Refresh completion icon.\n this._refreshCompletion({\n state,\n element: cm,\n });\n const url = new URL(window.location.href);\n const anchor = url.hash.replace('#', '');\n // Check if the current url is the cm url.\n if (window.location.href == cm.url\n || (window.location.href.includes(course.baseurl) && anchor == cm.anchor)\n ) {\n this.reactive.dispatch('setPageItem', 'cm', this.id);\n this.element.scrollIntoView({block: \"center\"});\n }\n // Check if this we are displaying this activity page.\n if (Config.contextid != Config.courseContextId && Config.contextInstanceId == this.id) {\n this.reactive.dispatch('setPageItem', 'cm', this.id, true);\n this.element.scrollIntoView({block: \"center\"});\n }\n // Add anchor logic if the element is not user visible or the element hasn't URL.\n if (!cm.uservisible || !cm.url) {\n this.addEventListener(\n this.getElement(this.selectors.CM_NAME),\n 'click',\n this._activityAnchor,\n );\n }\n }\n\n /**\n * Component watchers.\n *\n * @returns {Array} of watchers\n */\n getWatchers() {\n return [\n {watch: `cm[${this.id}]:deleted`, handler: this.remove},\n {watch: `cm[${this.id}]:updated`, handler: this._refreshCm},\n {watch: `cm[${this.id}].completionstate:updated`, handler: this._refreshCompletion},\n {watch: `course.pageItem:updated`, handler: this._refreshPageItem},\n ];\n }\n\n /**\n * Update a course index cm using the state information.\n *\n * @param {object} param\n * @param {Object} param.element details the update details.\n */\n _refreshCm({element}) {\n // Update classes.\n this.element.classList.toggle(this.classes.CMHIDDEN, !element.visible);\n this.getElement(this.selectors.CM_NAME).innerHTML = element.name;\n this.element.classList.toggle(this.classes.DRAGGING, element.dragging ?? false);\n this.element.classList.toggle(this.classes.LOCKED, element.locked ?? false);\n this.element.classList.toggle(this.classes.RESTRICTIONS, element.hascmrestrictions ?? false);\n this.element.classList.toggle(this.classes.INDENTED, element.indent);\n this.locked = element.locked;\n }\n\n /**\n * Handle a page item update.\n *\n * @param {Object} details the update details\n * @param {Object} details.element the course state data.\n */\n _refreshPageItem({element}) {\n if (!element.pageItem) {\n return;\n }\n const isPageId = (element.pageItem.type == 'cm' && element.pageItem.id == this.id);\n this.element.classList.toggle(this.classes.PAGEITEM, isPageId);\n if (isPageId && !this.reactive.isEditing) {\n this.element.scrollIntoView({block: \"nearest\"});\n }\n }\n\n /**\n * Update the activity completion icon.\n *\n * @param {Object} details the update details\n * @param {Object} details.state the state data\n * @param {Object} details.element the element data\n */\n async _refreshCompletion({state, element}) {\n // No completion icons are displayed in edit mode.\n if (this.reactive.isEditing || !element.istrackeduser) {\n return;\n }\n // Check if the completion value has changed.\n const completionElement = this.getElement(this.selectors.CM_COMPLETION);\n if (completionElement.dataset.value == element.completionstate) {\n return;\n }\n\n // Collect section information from the state.\n const exporter = this.reactive.getExporter();\n const data = exporter.cmCompletion(state, element);\n\n const {html, js} = await Templates.renderForPromise(completionTemplate, data);\n Templates.replaceNode(completionElement, html, js);\n }\n\n /**\n * The activity anchor event.\n *\n * @param {Event} event\n */\n _activityAnchor(event) {\n const cm = this.reactive.get('cm', this.id);\n // If the user cannot access the element but the element is present in the page\n // the new url should be an anchor link.\n const element = document.getElementById(cm.anchor);\n if (element) {\n // Marc the element as page item once the event is handled.\n setTimeout(() => {\n this.reactive.dispatch('setPageItem', 'cm', cm.id);\n }, 50);\n return;\n }\n // If the element is not present in the page we need to go to the specific section.\n const course = this.reactive.get('course');\n const section = this.reactive.get('section', cm.sectionid);\n if (!section) {\n return;\n }\n const url = `${course.baseurl}§ion=${section.number}#${cm.anchor}`;\n event.preventDefault();\n window.location = url;\n }\n}\n"],"names":["prefetchTemplate","Component","DndCmItem","create","name","selectors","CM_NAME","CM_COMPLETION","classes","CMHIDDEN","LOCKED","RESTRICTIONS","PAGEITEM","INDENTED","id","this","element","dataset","target","document","getElementById","stateReady","state","configDragDrop","cm","get","course","_refreshCompletion","anchor","URL","window","location","href","hash","replace","url","includes","baseurl","reactive","dispatch","scrollIntoView","block","Config","contextid","courseContextId","contextInstanceId","uservisible","addEventListener","getElement","_activityAnchor","getWatchers","watch","handler","remove","_refreshCm","_refreshPageItem","classList","toggle","visible","innerHTML","DRAGGING","dragging","locked","hascmrestrictions","indent","pageItem","isPageId","type","isEditing","istrackeduser","completionElement","value","completionstate","data","getExporter","cmCompletion","html","js","Templates","renderForPromise","replaceNode","event","setTimeout","section","sectionid","number","preventDefault"],"mappings":"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"}
\ No newline at end of file
diff --git a/course/format/amd/src/local/courseeditor/fileuploader.js b/course/format/amd/src/local/courseeditor/fileuploader.js
index 2c1e6c30bd1..278e2dd4e49 100644
--- a/course/format/amd/src/local/courseeditor/fileuploader.js
+++ b/course/format/amd/src/local/courseeditor/fileuploader.js
@@ -469,13 +469,9 @@ async function loadCourseHandlerManager(courseId) {
if (handlerManagers[courseId] !== undefined) {
return handlerManagers[courseId];
}
- try {
- const handlerManager = new HandlerManager(courseId);
- await handlerManager.loadHandlers();
- handlerManagers[courseId] = handlerManager;
- } catch (error) {
- throw error;
- }
+ const handlerManager = new HandlerManager(courseId);
+ await handlerManager.loadHandlers();
+ handlerManagers[courseId] = handlerManager;
return handlerManagers[courseId];
}
@@ -544,13 +540,8 @@ const queueFileUpload = async function(courseId, sectionId, sectionNum, fileInfo
*/
export const uploadFilesToCourse = async function(courseId, sectionId, sectionNum, files) {
// Get the course handlers.
- let handlerManager;
- try {
- handlerManager = await loadCourseHandlerManager(courseId);
- await loadErrorStrings(courseId);
- } catch (error) {
- throw error;
- }
+ const handlerManager = await loadCourseHandlerManager(courseId);
+ await loadErrorStrings(courseId);
for (let index = 0; index < files.length; index++) {
const fileInfo = files[index];
await queueFileUpload(courseId, sectionId, sectionNum, fileInfo, handlerManager);
diff --git a/course/format/amd/src/local/courseindex/cm.js b/course/format/amd/src/local/courseindex/cm.js
index 62a0dfef986..e33099923ae 100644
--- a/course/format/amd/src/local/courseindex/cm.js
+++ b/course/format/amd/src/local/courseindex/cm.js
@@ -180,12 +180,8 @@ export default class Component extends DndCmItem {
const exporter = this.reactive.getExporter();
const data = exporter.cmCompletion(state, element);
- try {
- const {html, js} = await Templates.renderForPromise(completionTemplate, data);
- Templates.replaceNode(completionElement, html, js);
- } catch (error) {
- throw error;
- }
+ const {html, js} = await Templates.renderForPromise(completionTemplate, data);
+ Templates.replaceNode(completionElement, html, js);
}
/**
diff --git a/lib/amd/build/local/aria/focuslock.min.js.map b/lib/amd/build/local/aria/focuslock.min.js.map
index f43298a4bae..4a579912cdb 100644
--- a/lib/amd/build/local/aria/focuslock.min.js.map
+++ b/lib/amd/build/local/aria/focuslock.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"focuslock.min.js","sources":["../../../src/local/aria/focuslock.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Tab locking system.\n *\n * This is based on code and examples provided in the ARIA specification.\n * https://www.w3.org/TR/wai-aria-practices/examples/dialog-modal/dialog.html\n *\n * @module core/local/aria/focuslock\n * @copyright 2019 Andrew Nicols \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Selectors from './selectors';\n\nconst lockRegionStack = [];\nconst initialFocusElementStack = [];\nconst finalFocusElementStack = [];\n\nlet lastFocus = null;\nlet ignoreFocusChanges = false;\nlet isLocked = false;\n\n/**\n * The lock handler.\n *\n * This is the item that does a majority of the work.\n * The overall logic from this comes from the examles in the WCAG guidelines.\n *\n * The general idea is that if the focus is not held within by an Element within the lock region, then we replace focus\n * on the first element in the lock region. If the first element is the element previously selected prior to the\n * user-initiated focus change, then instead jump to the last element in the lock region.\n *\n * This gives us a solution which supports focus locking of any kind, which loops in both directions, and which\n * prevents the lock from escaping the modal entirely.\n *\n * @method\n * @param {Event} event The event from the focus change\n */\nconst lockHandler = event => {\n if (ignoreFocusChanges) {\n // The focus change was made by an internal call to set focus.\n return;\n }\n\n // Find the current lock region.\n let lockRegion = getCurrentLockRegion();\n while (lockRegion) {\n if (document.contains(lockRegion)) {\n break;\n }\n\n // The lock region does not exist.\n // Perhaps it was removed without being untrapped.\n untrapFocus();\n lockRegion = getCurrentLockRegion();\n }\n if (!lockRegion) {\n return;\n }\n\n if (lockRegion.contains(event.target)) {\n lastFocus = event.target;\n } else {\n focusFirstDescendant();\n if (lastFocus == document.activeElement) {\n focusLastDescendant();\n }\n lastFocus = document.activeElement;\n }\n};\n\n/**\n * Focus the first descendant of the current lock region.\n *\n * @method\n * @returns {Bool} Whether a node was focused\n */\nconst focusFirstDescendant = () => {\n const lockRegion = getCurrentLockRegion();\n\n // Grab all elements in the lock region and attempt to focus each element until one is focused.\n // We can capture most of this in the query selector, but some cases may still reject focus.\n // For example, a disabled text area cannot be focused, and it becomes difficult to provide a decent query selector\n // to capture this.\n // The use of Array.some just ensures that we stop as soon as we have a successful focus.\n const focusableElements = Array.from(lockRegion.querySelectorAll(Selectors.elements.focusable));\n\n // The lock region itself may be focusable. This is particularly true on Moodle's older dialogues.\n // We must include it in the calculation of descendants to ensure that looping works correctly.\n focusableElements.unshift(lockRegion);\n return focusableElements.some(focusableElement => attemptFocus(focusableElement));\n};\n\n/**\n * Focus the last descendant of the current lock region.\n *\n * @method\n * @returns {Bool} Whether a node was focused\n */\nconst focusLastDescendant = () => {\n const lockRegion = getCurrentLockRegion();\n\n // Grab all elements in the lock region, reverse them, and attempt to focus each element until one is focused.\n // We can capture most of this in the query selector, but some cases may still reject focus.\n // For example, a disabled text area cannot be focused, and it becomes difficult to provide a decent query selector\n // to capture this.\n // The use of Array.some just ensures that we stop as soon as we have a successful focus.\n const focusableElements = Array.from(lockRegion.querySelectorAll(Selectors.elements.focusable)).reverse();\n\n // The lock region itself may be focusable. This is particularly true on Moodle's older dialogues.\n // We must include it in the calculation of descendants to ensure that looping works correctly.\n focusableElements.push(lockRegion);\n return focusableElements.some(focusableElement => attemptFocus(focusableElement));\n};\n\n/**\n * Check whether the supplied focusTarget is actually focusable.\n * There are cases where a normally focusable element can reject focus.\n *\n * Note: This example is a wholesale copy of the WCAG example.\n *\n * @method\n * @param {HTMLElement} focusTarget\n * @returns {Bool}\n */\nconst isFocusable = focusTarget => {\n if (focusTarget.tabIndex > 0 || (focusTarget.tabIndex === 0 && focusTarget.getAttribute('tabIndex') !== null)) {\n return true;\n }\n\n if (focusTarget.disabled) {\n return false;\n }\n\n switch (focusTarget.nodeName) {\n case 'A':\n return !!focusTarget.href && focusTarget.rel != 'ignore';\n case 'INPUT':\n return focusTarget.type != 'hidden' && focusTarget.type != 'file';\n case 'BUTTON':\n case 'SELECT':\n case 'TEXTAREA':\n return true;\n default:\n return false;\n }\n};\n\n/**\n * Attempt to focus the supplied focusTarget.\n *\n * Note: This example is a heavily inspired by the WCAG example.\n *\n * @method\n * @param {HTMLElement} focusTarget\n * @returns {Bool} Whether focus was successful o rnot.\n */\nconst attemptFocus = focusTarget => {\n if (!isFocusable(focusTarget)) {\n return false;\n }\n\n // The ignoreFocusChanges variable prevents the focus event handler from interfering and entering a fight with itself.\n ignoreFocusChanges = true;\n\n try {\n focusTarget.focus();\n } catch (e) {\n // Ignore failures. We will just try to focus the next element in the list.\n // eslint-disable-line\n }\n\n ignoreFocusChanges = false;\n\n // If focus was successful the activeElement will be the one we focused.\n return (document.activeElement === focusTarget);\n};\n\n/**\n * Get the current lock region from the top of the stack.\n *\n * @method\n * @returns {HTMLElement}\n */\nconst getCurrentLockRegion = () => {\n return lockRegionStack[lockRegionStack.length - 1];\n};\n\n/**\n * Add a new lock region to the stack.\n *\n * @method\n * @param {HTMLElement} newLockRegion\n */\nconst addLockRegionToStack = newLockRegion => {\n if (newLockRegion === getCurrentLockRegion()) {\n return;\n }\n\n lockRegionStack.push(newLockRegion);\n const currentLockRegion = getCurrentLockRegion();\n\n // Append an empty div which can be focused just outside of the item locked.\n // This locks tab focus to within the tab region, and does not allow it to extend back into the window by\n // guaranteeing the existence of a tabable item after the lock region which can be focused but which will be caught\n // by the handler.\n const element = document.createElement('div');\n element.tabIndex = 0;\n element.style.position = 'fixed';\n element.style.top = 0;\n element.style.left = 0;\n\n const initialNode = element.cloneNode();\n currentLockRegion.parentNode.insertBefore(initialNode, currentLockRegion);\n initialFocusElementStack.push(initialNode);\n\n const finalNode = element.cloneNode();\n currentLockRegion.parentNode.insertBefore(finalNode, currentLockRegion.nextSibling);\n finalFocusElementStack.push(finalNode);\n};\n\n/**\n * Remove the top lock region from the stack.\n *\n * @method\n */\nconst removeLastLockRegionFromStack = () => {\n // Take the top element off the stack, and replce the current lockRegion value.\n lockRegionStack.pop();\n\n const finalNode = finalFocusElementStack.pop();\n if (finalNode) {\n // The final focus element may have been removed if it was part of a parent item.\n finalNode.remove();\n }\n\n const initialNode = initialFocusElementStack.pop();\n if (initialNode) {\n // The initial focus element may have been removed if it was part of a parent item.\n initialNode.remove();\n }\n};\n\n/**\n * Whether any region is left in the stack.\n *\n * @return {Bool}\n */\nconst hasTrappedRegionsInStack = () => {\n return !!lockRegionStack.length;\n};\n\n/**\n * Start trapping the focus and lock it to the specified newLockRegion.\n *\n * @method\n * @param {HTMLElement} newLockRegion The container to lock focus to\n */\nexport const trapFocus = newLockRegion => {\n // Update the lock region stack.\n // This allows us to support nesting.\n addLockRegionToStack(newLockRegion);\n\n if (!isLocked) {\n // Add the focus handler.\n document.addEventListener('focus', lockHandler, true);\n }\n\n // Attempt to focus on the first item in the lock region.\n if (!focusFirstDescendant()) {\n const currentLockRegion = getCurrentLockRegion();\n\n // No focusable descendants found in the region yet.\n // This can happen when the region is locked before content is generated.\n // Focus on the region itself for now.\n const originalRegionTabIndex = currentLockRegion.tabIndex;\n currentLockRegion.tabIndex = 0;\n attemptFocus(currentLockRegion);\n currentLockRegion.tabIndex = originalRegionTabIndex;\n }\n\n // Keep track of the last item focused.\n lastFocus = document.activeElement;\n\n isLocked = true;\n};\n\n/**\n * Stop trapping the focus.\n *\n * @method\n */\nexport const untrapFocus = () => {\n // Remove the top region from the stack.\n removeLastLockRegionFromStack();\n\n if (hasTrappedRegionsInStack()) {\n // The focus manager still has items in the stack.\n return;\n }\n\n document.removeEventListener('focus', lockHandler, true);\n\n lastFocus = null;\n ignoreFocusChanges = false;\n isLocked = false;\n};\n"],"names":["lockRegionStack","initialFocusElementStack","finalFocusElementStack","lastFocus","ignoreFocusChanges","isLocked","lockHandler","event","lockRegion","getCurrentLockRegion","document","contains","untrapFocus","target","focusFirstDescendant","activeElement","focusLastDescendant","focusableElements","Array","from","querySelectorAll","Selectors","elements","focusable","unshift","some","focusableElement","attemptFocus","reverse","push","focusTarget","tabIndex","getAttribute","disabled","nodeName","href","rel","type","isFocusable","focus","e","length","newLockRegion","currentLockRegion","element","createElement","style","position","top","left","initialNode","cloneNode","parentNode","insertBefore","finalNode","nextSibling","addLockRegionToStack","addEventListener","originalRegionTabIndex","pop","remove","removeLastLockRegionFromStack","removeEventListener"],"mappings":";;;;;;;;;;gLA2BMA,gBAAkB,GAClBC,yBAA2B,GAC3BC,uBAAyB,OAE3BC,UAAY,KACZC,oBAAqB,EACrBC,UAAW,QAkBTC,YAAcC,WACZH,8BAMAI,WAAaC,4BACVD,aACCE,SAASC,SAASH,aAMtBI,cACAJ,WAAaC,uBAEZD,aAIDA,WAAWG,SAASJ,MAAMM,QAC1BV,UAAYI,MAAMM,QAElBC,uBACIX,WAAaO,SAASK,eACtBC,sBAEJb,UAAYO,SAASK,iBAUvBD,qBAAuB,WACnBN,WAAaC,uBAObQ,kBAAoBC,MAAMC,KAAKX,WAAWY,iBAAiBC,mBAAUC,SAASC,mBAIpFN,kBAAkBO,QAAQhB,YACnBS,kBAAkBQ,MAAKC,kBAAoBC,aAAaD,qBAS7DV,oBAAsB,WAClBR,WAAaC,uBAObQ,kBAAoBC,MAAMC,KAAKX,WAAWY,iBAAiBC,mBAAUC,SAASC,YAAYK,iBAIhGX,kBAAkBY,KAAKrB,YAChBS,kBAAkBQ,MAAKC,kBAAoBC,aAAaD,qBA6C7DC,aAAeG,kBAhCDA,CAAAA,iBACZA,YAAYC,SAAW,GAA+B,IAAzBD,YAAYC,UAA2D,OAAzCD,YAAYE,aAAa,mBAC7E,KAGPF,YAAYG,gBACL,SAGHH,YAAYI,cACX,YACQJ,YAAYK,MAA2B,UAAnBL,YAAYM,QACxC,cAC0B,UAApBN,YAAYO,MAAwC,QAApBP,YAAYO,SAClD,aACA,aACA,kBACM,iBAEA,IAcVC,CAAYR,oBACN,EAIX1B,oBAAqB,MAGjB0B,YAAYS,QACd,MAAOC,WAKTpC,oBAAqB,EAGbM,SAASK,gBAAkBe,aASjCrB,qBAAuB,IAClBT,gBAAgBA,gBAAgByC,OAAS,sBAyE3BC,mBAhEIA,CAAAA,mBACrBA,gBAAkBjC,8BAItBT,gBAAgB6B,KAAKa,qBACfC,kBAAoBlC,uBAMpBmC,QAAUlC,SAASmC,cAAc,OACvCD,QAAQb,SAAW,EACnBa,QAAQE,MAAMC,SAAW,QACzBH,QAAQE,MAAME,IAAM,EACpBJ,QAAQE,MAAMG,KAAO,QAEfC,YAAcN,QAAQO,YAC5BR,kBAAkBS,WAAWC,aAAaH,YAAaP,mBACvD1C,yBAAyB4B,KAAKqB,mBAExBI,UAAYV,QAAQO,YAC1BR,kBAAkBS,WAAWC,aAAaC,UAAWX,kBAAkBY,aACvErD,uBAAuB2B,KAAKyB,YA2C5BE,CAAqBd,eAEhBrC,UAEDK,SAAS+C,iBAAiB,QAASnD,aAAa,IAI/CQ,uBAAwB,OACnB6B,kBAAoBlC,uBAKpBiD,uBAAyBf,kBAAkBZ,SACjDY,kBAAkBZ,SAAW,EAC7BJ,aAAagB,mBACbA,kBAAkBZ,SAAW2B,uBAIjCvD,UAAYO,SAASK,cAErBV,UAAW,SAQFO,YAAc,KAlEW,MAElCZ,gBAAgB2D,YAEVL,UAAYpD,uBAAuByD,MACrCL,WAEAA,UAAUM,eAGRV,YAAcjD,yBAAyB0D,MACzCT,aAEAA,YAAYU,UAuDhBC,GA7CS7D,gBAAgByC,SAoDzB/B,SAASoD,oBAAoB,QAASxD,aAAa,GAEnDH,UAAY,KACZC,oBAAqB,EACrBC,UAAW"}
\ No newline at end of file
+{"version":3,"file":"focuslock.min.js","sources":["../../../src/local/aria/focuslock.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Tab locking system.\n *\n * This is based on code and examples provided in the ARIA specification.\n * https://www.w3.org/TR/wai-aria-practices/examples/dialog-modal/dialog.html\n *\n * @module core/local/aria/focuslock\n * @copyright 2019 Andrew Nicols \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Selectors from './selectors';\n\nconst lockRegionStack = [];\nconst initialFocusElementStack = [];\nconst finalFocusElementStack = [];\n\nlet lastFocus = null;\nlet ignoreFocusChanges = false;\nlet isLocked = false;\n\n/**\n * The lock handler.\n *\n * This is the item that does a majority of the work.\n * The overall logic from this comes from the examles in the WCAG guidelines.\n *\n * The general idea is that if the focus is not held within by an Element within the lock region, then we replace focus\n * on the first element in the lock region. If the first element is the element previously selected prior to the\n * user-initiated focus change, then instead jump to the last element in the lock region.\n *\n * This gives us a solution which supports focus locking of any kind, which loops in both directions, and which\n * prevents the lock from escaping the modal entirely.\n *\n * @method\n * @param {Event} event The event from the focus change\n */\nconst lockHandler = event => {\n if (ignoreFocusChanges) {\n // The focus change was made by an internal call to set focus.\n return;\n }\n\n // Find the current lock region.\n let lockRegion = getCurrentLockRegion();\n while (lockRegion) {\n if (document.contains(lockRegion)) {\n break;\n }\n\n // The lock region does not exist.\n // Perhaps it was removed without being untrapped.\n untrapFocus();\n lockRegion = getCurrentLockRegion();\n }\n if (!lockRegion) {\n return;\n }\n\n if (lockRegion.contains(event.target)) {\n lastFocus = event.target;\n } else {\n focusFirstDescendant();\n if (lastFocus == document.activeElement) {\n focusLastDescendant();\n }\n lastFocus = document.activeElement;\n }\n};\n\n/**\n * Focus the first descendant of the current lock region.\n *\n * @method\n * @returns {Bool} Whether a node was focused\n */\nconst focusFirstDescendant = () => {\n const lockRegion = getCurrentLockRegion();\n\n // Grab all elements in the lock region and attempt to focus each element until one is focused.\n // We can capture most of this in the query selector, but some cases may still reject focus.\n // For example, a disabled text area cannot be focused, and it becomes difficult to provide a decent query selector\n // to capture this.\n // The use of Array.some just ensures that we stop as soon as we have a successful focus.\n const focusableElements = Array.from(lockRegion.querySelectorAll(Selectors.elements.focusable));\n\n // The lock region itself may be focusable. This is particularly true on Moodle's older dialogues.\n // We must include it in the calculation of descendants to ensure that looping works correctly.\n focusableElements.unshift(lockRegion);\n return focusableElements.some(focusableElement => attemptFocus(focusableElement));\n};\n\n/**\n * Focus the last descendant of the current lock region.\n *\n * @method\n * @returns {Bool} Whether a node was focused\n */\nconst focusLastDescendant = () => {\n const lockRegion = getCurrentLockRegion();\n\n // Grab all elements in the lock region, reverse them, and attempt to focus each element until one is focused.\n // We can capture most of this in the query selector, but some cases may still reject focus.\n // For example, a disabled text area cannot be focused, and it becomes difficult to provide a decent query selector\n // to capture this.\n // The use of Array.some just ensures that we stop as soon as we have a successful focus.\n const focusableElements = Array.from(lockRegion.querySelectorAll(Selectors.elements.focusable)).reverse();\n\n // The lock region itself may be focusable. This is particularly true on Moodle's older dialogues.\n // We must include it in the calculation of descendants to ensure that looping works correctly.\n focusableElements.push(lockRegion);\n return focusableElements.some(focusableElement => attemptFocus(focusableElement));\n};\n\n/**\n * Check whether the supplied focusTarget is actually focusable.\n * There are cases where a normally focusable element can reject focus.\n *\n * Note: This example is a wholesale copy of the WCAG example.\n *\n * @method\n * @param {HTMLElement} focusTarget\n * @returns {Bool}\n */\nconst isFocusable = focusTarget => {\n if (focusTarget.tabIndex > 0 || (focusTarget.tabIndex === 0 && focusTarget.getAttribute('tabIndex') !== null)) {\n return true;\n }\n\n if (focusTarget.disabled) {\n return false;\n }\n\n switch (focusTarget.nodeName) {\n case 'A':\n return !!focusTarget.href && focusTarget.rel != 'ignore';\n case 'INPUT':\n return focusTarget.type != 'hidden' && focusTarget.type != 'file';\n case 'BUTTON':\n case 'SELECT':\n case 'TEXTAREA':\n return true;\n default:\n return false;\n }\n};\n\n/**\n * Attempt to focus the supplied focusTarget.\n *\n * Note: This example is a heavily inspired by the WCAG example.\n *\n * @method\n * @param {HTMLElement} focusTarget\n * @returns {Bool} Whether focus was successful o rnot.\n */\nconst attemptFocus = focusTarget => {\n if (!isFocusable(focusTarget)) {\n return false;\n }\n\n // The ignoreFocusChanges variable prevents the focus event handler from interfering and entering a fight with itself.\n ignoreFocusChanges = true;\n\n try {\n focusTarget.focus();\n } catch (e) {\n // Ignore failures. We will just try to focus the next element in the list.\n }\n\n ignoreFocusChanges = false;\n\n // If focus was successful the activeElement will be the one we focused.\n return (document.activeElement === focusTarget);\n};\n\n/**\n * Get the current lock region from the top of the stack.\n *\n * @method\n * @returns {HTMLElement}\n */\nconst getCurrentLockRegion = () => {\n return lockRegionStack[lockRegionStack.length - 1];\n};\n\n/**\n * Add a new lock region to the stack.\n *\n * @method\n * @param {HTMLElement} newLockRegion\n */\nconst addLockRegionToStack = newLockRegion => {\n if (newLockRegion === getCurrentLockRegion()) {\n return;\n }\n\n lockRegionStack.push(newLockRegion);\n const currentLockRegion = getCurrentLockRegion();\n\n // Append an empty div which can be focused just outside of the item locked.\n // This locks tab focus to within the tab region, and does not allow it to extend back into the window by\n // guaranteeing the existence of a tabable item after the lock region which can be focused but which will be caught\n // by the handler.\n const element = document.createElement('div');\n element.tabIndex = 0;\n element.style.position = 'fixed';\n element.style.top = 0;\n element.style.left = 0;\n\n const initialNode = element.cloneNode();\n currentLockRegion.parentNode.insertBefore(initialNode, currentLockRegion);\n initialFocusElementStack.push(initialNode);\n\n const finalNode = element.cloneNode();\n currentLockRegion.parentNode.insertBefore(finalNode, currentLockRegion.nextSibling);\n finalFocusElementStack.push(finalNode);\n};\n\n/**\n * Remove the top lock region from the stack.\n *\n * @method\n */\nconst removeLastLockRegionFromStack = () => {\n // Take the top element off the stack, and replce the current lockRegion value.\n lockRegionStack.pop();\n\n const finalNode = finalFocusElementStack.pop();\n if (finalNode) {\n // The final focus element may have been removed if it was part of a parent item.\n finalNode.remove();\n }\n\n const initialNode = initialFocusElementStack.pop();\n if (initialNode) {\n // The initial focus element may have been removed if it was part of a parent item.\n initialNode.remove();\n }\n};\n\n/**\n * Whether any region is left in the stack.\n *\n * @return {Bool}\n */\nconst hasTrappedRegionsInStack = () => {\n return !!lockRegionStack.length;\n};\n\n/**\n * Start trapping the focus and lock it to the specified newLockRegion.\n *\n * @method\n * @param {HTMLElement} newLockRegion The container to lock focus to\n */\nexport const trapFocus = newLockRegion => {\n // Update the lock region stack.\n // This allows us to support nesting.\n addLockRegionToStack(newLockRegion);\n\n if (!isLocked) {\n // Add the focus handler.\n document.addEventListener('focus', lockHandler, true);\n }\n\n // Attempt to focus on the first item in the lock region.\n if (!focusFirstDescendant()) {\n const currentLockRegion = getCurrentLockRegion();\n\n // No focusable descendants found in the region yet.\n // This can happen when the region is locked before content is generated.\n // Focus on the region itself for now.\n const originalRegionTabIndex = currentLockRegion.tabIndex;\n currentLockRegion.tabIndex = 0;\n attemptFocus(currentLockRegion);\n currentLockRegion.tabIndex = originalRegionTabIndex;\n }\n\n // Keep track of the last item focused.\n lastFocus = document.activeElement;\n\n isLocked = true;\n};\n\n/**\n * Stop trapping the focus.\n *\n * @method\n */\nexport const untrapFocus = () => {\n // Remove the top region from the stack.\n removeLastLockRegionFromStack();\n\n if (hasTrappedRegionsInStack()) {\n // The focus manager still has items in the stack.\n return;\n }\n\n document.removeEventListener('focus', lockHandler, true);\n\n lastFocus = null;\n ignoreFocusChanges = false;\n isLocked = false;\n};\n"],"names":["lockRegionStack","initialFocusElementStack","finalFocusElementStack","lastFocus","ignoreFocusChanges","isLocked","lockHandler","event","lockRegion","getCurrentLockRegion","document","contains","untrapFocus","target","focusFirstDescendant","activeElement","focusLastDescendant","focusableElements","Array","from","querySelectorAll","Selectors","elements","focusable","unshift","some","focusableElement","attemptFocus","reverse","push","focusTarget","tabIndex","getAttribute","disabled","nodeName","href","rel","type","isFocusable","focus","e","length","newLockRegion","currentLockRegion","element","createElement","style","position","top","left","initialNode","cloneNode","parentNode","insertBefore","finalNode","nextSibling","addLockRegionToStack","addEventListener","originalRegionTabIndex","pop","remove","removeLastLockRegionFromStack","removeEventListener"],"mappings":";;;;;;;;;;gLA2BMA,gBAAkB,GAClBC,yBAA2B,GAC3BC,uBAAyB,OAE3BC,UAAY,KACZC,oBAAqB,EACrBC,UAAW,QAkBTC,YAAcC,WACZH,8BAMAI,WAAaC,4BACVD,aACCE,SAASC,SAASH,aAMtBI,cACAJ,WAAaC,uBAEZD,aAIDA,WAAWG,SAASJ,MAAMM,QAC1BV,UAAYI,MAAMM,QAElBC,uBACIX,WAAaO,SAASK,eACtBC,sBAEJb,UAAYO,SAASK,iBAUvBD,qBAAuB,WACnBN,WAAaC,uBAObQ,kBAAoBC,MAAMC,KAAKX,WAAWY,iBAAiBC,mBAAUC,SAASC,mBAIpFN,kBAAkBO,QAAQhB,YACnBS,kBAAkBQ,MAAKC,kBAAoBC,aAAaD,qBAS7DV,oBAAsB,WAClBR,WAAaC,uBAObQ,kBAAoBC,MAAMC,KAAKX,WAAWY,iBAAiBC,mBAAUC,SAASC,YAAYK,iBAIhGX,kBAAkBY,KAAKrB,YAChBS,kBAAkBQ,MAAKC,kBAAoBC,aAAaD,qBA6C7DC,aAAeG,kBAhCDA,CAAAA,iBACZA,YAAYC,SAAW,GAA+B,IAAzBD,YAAYC,UAA2D,OAAzCD,YAAYE,aAAa,mBAC7E,KAGPF,YAAYG,gBACL,SAGHH,YAAYI,cACX,YACQJ,YAAYK,MAA2B,UAAnBL,YAAYM,QACxC,cAC0B,UAApBN,YAAYO,MAAwC,QAApBP,YAAYO,SAClD,aACA,aACA,kBACM,iBAEA,IAcVC,CAAYR,oBACN,EAIX1B,oBAAqB,MAGjB0B,YAAYS,QACd,MAAOC,WAITpC,oBAAqB,EAGbM,SAASK,gBAAkBe,aASjCrB,qBAAuB,IAClBT,gBAAgBA,gBAAgByC,OAAS,sBAyE3BC,mBAhEIA,CAAAA,mBACrBA,gBAAkBjC,8BAItBT,gBAAgB6B,KAAKa,qBACfC,kBAAoBlC,uBAMpBmC,QAAUlC,SAASmC,cAAc,OACvCD,QAAQb,SAAW,EACnBa,QAAQE,MAAMC,SAAW,QACzBH,QAAQE,MAAME,IAAM,EACpBJ,QAAQE,MAAMG,KAAO,QAEfC,YAAcN,QAAQO,YAC5BR,kBAAkBS,WAAWC,aAAaH,YAAaP,mBACvD1C,yBAAyB4B,KAAKqB,mBAExBI,UAAYV,QAAQO,YAC1BR,kBAAkBS,WAAWC,aAAaC,UAAWX,kBAAkBY,aACvErD,uBAAuB2B,KAAKyB,YA2C5BE,CAAqBd,eAEhBrC,UAEDK,SAAS+C,iBAAiB,QAASnD,aAAa,IAI/CQ,uBAAwB,OACnB6B,kBAAoBlC,uBAKpBiD,uBAAyBf,kBAAkBZ,SACjDY,kBAAkBZ,SAAW,EAC7BJ,aAAagB,mBACbA,kBAAkBZ,SAAW2B,uBAIjCvD,UAAYO,SAASK,cAErBV,UAAW,SAQFO,YAAc,KAlEW,MAElCZ,gBAAgB2D,YAEVL,UAAYpD,uBAAuByD,MACrCL,WAEAA,UAAUM,eAGRV,YAAcjD,yBAAyB0D,MACzCT,aAEAA,YAAYU,UAuDhBC,GA7CS7D,gBAAgByC,SAoDzB/B,SAASoD,oBAAoB,QAASxD,aAAa,GAEnDH,UAAY,KACZC,oBAAqB,EACrBC,UAAW"}
\ No newline at end of file
diff --git a/lib/amd/build/local/reactive/overlay.min.js b/lib/amd/build/local/reactive/overlay.min.js
index 2b2d0ea5eae..97cd2e5d532 100644
--- a/lib/amd/build/local/reactive/overlay.min.js
+++ b/lib/amd/build/local/reactive/overlay.min.js
@@ -8,6 +8,6 @@ define("core/local/reactive/overlay",["exports","core/templates","core/prefetch"
* @module core/local/reactive/overlay
* @copyright 2022 Ferran Recio
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.removeOverlay=_exports.removeAllOverlays=_exports.addOverlay=void 0,_templates=_interopRequireDefault(_templates),_prefetch=_interopRequireDefault(_prefetch);_prefetch.default.prefetchTemplate("core/local/reactive/overlay");const selectors_OVERLAY="[data-overlay]",selectors_REPOSITION="[data-overlay-dynamic]",selectors_NAVBAR="nav.navbar.fixed-top";_exports.addOverlay=async(definition,parent)=>{var _definition$classes;definition.content&&"string"!=typeof definition.content&&(definition.content=await definition.content),definition.icon&&"string"!=typeof definition.icon&&(definition.icon=await definition.icon);const data={content:definition.content,css:null!==(_definition$classes=definition.classes)&&void 0!==_definition$classes?_definition$classes:"file-drop-zone"};let overlay;try{const{html:html,js:js}=await _templates.default.renderForPromise("core/local/reactive/overlay",data);_templates.default.appendNodeContents(parent,html,js),overlay=parent.querySelector(selectors_OVERLAY),rePositionPreviewInfoElement(overlay),init()}catch(error){throw error}return overlay};const removeOverlay=overlay=>{var _overlay$dataset;overlay&&overlay.parentNode&&(null!==(_overlay$dataset=overlay.dataset)&&void 0!==_overlay$dataset&&_overlay$dataset.overlayPosition&&delete overlay.parentNode.style.position,overlay.parentNode.removeChild(overlay))};_exports.removeOverlay=removeOverlay;_exports.removeAllOverlays=()=>{document.querySelectorAll(selectors_OVERLAY).forEach((overlay=>{removeOverlay(overlay)}))};const rePositionPreviewInfoElement=function(overlay){var _overlay$parentNode,_overlay$parentNode$s;if(!overlay)throw new Error("Inexistent overlay element");null!==(_overlay$parentNode=overlay.parentNode)&&void 0!==_overlay$parentNode&&null!==(_overlay$parentNode$s=_overlay$parentNode.style)&&void 0!==_overlay$parentNode$s&&_overlay$parentNode$s.position||(overlay.parentNode.style.position="relative",overlay.dataset.overlayPosition="true");const target=overlay.querySelector(selectors_REPOSITION);if(!target)return;const rect=overlay.getBoundingClientRect(),sectionHeight=parseInt(window.getComputedStyle(overlay).height,10),sectionOffset=rect.top,previewHeight=parseInt(window.getComputedStyle(target).height,10)+2*parseInt(window.getComputedStyle(target).padding,10);let top,bottom;if(sectionOffset<0)if(sectionHeight+sectionOffset>=previewHeight){let offSetTop=0-sectionOffset;const navBar=document.querySelector(selectors_NAVBAR);navBar&&(offSetTop+=navBar.offsetHeight),top=offSetTop+"px",bottom="unset"}else top="unset",bottom=0;else top=0,bottom="unset";target.style.top=top,target.style.bottom=bottom},init=()=>{document.addEventListener("scroll",(()=>{document.querySelectorAll(selectors_OVERLAY).forEach((overlay=>{rePositionPreviewInfoElement(overlay)}))}),!0)}}));
+ */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.removeOverlay=_exports.removeAllOverlays=_exports.addOverlay=void 0,_templates=_interopRequireDefault(_templates),_prefetch=_interopRequireDefault(_prefetch);_prefetch.default.prefetchTemplate("core/local/reactive/overlay");const selectors_OVERLAY="[data-overlay]",selectors_REPOSITION="[data-overlay-dynamic]",selectors_NAVBAR="nav.navbar.fixed-top";_exports.addOverlay=async(definition,parent)=>{var _definition$classes;definition.content&&"string"!=typeof definition.content&&(definition.content=await definition.content),definition.icon&&"string"!=typeof definition.icon&&(definition.icon=await definition.icon);const data={content:definition.content,css:null!==(_definition$classes=definition.classes)&&void 0!==_definition$classes?_definition$classes:"file-drop-zone"},{html:html,js:js}=await _templates.default.renderForPromise("core/local/reactive/overlay",data);_templates.default.appendNodeContents(parent,html,js);const overlay=parent.querySelector(selectors_OVERLAY);return rePositionPreviewInfoElement(overlay),init(),overlay};const removeOverlay=overlay=>{var _overlay$dataset;overlay&&overlay.parentNode&&(null!==(_overlay$dataset=overlay.dataset)&&void 0!==_overlay$dataset&&_overlay$dataset.overlayPosition&&delete overlay.parentNode.style.position,overlay.parentNode.removeChild(overlay))};_exports.removeOverlay=removeOverlay;_exports.removeAllOverlays=()=>{document.querySelectorAll(selectors_OVERLAY).forEach((overlay=>{removeOverlay(overlay)}))};const rePositionPreviewInfoElement=function(overlay){var _overlay$parentNode,_overlay$parentNode$s;if(!overlay)throw new Error("Inexistent overlay element");null!==(_overlay$parentNode=overlay.parentNode)&&void 0!==_overlay$parentNode&&null!==(_overlay$parentNode$s=_overlay$parentNode.style)&&void 0!==_overlay$parentNode$s&&_overlay$parentNode$s.position||(overlay.parentNode.style.position="relative",overlay.dataset.overlayPosition="true");const target=overlay.querySelector(selectors_REPOSITION);if(!target)return;const rect=overlay.getBoundingClientRect(),sectionHeight=parseInt(window.getComputedStyle(overlay).height,10),sectionOffset=rect.top,previewHeight=parseInt(window.getComputedStyle(target).height,10)+2*parseInt(window.getComputedStyle(target).padding,10);let top,bottom;if(sectionOffset<0)if(sectionHeight+sectionOffset>=previewHeight){let offSetTop=0-sectionOffset;const navBar=document.querySelector(selectors_NAVBAR);navBar&&(offSetTop+=navBar.offsetHeight),top=offSetTop+"px",bottom="unset"}else top="unset",bottom=0;else top=0,bottom="unset";target.style.top=top,target.style.bottom=bottom},init=()=>{document.addEventListener("scroll",(()=>{document.querySelectorAll(selectors_OVERLAY).forEach((overlay=>{rePositionPreviewInfoElement(overlay)}))}),!0)}}));
//# sourceMappingURL=overlay.min.js.map
\ No newline at end of file
diff --git a/lib/amd/build/local/reactive/overlay.min.js.map b/lib/amd/build/local/reactive/overlay.min.js.map
index 76623879487..32236986887 100644
--- a/lib/amd/build/local/reactive/overlay.min.js.map
+++ b/lib/amd/build/local/reactive/overlay.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"overlay.min.js","sources":["../../../src/local/reactive/overlay.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Element overlay methods.\n *\n * This module is used to create overlay information on components. For example\n * to generate or destroy file drop-zones.\n *\n * @module core/local/reactive/overlay\n * @copyright 2022 Ferran Recio \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Templates from 'core/templates';\nimport Prefetch from 'core/prefetch';\n\n// Prefetch the overlay html.\nconst overlayTemplate = 'core/local/reactive/overlay';\nPrefetch.prefetchTemplate(overlayTemplate);\n\n/**\n * @var {boolean} isInitialized if the module is capturing the proper page events.\n */\nlet isInitialized = false;\n\n/**\n * @var {Object} isInitialized if the module is capturing the proper page events.\n */\nconst selectors = {\n OVERLAY: \"[data-overlay]\",\n REPOSITION: \"[data-overlay-dynamic]\",\n NAVBAR: \"nav.navbar.fixed-top\",\n};\n\n/**\n * Adds an overlay to a specific page element.\n *\n * @param {Object} definition the overlay definition.\n * @param {String|Promise} definition.content an optional overlay content.\n * @param {String|Promise} definition.icon an optional icon content.\n * @param {String} definition.classes an optional CSS classes\n * @param {HTMLElement} parent the parent object\n * @return {HTMLElement|undefined} the new page element.\n */\nexport const addOverlay = async(definition, parent) => {\n // Validate non of the passed params is a promise.\n if (definition.content && typeof definition.content !== 'string') {\n definition.content = await definition.content;\n }\n if (definition.icon && typeof definition.icon !== 'string') {\n definition.icon = await definition.icon;\n }\n const data = {\n content: definition.content,\n css: definition.classes ?? 'file-drop-zone',\n };\n let overlay;\n try {\n const {html, js} = await Templates.renderForPromise(overlayTemplate, data);\n Templates.appendNodeContents(parent, html, js);\n overlay = parent.querySelector(selectors.OVERLAY);\n rePositionPreviewInfoElement(overlay);\n init();\n } catch (error) {\n throw error;\n }\n return overlay;\n};\n\n/**\n * Adds an overlay to a specific page element.\n *\n * @param {HTMLElement} overlay the parent object\n */\nexport const removeOverlay = (overlay) => {\n if (!overlay || !overlay.parentNode) {\n return;\n }\n // Remove any forced parentNode position.\n if (overlay.dataset?.overlayPosition) {\n delete overlay.parentNode.style.position;\n }\n overlay.parentNode.removeChild(overlay);\n};\n\nexport const removeAllOverlays = () => {\n document.querySelectorAll(selectors.OVERLAY).forEach(\n (overlay) => {\n removeOverlay(overlay);\n }\n );\n};\n\n/**\n * Re-position the preview information element by calculating the section position.\n *\n * @param {Object} overlay the overlay element.\n */\nconst rePositionPreviewInfoElement = function(overlay) {\n if (!overlay) {\n throw new Error('Inexistent overlay element');\n }\n // Add relative position to the parent object.\n if (!overlay.parentNode?.style?.position) {\n overlay.parentNode.style.position = 'relative';\n overlay.dataset.overlayPosition = \"true\";\n }\n // Get the element to reposition.\n const target = overlay.querySelector(selectors.REPOSITION);\n if (!target) {\n return;\n }\n // Get the new bounds.\n const rect = overlay.getBoundingClientRect();\n const sectionHeight = parseInt(window.getComputedStyle(overlay).height, 10);\n const sectionOffset = rect.top;\n const previewHeight = parseInt(window.getComputedStyle(target).height, 10) +\n (2 * parseInt(window.getComputedStyle(target).padding, 10));\n // Calculate the new target position.\n let top, bottom;\n if (sectionOffset < 0) {\n if (sectionHeight + sectionOffset >= previewHeight) {\n // We have enough space here, just stick the preview to the top.\n let offSetTop = 0 - sectionOffset;\n const navBar = document.querySelector(selectors.NAVBAR);\n if (navBar) {\n offSetTop = offSetTop + navBar.offsetHeight;\n }\n top = offSetTop + 'px';\n bottom = 'unset';\n } else {\n // We do not have enough space here, just stick the preview to the bottom.\n top = 'unset';\n bottom = 0;\n }\n } else {\n top = 0;\n bottom = 'unset';\n }\n\n target.style.top = top;\n target.style.bottom = bottom;\n};\n\n// Update overlays when the page scrolls.\nconst init = () => {\n if (isInitialized) {\n return;\n }\n // Add scroll events.\n document.addEventListener('scroll', () => {\n document.querySelectorAll(selectors.OVERLAY).forEach(\n (overlay) => {\n rePositionPreviewInfoElement(overlay);\n }\n );\n }, true);\n};\n"],"names":["prefetchTemplate","selectors","async","definition","parent","content","icon","data","css","classes","overlay","html","js","Templates","renderForPromise","appendNodeContents","querySelector","rePositionPreviewInfoElement","init","error","removeOverlay","parentNode","dataset","_overlay$dataset","overlayPosition","style","position","removeChild","document","querySelectorAll","forEach","Error","_overlay$parentNode","_overlay$parentNode$s","target","rect","getBoundingClientRect","sectionHeight","parseInt","window","getComputedStyle","height","sectionOffset","top","previewHeight","padding","bottom","offSetTop","navBar","offsetHeight","addEventListener"],"mappings":";;;;;;;;;;sPA+BSA,iBADe,qCAWlBC,kBACO,iBADPA,qBAEU,yBAFVA,iBAGM,2CAacC,MAAMC,WAAYC,kCAEpCD,WAAWE,SAAyC,iBAAvBF,WAAWE,UACxCF,WAAWE,cAAgBF,WAAWE,SAEtCF,WAAWG,MAAmC,iBAApBH,WAAWG,OACrCH,WAAWG,WAAaH,WAAWG,YAEjCC,KAAO,CACTF,QAASF,WAAWE,QACpBG,gCAAKL,WAAWM,2DAAW,sBAE3BC,kBAEMC,KAACA,KAADC,GAAOA,UAAYC,mBAAUC,iBAzCnB,8BAyCqDP,yBAC3DQ,mBAAmBX,OAAQO,KAAMC,IAC3CF,QAAUN,OAAOY,cAAcf,mBAC/BgB,6BAA6BP,SAC7BQ,OACF,MAAOC,aACCA,aAEHT,eAQEU,cAAiBV,+BACrBA,SAAYA,QAAQW,sCAIrBX,QAAQY,qCAARC,iBAAiBC,wBACVd,QAAQW,WAAWI,MAAMC,SAEpChB,QAAQW,WAAWM,YAAYjB,2EAGF,KAC7BkB,SAASC,iBAAiB5B,mBAAmB6B,SACxCpB,UACGU,cAAcV,mBAUpBO,6BAA+B,SAASP,2DACrCA,cACK,IAAIqB,MAAM,0DAGfrB,QAAQW,yEAARW,oBAAoBP,wCAApBQ,sBAA2BP,WAC5BhB,QAAQW,WAAWI,MAAMC,SAAW,WACpChB,QAAQY,QAAQE,gBAAkB,cAGhCU,OAASxB,QAAQM,cAAcf,0BAChCiC,oBAICC,KAAOzB,QAAQ0B,wBACfC,cAAgBC,SAASC,OAAOC,iBAAiB9B,SAAS+B,OAAQ,IAClEC,cAAgBP,KAAKQ,IACrBC,cAAgBN,SAASC,OAAOC,iBAAiBN,QAAQO,OAAQ,IAClE,EAAIH,SAASC,OAAOC,iBAAiBN,QAAQW,QAAS,QAEvDF,IAAKG,UACLJ,cAAgB,KACZL,cAAgBK,eAAiBE,cAAe,KAE5CG,UAAY,EAAIL,oBACdM,OAASpB,SAASZ,cAAcf,kBAClC+C,SACAD,WAAwBC,OAAOC,cAEnCN,IAAMI,UAAY,KAClBD,OAAS,aAGTH,IAAM,QACNG,OAAS,OAGbH,IAAM,EACNG,OAAS,QAGbZ,OAAOT,MAAMkB,IAAMA,IACnBT,OAAOT,MAAMqB,OAASA,QAIpB5B,KAAO,KAKTU,SAASsB,iBAAiB,UAAU,KAChCtB,SAASC,iBAAiB5B,mBAAmB6B,SACxCpB,UACGO,6BAA6BP,eAGtC"}
\ No newline at end of file
+{"version":3,"file":"overlay.min.js","sources":["../../../src/local/reactive/overlay.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Element overlay methods.\n *\n * This module is used to create overlay information on components. For example\n * to generate or destroy file drop-zones.\n *\n * @module core/local/reactive/overlay\n * @copyright 2022 Ferran Recio \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Templates from 'core/templates';\nimport Prefetch from 'core/prefetch';\n\n// Prefetch the overlay html.\nconst overlayTemplate = 'core/local/reactive/overlay';\nPrefetch.prefetchTemplate(overlayTemplate);\n\n/**\n * @var {boolean} isInitialized if the module is capturing the proper page events.\n */\nlet isInitialized = false;\n\n/**\n * @var {Object} isInitialized if the module is capturing the proper page events.\n */\nconst selectors = {\n OVERLAY: \"[data-overlay]\",\n REPOSITION: \"[data-overlay-dynamic]\",\n NAVBAR: \"nav.navbar.fixed-top\",\n};\n\n/**\n * Adds an overlay to a specific page element.\n *\n * @param {Object} definition the overlay definition.\n * @param {String|Promise} definition.content an optional overlay content.\n * @param {String|Promise} definition.icon an optional icon content.\n * @param {String} definition.classes an optional CSS classes\n * @param {HTMLElement} parent the parent object\n * @return {HTMLElement|undefined} the new page element.\n */\nexport const addOverlay = async(definition, parent) => {\n // Validate non of the passed params is a promise.\n if (definition.content && typeof definition.content !== 'string') {\n definition.content = await definition.content;\n }\n if (definition.icon && typeof definition.icon !== 'string') {\n definition.icon = await definition.icon;\n }\n const data = {\n content: definition.content,\n css: definition.classes ?? 'file-drop-zone',\n };\n const {html, js} = await Templates.renderForPromise(overlayTemplate, data);\n Templates.appendNodeContents(parent, html, js);\n const overlay = parent.querySelector(selectors.OVERLAY);\n rePositionPreviewInfoElement(overlay);\n init();\n return overlay;\n};\n\n/**\n * Adds an overlay to a specific page element.\n *\n * @param {HTMLElement} overlay the parent object\n */\nexport const removeOverlay = (overlay) => {\n if (!overlay || !overlay.parentNode) {\n return;\n }\n // Remove any forced parentNode position.\n if (overlay.dataset?.overlayPosition) {\n delete overlay.parentNode.style.position;\n }\n overlay.parentNode.removeChild(overlay);\n};\n\nexport const removeAllOverlays = () => {\n document.querySelectorAll(selectors.OVERLAY).forEach(\n (overlay) => {\n removeOverlay(overlay);\n }\n );\n};\n\n/**\n * Re-position the preview information element by calculating the section position.\n *\n * @param {Object} overlay the overlay element.\n */\nconst rePositionPreviewInfoElement = function(overlay) {\n if (!overlay) {\n throw new Error('Inexistent overlay element');\n }\n // Add relative position to the parent object.\n if (!overlay.parentNode?.style?.position) {\n overlay.parentNode.style.position = 'relative';\n overlay.dataset.overlayPosition = \"true\";\n }\n // Get the element to reposition.\n const target = overlay.querySelector(selectors.REPOSITION);\n if (!target) {\n return;\n }\n // Get the new bounds.\n const rect = overlay.getBoundingClientRect();\n const sectionHeight = parseInt(window.getComputedStyle(overlay).height, 10);\n const sectionOffset = rect.top;\n const previewHeight = parseInt(window.getComputedStyle(target).height, 10) +\n (2 * parseInt(window.getComputedStyle(target).padding, 10));\n // Calculate the new target position.\n let top, bottom;\n if (sectionOffset < 0) {\n if (sectionHeight + sectionOffset >= previewHeight) {\n // We have enough space here, just stick the preview to the top.\n let offSetTop = 0 - sectionOffset;\n const navBar = document.querySelector(selectors.NAVBAR);\n if (navBar) {\n offSetTop = offSetTop + navBar.offsetHeight;\n }\n top = offSetTop + 'px';\n bottom = 'unset';\n } else {\n // We do not have enough space here, just stick the preview to the bottom.\n top = 'unset';\n bottom = 0;\n }\n } else {\n top = 0;\n bottom = 'unset';\n }\n\n target.style.top = top;\n target.style.bottom = bottom;\n};\n\n// Update overlays when the page scrolls.\nconst init = () => {\n if (isInitialized) {\n return;\n }\n // Add scroll events.\n document.addEventListener('scroll', () => {\n document.querySelectorAll(selectors.OVERLAY).forEach(\n (overlay) => {\n rePositionPreviewInfoElement(overlay);\n }\n );\n }, true);\n};\n"],"names":["prefetchTemplate","selectors","async","definition","parent","content","icon","data","css","classes","html","js","Templates","renderForPromise","appendNodeContents","overlay","querySelector","rePositionPreviewInfoElement","init","removeOverlay","parentNode","dataset","_overlay$dataset","overlayPosition","style","position","removeChild","document","querySelectorAll","forEach","Error","_overlay$parentNode","_overlay$parentNode$s","target","rect","getBoundingClientRect","sectionHeight","parseInt","window","getComputedStyle","height","sectionOffset","top","previewHeight","padding","bottom","offSetTop","navBar","offsetHeight","addEventListener"],"mappings":";;;;;;;;;;sPA+BSA,iBADe,qCAWlBC,kBACO,iBADPA,qBAEU,yBAFVA,iBAGM,2CAacC,MAAMC,WAAYC,kCAEpCD,WAAWE,SAAyC,iBAAvBF,WAAWE,UACxCF,WAAWE,cAAgBF,WAAWE,SAEtCF,WAAWG,MAAmC,iBAApBH,WAAWG,OACrCH,WAAWG,WAAaH,WAAWG,YAEjCC,KAAO,CACTF,QAASF,WAAWE,QACpBG,gCAAKL,WAAWM,2DAAW,mBAEzBC,KAACA,KAADC,GAAOA,UAAYC,mBAAUC,iBAvCf,8BAuCiDN,yBAC3DO,mBAAmBV,OAAQM,KAAMC,UACrCI,QAAUX,OAAOY,cAAcf,0BACrCgB,6BAA6BF,SAC7BG,OACOH,eAQEI,cAAiBJ,+BACrBA,SAAYA,QAAQK,sCAIrBL,QAAQM,qCAARC,iBAAiBC,wBACVR,QAAQK,WAAWI,MAAMC,SAEpCV,QAAQK,WAAWM,YAAYX,2EAGF,KAC7BY,SAASC,iBAAiB3B,mBAAmB4B,SACxCd,UACGI,cAAcJ,mBAUpBE,6BAA+B,SAASF,2DACrCA,cACK,IAAIe,MAAM,0DAGff,QAAQK,yEAARW,oBAAoBP,wCAApBQ,sBAA2BP,WAC5BV,QAAQK,WAAWI,MAAMC,SAAW,WACpCV,QAAQM,QAAQE,gBAAkB,cAGhCU,OAASlB,QAAQC,cAAcf,0BAChCgC,oBAICC,KAAOnB,QAAQoB,wBACfC,cAAgBC,SAASC,OAAOC,iBAAiBxB,SAASyB,OAAQ,IAClEC,cAAgBP,KAAKQ,IACrBC,cAAgBN,SAASC,OAAOC,iBAAiBN,QAAQO,OAAQ,IAClE,EAAIH,SAASC,OAAOC,iBAAiBN,QAAQW,QAAS,QAEvDF,IAAKG,UACLJ,cAAgB,KACZL,cAAgBK,eAAiBE,cAAe,KAE5CG,UAAY,EAAIL,oBACdM,OAASpB,SAASX,cAAcf,kBAClC8C,SACAD,WAAwBC,OAAOC,cAEnCN,IAAMI,UAAY,KAClBD,OAAS,aAGTH,IAAM,QACNG,OAAS,OAGbH,IAAM,EACNG,OAAS,QAGbZ,OAAOT,MAAMkB,IAAMA,IACnBT,OAAOT,MAAMqB,OAASA,QAIpB3B,KAAO,KAKTS,SAASsB,iBAAiB,UAAU,KAChCtB,SAASC,iBAAiB3B,mBAAmB4B,SACxCd,UACGE,6BAA6BF,eAGtC"}
\ No newline at end of file
diff --git a/lib/amd/build/sortable_list.min.js.map b/lib/amd/build/sortable_list.min.js.map
index 454f008be49..a4d6e4713bd 100644
--- a/lib/amd/build/sortable_list.min.js.map
+++ b/lib/amd/build/sortable_list.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"sortable_list.min.js","sources":["../src/sortable_list.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * A javascript module to handle list items drag and drop\n *\n * Example of usage:\n *\n * Create a list (for example `` or ``) where each draggable element has a drag handle.\n * The best practice is to use the template core/drag_handle:\n * $OUTPUT->render_from_template('core/drag_handle', ['movetitle' => get_string('movecontent', 'moodle', ELEMENTNAME)]);\n *\n * Attach this JS module to this list:\n *\n * Space between define and ( critical in comment but not allowed in code in order to function\n * correctly with Moodle's requirejs.php\n *\n * More details: https://docs.moodle.org/dev/Sortable_list\n *\n * For the full list of possible parameters see var defaultParameters below.\n *\n * The following jQuery events are fired:\n * - SortableList.EVENTS.DRAGSTART : when user started dragging a list element\n * - SortableList.EVENTS.DRAG : when user dragged a list element to a new position\n * - SortableList.EVENTS.DROP : when user dropped a list element\n * - SortableList.EVENTS.DROPEND : when user finished dragging - either fired right after dropping or\n * if \"Esc\" was pressed during dragging\n *\n * @example\n * define (['jquery', 'core/sortable_list'], function($, SortableList) {\n * var list = new SortableList('ul.my-awesome-list'); // source list (usually or ) - selector or element\n *\n * // Listen to the events when element is dragged.\n * $('ul.my-awesome-list > *').on(SortableList.EVENTS.DROP, function(evt, info) {\n * console.log(info);\n * });\n *\n * // Advanced usage. Overwrite methods getElementName, getDestinationName, moveDialogueTitle, for example:\n * list.getElementName = function(element) {\n * return $.Deferred().resolve(element.attr('data-name'));\n * }\n * });\n *\n * @module core/sortable_list\n * @class core/sortable_list\n * @copyright 2018 Marina Glancy\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['jquery', 'core/log', 'core/autoscroll', 'core/str', 'core/modal_factory', 'core/modal_events', 'core/notification'],\nfunction($, log, autoScroll, str, ModalFactory, ModalEvents, Notification) {\n\n /**\n * Default parameters\n *\n * @private\n * @type {Object}\n */\n var defaultParameters = {\n targetListSelector: null,\n moveHandlerSelector: '[data-drag-type=move]',\n isHorizontal: false,\n autoScroll: true\n };\n\n /**\n * Class names for different elements that may be changed during sorting\n *\n * @private\n * @type {Object}\n */\n var CSS = {\n keyboardDragClass: 'dragdrop-keyboard-drag',\n isDraggedClass: 'sortable-list-is-dragged',\n currentPositionClass: 'sortable-list-current-position',\n sourceListClass: 'sortable-list-source',\n targetListClass: 'sortable-list-target',\n overElementClass: 'sortable-list-over-element'\n };\n\n /**\n * Test the browser support for options objects on event listeners.\n * @return {Boolean}\n */\n var eventListenerOptionsSupported = function() {\n var passivesupported = false,\n options,\n testeventname = \"testpassiveeventoptions\";\n\n // Options support testing example from:\n // https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener\n\n try {\n options = Object.defineProperty({}, \"passive\", {\n get: function() {\n passivesupported = true;\n }\n });\n\n // We use an event name that is not likely to conflict with any real event.\n document.addEventListener(testeventname, options, options);\n // We remove the event listener as we have tested the options already.\n document.removeEventListener(testeventname, options, options);\n } catch (err) {\n // It's already false.\n passivesupported = false;\n }\n return passivesupported;\n };\n\n /**\n * Allow to create non-passive touchstart listeners and prevent page scrolling when dragging\n * From: https://stackoverflow.com/a/48098097\n *\n * @param {string} eventname\n * @returns {object}\n */\n var registerNotPassiveListeners = function(eventname) {\n return {\n setup: function(x, ns, handle) {\n if (ns.includes('notPassive')) {\n this.addEventListener(eventname, handle, {passive: false});\n return true;\n } else {\n return false;\n }\n }\n };\n };\n\n if (eventListenerOptionsSupported) {\n $.event.special.touchstart = registerNotPassiveListeners('touchstart');\n $.event.special.touchmove = registerNotPassiveListeners('touchmove');\n $.event.special.touchend = registerNotPassiveListeners('touchend');\n }\n\n /**\n * Initialise sortable list.\n *\n * @param {(String|jQuery|Element)} root JQuery/DOM element representing sortable list (i.e. , ) or CSS selector\n * @param {Object} config Parameters for the list. See defaultParameters above for examples.\n * @param {(String|jQuery|Element)} config.targetListSelector target lists, by default same as root\n * @param {String} config.moveHandlerSelector CSS selector for a drag handle. By default '[data-drag-type=move]'\n * @param {String} config.listSelector CSS selector for target lists. By default the same as root\n * @param {(Boolean|Function)} config.isHorizontal Set to true if the list is horizontal (can also be a callback\n * with list as an argument)\n * @param {Boolean} config.autoScroll Engages autoscroll module for automatic vertical scrolling of the whole page,\n * by default true\n */\n var SortableList = function(root, config) {\n\n this.info = null;\n this.proxy = null;\n this.proxyDelta = null;\n this.dragCounter = 0;\n this.lastEvent = null;\n\n this.config = $.extend({}, defaultParameters, config || {});\n this.config.listSelector = root;\n if (!this.config.targetListSelector) {\n this.config.targetListSelector = root;\n }\n if (typeof this.config.listSelector === 'object') {\n // The root is an element on the page. Register a listener for this element.\n $(this.config.listSelector).on('mousedown touchstart.notPassive', $.proxy(this.dragStartHandler, this));\n } else {\n // The root is a CSS selector. Register a listener that picks up the element dynamically.\n $('body').on('mousedown touchstart.notPassive', this.config.listSelector, $.proxy(this.dragStartHandler, this));\n }\n if (this.config.moveHandlerSelector !== null) {\n $('body').on('click keypress', this.config.moveHandlerSelector, $.proxy(this.clickHandler, this));\n }\n\n };\n\n /**\n * Events fired by this entity\n *\n * @public\n * @type {Object}\n */\n SortableList.EVENTS = {\n DRAGSTART: 'sortablelist-dragstart',\n DRAG: 'sortablelist-drag',\n DROP: 'sortablelist-drop',\n DRAGEND: 'sortablelist-dragend'\n };\n\n /**\n * Resets the temporary classes assigned during dragging\n * @private\n */\n SortableList.prototype.resetDraggedClasses = function() {\n var classes = [\n CSS.isDraggedClass,\n CSS.currentPositionClass,\n CSS.overElementClass,\n CSS.targetListClass,\n ];\n for (var i in classes) {\n $('.' + classes[i]).removeClass(classes[i]);\n }\n if (this.proxy) {\n this.proxy.remove();\n this.proxy = $();\n }\n };\n\n /**\n * Calculates evt.pageX, evt.pageY, evt.clientX and evt.clientY\n *\n * For touch events pageX and pageY are taken from the first touch;\n * For the emulated mousemove event they are taken from the last real event.\n *\n * @private\n * @param {Event} evt\n */\n SortableList.prototype.calculatePositionOnPage = function(evt) {\n\n if (evt.originalEvent && evt.originalEvent.touches && evt.originalEvent.touches[0] !== undefined) {\n // This is a touchmove or touchstart event, get position from the first touch position.\n var touch = evt.originalEvent.touches[0];\n evt.pageX = touch.pageX;\n evt.pageY = touch.pageY;\n }\n\n if (evt.pageX === undefined) {\n // Information is not present in case of touchend or when event was emulated by autoScroll.\n // Take the absolute mouse position from the last event.\n evt.pageX = this.lastEvent.pageX;\n evt.pageY = this.lastEvent.pageY;\n } else {\n this.lastEvent = evt;\n }\n\n if (evt.clientX === undefined) {\n // If not provided in event calculate relative mouse position.\n evt.clientX = Math.round(evt.pageX - $(window).scrollLeft());\n evt.clientY = Math.round(evt.pageY - $(window).scrollTop());\n }\n };\n\n /**\n * Handler from dragstart event\n *\n * @private\n * @param {Event} evt\n */\n SortableList.prototype.dragStartHandler = function(evt) {\n if (this.info !== null) {\n if (this.info.type === 'click' || this.info.type === 'touchend') {\n // Ignore double click.\n return;\n }\n // Mouse down or touch while already dragging, cancel previous dragging.\n this.moveElement(this.info.sourceList, this.info.sourceNextElement);\n this.finishDragging();\n }\n\n if (evt.type === 'mousedown' && evt.which !== 1) {\n // We only need left mouse click. If this is a mousedown event with right/middle click ignore it.\n return;\n }\n\n this.calculatePositionOnPage(evt);\n var movedElement = $(evt.target).closest($(evt.currentTarget).children());\n if (!movedElement.length) {\n // Can't find the element user wants to drag. They clicked on the list but outside of any element of the list.\n return;\n }\n\n // Check that we grabbed the element by the handle.\n if (this.config.moveHandlerSelector !== null) {\n if (!$(evt.target).closest(this.config.moveHandlerSelector, movedElement).length) {\n return;\n }\n }\n\n evt.stopPropagation();\n evt.preventDefault();\n\n // Information about moved element with original location.\n // This object is passed to event observers.\n this.dragCounter++;\n this.info = {\n element: movedElement,\n sourceNextElement: movedElement.next(),\n sourceList: movedElement.parent(),\n targetNextElement: movedElement.next(),\n targetList: movedElement.parent(),\n type: evt.type,\n dropped: false,\n startX: evt.pageX,\n startY: evt.pageY,\n startTime: new Date().getTime()\n };\n\n $(this.config.targetListSelector).addClass(CSS.targetListClass);\n\n var offset = movedElement.offset();\n movedElement.addClass(CSS.currentPositionClass);\n this.proxyDelta = {x: offset.left - evt.pageX, y: offset.top - evt.pageY};\n this.proxy = $();\n var thisDragCounter = this.dragCounter;\n setTimeout($.proxy(function() {\n // This mousedown event may in fact be a beginning of a 'click' event. Use timeout before showing the\n // dragged object so we can catch click event. When timeout finishes make sure that click event\n // has not happened during this half a second.\n // Verify dragcounter to make sure the user did not manage to do two very fast drag actions one after another.\n if (this.info === null || this.info.type === 'click' || this.info.type === 'keypress'\n || this.dragCounter !== thisDragCounter) {\n return;\n }\n\n // Create a proxy - the copy of the dragged element that moves together with a mouse.\n this.createProxy();\n }, this), 500);\n\n // Start drag.\n $(window).on('mousemove touchmove.notPassive mouseup touchend.notPassive', $.proxy(this.dragHandler, this));\n $(window).on('keypress', $.proxy(this.dragcancelHandler, this));\n\n // Start autoscrolling. Every time the page is scrolled emulate the mousemove event.\n if (this.config.autoScroll) {\n autoScroll.start(function() {\n $(window).trigger('mousemove');\n });\n }\n\n this.executeCallback(SortableList.EVENTS.DRAGSTART);\n };\n\n /**\n * Creates a \"proxy\" object - a copy of the element that is being moved that always follows the mouse\n * @private\n */\n SortableList.prototype.createProxy = function() {\n this.proxy = this.info.element.clone();\n this.info.sourceList.append(this.proxy);\n this.proxy.removeAttr('id').removeClass(CSS.currentPositionClass)\n .addClass(CSS.isDraggedClass).css({position: 'fixed'});\n this.proxy.offset({top: this.proxyDelta.y + this.lastEvent.pageY, left: this.proxyDelta.x + this.lastEvent.pageX});\n };\n\n /**\n * Handler for click event - when user clicks on the drag handler or presses Enter on keyboard\n *\n * @private\n * @param {Event} evt\n */\n SortableList.prototype.clickHandler = function(evt) {\n if (evt.type === 'keypress' && evt.originalEvent.keyCode !== 13 && evt.originalEvent.keyCode !== 32) {\n return;\n }\n if (this.info !== null) {\n // Ignore double click.\n return;\n }\n\n // Find the element that this draghandle belongs to.\n var clickedElement = $(evt.target).closest(this.config.moveHandlerSelector),\n sourceList = clickedElement.closest(this.config.listSelector),\n movedElement = clickedElement.closest(sourceList.children());\n if (!movedElement.length) {\n return;\n }\n\n evt.preventDefault();\n evt.stopPropagation();\n\n // Store information about moved element with original location.\n this.dragCounter++;\n this.info = {\n element: movedElement,\n sourceNextElement: movedElement.next(),\n sourceList: sourceList,\n targetNextElement: movedElement.next(),\n targetList: sourceList,\n dropped: false,\n type: evt.type,\n startTime: new Date().getTime()\n };\n\n this.executeCallback(SortableList.EVENTS.DRAGSTART);\n this.displayMoveDialogue(clickedElement);\n };\n\n /**\n * Finds the position of the mouse inside the element - on the top, on the bottom, on the right or on the left\\\n *\n * Used to determine if the moved element should be moved after or before the current element\n *\n * @private\n * @param {Number} pageX\n * @param {Number} pageY\n * @param {jQuery} element\n * @returns {(Object|null)}\n */\n SortableList.prototype.getPositionInNode = function(pageX, pageY, element) {\n if (!element.length) {\n return null;\n }\n var node = element[0],\n offset = 0,\n rect = node.getBoundingClientRect(),\n y = pageY - (rect.top + window.scrollY),\n x = pageX - (rect.left + window.scrollX);\n if (x >= -offset && x <= rect.width + offset && y >= -offset && y <= rect.height + offset) {\n return {\n x: x,\n y: y,\n xRatio: rect.width ? (x / rect.width) : 0,\n yRatio: rect.height ? (y / rect.height) : 0\n };\n }\n return null;\n };\n\n /**\n * Check if list is horizontal\n *\n * @param {jQuery} element\n * @return {Boolean}\n */\n SortableList.prototype.isListHorizontal = function(element) {\n var isHorizontal = this.config.isHorizontal;\n if (isHorizontal === true || isHorizontal === false) {\n return isHorizontal;\n }\n return isHorizontal(element);\n };\n\n /**\n * Handler for events mousemove touchmove mouseup touchend\n *\n * @private\n * @param {Event} evt\n */\n SortableList.prototype.dragHandler = function(evt) {\n\n evt.preventDefault();\n evt.stopPropagation();\n\n this.calculatePositionOnPage(evt);\n\n // We can not use evt.target here because it will most likely be our proxy.\n // Move the proxy out of the way so we can find the element at the current mouse position.\n this.proxy.offset({top: -1000, left: -1000});\n // Find the element at the current mouse position.\n var element = $(document.elementFromPoint(evt.clientX, evt.clientY));\n\n // Find the list element and the list over the mouse position.\n var mainElement = this.info.element[0],\n isNotSelf = function() {\n return this !== mainElement;\n },\n current = element.closest('.' + CSS.targetListClass + ' > :not(.' + CSS.isDraggedClass + ')').filter(isNotSelf),\n currentList = element.closest('.' + CSS.targetListClass),\n proxy = this.proxy,\n isNotProxy = function() {\n return !proxy || !proxy.length || this !== proxy[0];\n };\n\n // Add the specified class to the list element we are hovering.\n $('.' + CSS.overElementClass).removeClass(CSS.overElementClass);\n current.addClass(CSS.overElementClass);\n\n // Move proxy to the current position.\n this.proxy.offset({top: this.proxyDelta.y + evt.pageY, left: this.proxyDelta.x + evt.pageX});\n\n if (currentList.length && !currentList.children().filter(isNotProxy).length) {\n // Mouse is over an empty list.\n this.moveElement(currentList, $());\n } else if (current.length === 1 && !this.info.element.find(current[0]).length) {\n // Mouse is over an element in a list - find whether we should move the current position\n // above or below this element.\n var coordinates = this.getPositionInNode(evt.pageX, evt.pageY, current);\n if (coordinates) {\n var parent = current.parent(),\n ratio = this.isListHorizontal(parent) ? coordinates.xRatio : coordinates.yRatio,\n subList = current.find('.' + CSS.targetListClass),\n subListEmpty = !subList.children().filter(isNotProxy).filter(isNotSelf).length;\n if (subList.length && subListEmpty && ratio > 0.2 && ratio < 0.8) {\n // This is an element that is a parent of an empty list and we are around the middle of this element.\n // Treat it as if we are over this empty list.\n this.moveElement(subList, $());\n } else if (ratio > 0.5) {\n // Insert after this element.\n this.moveElement(parent, current.next().filter(isNotProxy));\n } else {\n // Insert before this element.\n this.moveElement(parent, current);\n }\n }\n }\n\n if (evt.type === 'mouseup' || evt.type === 'touchend') {\n // Drop the moved element.\n this.info.endX = evt.pageX;\n this.info.endY = evt.pageY;\n this.info.endTime = new Date().getTime();\n this.info.dropped = true;\n this.info.positionChanged = this.hasPositionChanged(this.info);\n var oldinfo = this.info;\n this.executeCallback(SortableList.EVENTS.DROP);\n this.finishDragging();\n\n if (evt.type === 'touchend'\n && this.config.moveHandlerSelector !== null\n && (oldinfo.endTime - oldinfo.startTime < 500)\n && !oldinfo.positionChanged) {\n // The click event is not triggered on touch screens because we call preventDefault in touchstart handler.\n // If the touchend quickly followed touchstart without moving, consider it a \"click\".\n this.clickHandler(evt);\n }\n }\n };\n\n /**\n * Checks if the position of the dragged element in the list has changed\n *\n * @private\n * @param {Object} info\n * @return {Boolean}\n */\n SortableList.prototype.hasPositionChanged = function(info) {\n return info.sourceList[0] !== info.targetList[0] ||\n info.sourceNextElement.length !== info.targetNextElement.length ||\n (info.sourceNextElement.length && info.sourceNextElement[0] !== info.targetNextElement[0]);\n };\n\n /**\n * Moves the current position of the dragged element\n *\n * @private\n * @param {jQuery} parentElement\n * @param {jQuery} beforeElement\n */\n SortableList.prototype.moveElement = function(parentElement, beforeElement) {\n var dragEl = this.info.element;\n if (beforeElement.length && beforeElement[0] === dragEl[0]) {\n // Insert before the current position of the dragged element - nothing to do.\n return;\n }\n if (parentElement[0] === this.info.targetList[0] &&\n beforeElement.length === this.info.targetNextElement.length &&\n beforeElement[0] === this.info.targetNextElement[0]) {\n // Insert in the same location as the current position - nothing to do.\n return;\n }\n\n if (beforeElement.length) {\n // Move the dragged element before the specified element.\n parentElement[0].insertBefore(dragEl[0], beforeElement[0]);\n } else if (this.proxy && this.proxy.parent().length && this.proxy.parent()[0] === parentElement[0]) {\n // We need to move to the end of the list but the last element in this list is a proxy.\n // Always leave the proxy in the end of the list.\n parentElement[0].insertBefore(dragEl[0], this.proxy[0]);\n } else {\n // Insert in the end of a list (when proxy is in another list).\n parentElement[0].appendChild(dragEl[0]);\n }\n\n // Save the current position of the dragged element in the list.\n this.info.targetList = parentElement;\n this.info.targetNextElement = beforeElement;\n this.executeCallback(SortableList.EVENTS.DRAG);\n };\n\n /**\n * Finish dragging (when dropped or cancelled).\n * @private\n */\n SortableList.prototype.finishDragging = function() {\n this.resetDraggedClasses();\n if (this.config.autoScroll) {\n autoScroll.stop();\n }\n $(window).off('mousemove touchmove.notPassive mouseup touchend.notPassive', $.proxy(this.dragHandler, this));\n $(window).off('keypress', $.proxy(this.dragcancelHandler, this));\n this.executeCallback(SortableList.EVENTS.DRAGEND);\n this.info = null;\n };\n\n /**\n * Executes callback specified in sortable list parameters\n *\n * @private\n * @param {String} eventName\n */\n SortableList.prototype.executeCallback = function(eventName) {\n this.info.element.trigger(eventName, this.info);\n };\n\n /**\n * Handler from keypress event (cancel dragging when Esc is pressed)\n *\n * @private\n * @param {Event} evt\n */\n SortableList.prototype.dragcancelHandler = function(evt) {\n if (evt.type !== 'keypress' || evt.originalEvent.keyCode !== 27) {\n // Only cancel dragging when Esc was pressed.\n return;\n }\n // Dragging was cancelled. Return item to the original position.\n this.moveElement(this.info.sourceList, this.info.sourceNextElement);\n this.finishDragging();\n };\n\n /**\n * Returns the name of the current element to be used in the move dialogue\n *\n * @public\n * @param {jQuery} element\n * @return {Promise}\n */\n SortableList.prototype.getElementName = function(element) {\n return $.Deferred().resolve(element.text());\n };\n\n /**\n * Returns the label for the potential move destination, i.e. \"After ElementX\" or \"To the top of the list\"\n *\n * Note that we use \"after\" in the label for better UX\n *\n * @public\n * @param {jQuery} parentElement\n * @param {jQuery} afterElement\n * @return {Promise}\n */\n SortableList.prototype.getDestinationName = function(parentElement, afterElement) {\n if (!afterElement.length) {\n return str.get_string('movecontenttothetop', 'moodle');\n } else {\n return this.getElementName(afterElement)\n .then(function(name) {\n return str.get_string('movecontentafter', 'moodle', name);\n });\n }\n };\n\n /**\n * Returns the title for the move dialogue (\"Move elementY\")\n *\n * @public\n * @param {jQuery} element\n * @param {jQuery} handler\n * @return {Promise}\n */\n SortableList.prototype.getMoveDialogueTitle = function(element, handler) {\n if (handler.attr('title')) {\n return $.Deferred().resolve(handler.attr('title'));\n }\n return this.getElementName(element).then(function(name) {\n return str.get_string('movecontent', 'moodle', name);\n });\n };\n\n /**\n * Returns the list of possible move destinations\n *\n * @private\n * @return {Promise}\n */\n SortableList.prototype.getDestinationsList = function() {\n var addedLists = [],\n targets = $(this.config.targetListSelector),\n destinations = $('').addClass(CSS.keyboardDragClass),\n result = $.when().then(function() {\n return destinations;\n }),\n createLink = $.proxy(function(parentElement, beforeElement, afterElement) {\n if (beforeElement.is(this.info.element) || afterElement.is(this.info.element)) {\n // Can not move before or after itself.\n return;\n }\n if ($.contains(this.info.element[0], parentElement[0])) {\n // Can not move to its own child.\n return;\n }\n result = result\n .then($.proxy(function() {\n return this.getDestinationName(parentElement, afterElement);\n }, this))\n .then(function(txt) {\n var li = $('').appendTo(destinations);\n var a = $('').attr('data-core_sortable_list-quickmove', 1).appendTo(li);\n a.data('parent-element', parentElement).data('before-element', beforeElement).text(txt);\n return destinations;\n });\n }, this),\n addList = function() {\n // Destination lists may be nested. We want to add all move destinations in the same\n // order they appear on the screen for the user.\n if ($.inArray(this, addedLists) !== -1) {\n return;\n }\n addedLists.push(this);\n var list = $(this),\n children = list.children();\n children.each(function() {\n var element = $(this);\n createLink(list, element, element.prev());\n // Add all nested lists.\n element.find(targets).each(addList);\n });\n createLink(list, $(), children.last());\n };\n targets.each(addList);\n return result;\n };\n\n /**\n * Displays the dialogue to move element.\n * @param {jQuery} clickedElement element to return focus to after the modal is closed\n * @private\n */\n SortableList.prototype.displayMoveDialogue = function(clickedElement) {\n ModalFactory.create({\n type: ModalFactory.types.CANCEL,\n title: this.getMoveDialogueTitle(this.info.element, clickedElement),\n body: this.getDestinationsList()\n }).then($.proxy(function(modal) {\n var quickMoveHandler = $.proxy(function(e) {\n e.preventDefault();\n e.stopPropagation();\n this.moveElement($(e.currentTarget).data('parent-element'), $(e.currentTarget).data('before-element'));\n this.info.endTime = new Date().getTime();\n this.info.positionChanged = this.hasPositionChanged(this.info);\n this.info.dropped = true;\n clickedElement.focus();\n this.executeCallback(SortableList.EVENTS.DROP);\n modal.hide();\n }, this);\n modal.getRoot().on('click', '[data-core_sortable_list-quickmove]', quickMoveHandler);\n modal.getRoot().on(ModalEvents.hidden, $.proxy(function() {\n // Always destroy when hidden, it is generated dynamically each time.\n modal.getRoot().off('click', '[data-core_sortable_list-quickmove]', quickMoveHandler);\n modal.destroy();\n this.finishDragging();\n }, this));\n modal.setLarge();\n modal.show();\n return modal;\n }, this)).catch(Notification.exception);\n };\n\n return SortableList;\n\n});\n"],"names":["define","$","log","autoScroll","str","ModalFactory","ModalEvents","Notification","defaultParameters","targetListSelector","moveHandlerSelector","isHorizontal","CSS","registerNotPassiveListeners","eventname","setup","x","ns","handle","includes","addEventListener","passive","options","passivesupported","Object","defineProperty","get","document","removeEventListener","err","event","special","touchstart","touchmove","touchend","SortableList","root","config","info","proxy","proxyDelta","dragCounter","lastEvent","extend","listSelector","this","on","dragStartHandler","clickHandler","EVENTS","DRAGSTART","DRAG","DROP","DRAGEND","prototype","resetDraggedClasses","classes","i","removeClass","remove","calculatePositionOnPage","evt","originalEvent","touches","undefined","touch","pageX","pageY","clientX","Math","round","window","scrollLeft","clientY","scrollTop","type","moveElement","sourceList","sourceNextElement","finishDragging","which","movedElement","target","closest","currentTarget","children","length","stopPropagation","preventDefault","element","next","parent","targetNextElement","targetList","dropped","startX","startY","startTime","Date","getTime","addClass","offset","left","y","top","thisDragCounter","setTimeout","createProxy","dragHandler","dragcancelHandler","start","trigger","executeCallback","clone","append","removeAttr","css","position","keyCode","clickedElement","displayMoveDialogue","getPositionInNode","rect","getBoundingClientRect","scrollY","scrollX","width","height","xRatio","yRatio","isListHorizontal","elementFromPoint","mainElement","isNotSelf","current","filter","currentList","isNotProxy","find","coordinates","ratio","subList","subListEmpty","endX","endY","endTime","positionChanged","hasPositionChanged","oldinfo","parentElement","beforeElement","dragEl","insertBefore","appendChild","stop","off","eventName","getElementName","Deferred","resolve","text","getDestinationName","afterElement","then","name","get_string","getMoveDialogueTitle","handler","attr","getDestinationsList","addedLists","targets","destinations","result","when","createLink","is","contains","txt","li","appendTo","data","addList","inArray","push","list","each","prev","last","create","types","CANCEL","title","body","modal","quickMoveHandler","e","focus","hide","getRoot","hidden","destroy","setLarge","show","catch","exception"],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"sortable_list.min.js","sources":["../src/sortable_list.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * A javascript module to handle list items drag and drop\n *\n * Example of usage:\n *\n * Create a list (for example `` or ``) where each draggable element has a drag handle.\n * The best practice is to use the template core/drag_handle:\n * $OUTPUT->render_from_template('core/drag_handle', ['movetitle' => get_string('movecontent', 'moodle', ELEMENTNAME)]);\n *\n * Attach this JS module to this list:\n *\n * Space between define and ( critical in comment but not allowed in code in order to function\n * correctly with Moodle's requirejs.php\n *\n * More details: https://docs.moodle.org/dev/Sortable_list\n *\n * For the full list of possible parameters see var defaultParameters below.\n *\n * The following jQuery events are fired:\n * - SortableList.EVENTS.DRAGSTART : when user started dragging a list element\n * - SortableList.EVENTS.DRAG : when user dragged a list element to a new position\n * - SortableList.EVENTS.DROP : when user dropped a list element\n * - SortableList.EVENTS.DROPEND : when user finished dragging - either fired right after dropping or\n * if \"Esc\" was pressed during dragging\n *\n * @example\n * define (['jquery', 'core/sortable_list'], function($, SortableList) {\n * var list = new SortableList('ul.my-awesome-list'); // source list (usually or ) - selector or element\n *\n * // Listen to the events when element is dragged.\n * $('ul.my-awesome-list > *').on(SortableList.EVENTS.DROP, function(evt, info) {\n * console.log(info);\n * });\n *\n * // Advanced usage. Overwrite methods getElementName, getDestinationName, moveDialogueTitle, for example:\n * list.getElementName = function(element) {\n * return $.Deferred().resolve(element.attr('data-name'));\n * }\n * });\n *\n * @module core/sortable_list\n * @class core/sortable_list\n * @copyright 2018 Marina Glancy\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['jquery', 'core/log', 'core/autoscroll', 'core/str', 'core/modal_factory', 'core/modal_events', 'core/notification'],\nfunction($, log, autoScroll, str, ModalFactory, ModalEvents, Notification) {\n\n /**\n * Default parameters\n *\n * @private\n * @type {Object}\n */\n var defaultParameters = {\n targetListSelector: null,\n moveHandlerSelector: '[data-drag-type=move]',\n isHorizontal: false,\n autoScroll: true\n };\n\n /**\n * Class names for different elements that may be changed during sorting\n *\n * @private\n * @type {Object}\n */\n var CSS = {\n keyboardDragClass: 'dragdrop-keyboard-drag',\n isDraggedClass: 'sortable-list-is-dragged',\n currentPositionClass: 'sortable-list-current-position',\n sourceListClass: 'sortable-list-source',\n targetListClass: 'sortable-list-target',\n overElementClass: 'sortable-list-over-element'\n };\n\n /**\n * Test the browser support for options objects on event listeners.\n * @return {Boolean}\n */\n var eventListenerOptionsSupported = function() {\n var passivesupported = false,\n options,\n testeventname = \"testpassiveeventoptions\";\n\n // Options support testing example from:\n // https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener\n\n try {\n options = Object.defineProperty({}, \"passive\", {\n // eslint-disable-next-line getter-return\n get: function() {\n passivesupported = true;\n }\n });\n\n // We use an event name that is not likely to conflict with any real event.\n document.addEventListener(testeventname, options, options);\n // We remove the event listener as we have tested the options already.\n document.removeEventListener(testeventname, options, options);\n } catch (err) {\n // It's already false.\n passivesupported = false;\n }\n return passivesupported;\n };\n\n /**\n * Allow to create non-passive touchstart listeners and prevent page scrolling when dragging\n * From: https://stackoverflow.com/a/48098097\n *\n * @param {string} eventname\n * @returns {object}\n */\n var registerNotPassiveListeners = function(eventname) {\n return {\n setup: function(x, ns, handle) {\n if (ns.includes('notPassive')) {\n this.addEventListener(eventname, handle, {passive: false});\n return true;\n } else {\n return false;\n }\n }\n };\n };\n\n if (eventListenerOptionsSupported) {\n $.event.special.touchstart = registerNotPassiveListeners('touchstart');\n $.event.special.touchmove = registerNotPassiveListeners('touchmove');\n $.event.special.touchend = registerNotPassiveListeners('touchend');\n }\n\n /**\n * Initialise sortable list.\n *\n * @param {(String|jQuery|Element)} root JQuery/DOM element representing sortable list (i.e. , ) or CSS selector\n * @param {Object} config Parameters for the list. See defaultParameters above for examples.\n * @param {(String|jQuery|Element)} config.targetListSelector target lists, by default same as root\n * @param {String} config.moveHandlerSelector CSS selector for a drag handle. By default '[data-drag-type=move]'\n * @param {String} config.listSelector CSS selector for target lists. By default the same as root\n * @param {(Boolean|Function)} config.isHorizontal Set to true if the list is horizontal (can also be a callback\n * with list as an argument)\n * @param {Boolean} config.autoScroll Engages autoscroll module for automatic vertical scrolling of the whole page,\n * by default true\n */\n var SortableList = function(root, config) {\n\n this.info = null;\n this.proxy = null;\n this.proxyDelta = null;\n this.dragCounter = 0;\n this.lastEvent = null;\n\n this.config = $.extend({}, defaultParameters, config || {});\n this.config.listSelector = root;\n if (!this.config.targetListSelector) {\n this.config.targetListSelector = root;\n }\n if (typeof this.config.listSelector === 'object') {\n // The root is an element on the page. Register a listener for this element.\n $(this.config.listSelector).on('mousedown touchstart.notPassive', $.proxy(this.dragStartHandler, this));\n } else {\n // The root is a CSS selector. Register a listener that picks up the element dynamically.\n $('body').on('mousedown touchstart.notPassive', this.config.listSelector, $.proxy(this.dragStartHandler, this));\n }\n if (this.config.moveHandlerSelector !== null) {\n $('body').on('click keypress', this.config.moveHandlerSelector, $.proxy(this.clickHandler, this));\n }\n\n };\n\n /**\n * Events fired by this entity\n *\n * @public\n * @type {Object}\n */\n SortableList.EVENTS = {\n DRAGSTART: 'sortablelist-dragstart',\n DRAG: 'sortablelist-drag',\n DROP: 'sortablelist-drop',\n DRAGEND: 'sortablelist-dragend'\n };\n\n /**\n * Resets the temporary classes assigned during dragging\n * @private\n */\n SortableList.prototype.resetDraggedClasses = function() {\n var classes = [\n CSS.isDraggedClass,\n CSS.currentPositionClass,\n CSS.overElementClass,\n CSS.targetListClass,\n ];\n for (var i in classes) {\n $('.' + classes[i]).removeClass(classes[i]);\n }\n if (this.proxy) {\n this.proxy.remove();\n this.proxy = $();\n }\n };\n\n /**\n * Calculates evt.pageX, evt.pageY, evt.clientX and evt.clientY\n *\n * For touch events pageX and pageY are taken from the first touch;\n * For the emulated mousemove event they are taken from the last real event.\n *\n * @private\n * @param {Event} evt\n */\n SortableList.prototype.calculatePositionOnPage = function(evt) {\n\n if (evt.originalEvent && evt.originalEvent.touches && evt.originalEvent.touches[0] !== undefined) {\n // This is a touchmove or touchstart event, get position from the first touch position.\n var touch = evt.originalEvent.touches[0];\n evt.pageX = touch.pageX;\n evt.pageY = touch.pageY;\n }\n\n if (evt.pageX === undefined) {\n // Information is not present in case of touchend or when event was emulated by autoScroll.\n // Take the absolute mouse position from the last event.\n evt.pageX = this.lastEvent.pageX;\n evt.pageY = this.lastEvent.pageY;\n } else {\n this.lastEvent = evt;\n }\n\n if (evt.clientX === undefined) {\n // If not provided in event calculate relative mouse position.\n evt.clientX = Math.round(evt.pageX - $(window).scrollLeft());\n evt.clientY = Math.round(evt.pageY - $(window).scrollTop());\n }\n };\n\n /**\n * Handler from dragstart event\n *\n * @private\n * @param {Event} evt\n */\n SortableList.prototype.dragStartHandler = function(evt) {\n if (this.info !== null) {\n if (this.info.type === 'click' || this.info.type === 'touchend') {\n // Ignore double click.\n return;\n }\n // Mouse down or touch while already dragging, cancel previous dragging.\n this.moveElement(this.info.sourceList, this.info.sourceNextElement);\n this.finishDragging();\n }\n\n if (evt.type === 'mousedown' && evt.which !== 1) {\n // We only need left mouse click. If this is a mousedown event with right/middle click ignore it.\n return;\n }\n\n this.calculatePositionOnPage(evt);\n var movedElement = $(evt.target).closest($(evt.currentTarget).children());\n if (!movedElement.length) {\n // Can't find the element user wants to drag. They clicked on the list but outside of any element of the list.\n return;\n }\n\n // Check that we grabbed the element by the handle.\n if (this.config.moveHandlerSelector !== null) {\n if (!$(evt.target).closest(this.config.moveHandlerSelector, movedElement).length) {\n return;\n }\n }\n\n evt.stopPropagation();\n evt.preventDefault();\n\n // Information about moved element with original location.\n // This object is passed to event observers.\n this.dragCounter++;\n this.info = {\n element: movedElement,\n sourceNextElement: movedElement.next(),\n sourceList: movedElement.parent(),\n targetNextElement: movedElement.next(),\n targetList: movedElement.parent(),\n type: evt.type,\n dropped: false,\n startX: evt.pageX,\n startY: evt.pageY,\n startTime: new Date().getTime()\n };\n\n $(this.config.targetListSelector).addClass(CSS.targetListClass);\n\n var offset = movedElement.offset();\n movedElement.addClass(CSS.currentPositionClass);\n this.proxyDelta = {x: offset.left - evt.pageX, y: offset.top - evt.pageY};\n this.proxy = $();\n var thisDragCounter = this.dragCounter;\n setTimeout($.proxy(function() {\n // This mousedown event may in fact be a beginning of a 'click' event. Use timeout before showing the\n // dragged object so we can catch click event. When timeout finishes make sure that click event\n // has not happened during this half a second.\n // Verify dragcounter to make sure the user did not manage to do two very fast drag actions one after another.\n if (this.info === null || this.info.type === 'click' || this.info.type === 'keypress'\n || this.dragCounter !== thisDragCounter) {\n return;\n }\n\n // Create a proxy - the copy of the dragged element that moves together with a mouse.\n this.createProxy();\n }, this), 500);\n\n // Start drag.\n $(window).on('mousemove touchmove.notPassive mouseup touchend.notPassive', $.proxy(this.dragHandler, this));\n $(window).on('keypress', $.proxy(this.dragcancelHandler, this));\n\n // Start autoscrolling. Every time the page is scrolled emulate the mousemove event.\n if (this.config.autoScroll) {\n autoScroll.start(function() {\n $(window).trigger('mousemove');\n });\n }\n\n this.executeCallback(SortableList.EVENTS.DRAGSTART);\n };\n\n /**\n * Creates a \"proxy\" object - a copy of the element that is being moved that always follows the mouse\n * @private\n */\n SortableList.prototype.createProxy = function() {\n this.proxy = this.info.element.clone();\n this.info.sourceList.append(this.proxy);\n this.proxy.removeAttr('id').removeClass(CSS.currentPositionClass)\n .addClass(CSS.isDraggedClass).css({position: 'fixed'});\n this.proxy.offset({top: this.proxyDelta.y + this.lastEvent.pageY, left: this.proxyDelta.x + this.lastEvent.pageX});\n };\n\n /**\n * Handler for click event - when user clicks on the drag handler or presses Enter on keyboard\n *\n * @private\n * @param {Event} evt\n */\n SortableList.prototype.clickHandler = function(evt) {\n if (evt.type === 'keypress' && evt.originalEvent.keyCode !== 13 && evt.originalEvent.keyCode !== 32) {\n return;\n }\n if (this.info !== null) {\n // Ignore double click.\n return;\n }\n\n // Find the element that this draghandle belongs to.\n var clickedElement = $(evt.target).closest(this.config.moveHandlerSelector),\n sourceList = clickedElement.closest(this.config.listSelector),\n movedElement = clickedElement.closest(sourceList.children());\n if (!movedElement.length) {\n return;\n }\n\n evt.preventDefault();\n evt.stopPropagation();\n\n // Store information about moved element with original location.\n this.dragCounter++;\n this.info = {\n element: movedElement,\n sourceNextElement: movedElement.next(),\n sourceList: sourceList,\n targetNextElement: movedElement.next(),\n targetList: sourceList,\n dropped: false,\n type: evt.type,\n startTime: new Date().getTime()\n };\n\n this.executeCallback(SortableList.EVENTS.DRAGSTART);\n this.displayMoveDialogue(clickedElement);\n };\n\n /**\n * Finds the position of the mouse inside the element - on the top, on the bottom, on the right or on the left\\\n *\n * Used to determine if the moved element should be moved after or before the current element\n *\n * @private\n * @param {Number} pageX\n * @param {Number} pageY\n * @param {jQuery} element\n * @returns {(Object|null)}\n */\n SortableList.prototype.getPositionInNode = function(pageX, pageY, element) {\n if (!element.length) {\n return null;\n }\n var node = element[0],\n offset = 0,\n rect = node.getBoundingClientRect(),\n y = pageY - (rect.top + window.scrollY),\n x = pageX - (rect.left + window.scrollX);\n if (x >= -offset && x <= rect.width + offset && y >= -offset && y <= rect.height + offset) {\n return {\n x: x,\n y: y,\n xRatio: rect.width ? (x / rect.width) : 0,\n yRatio: rect.height ? (y / rect.height) : 0\n };\n }\n return null;\n };\n\n /**\n * Check if list is horizontal\n *\n * @param {jQuery} element\n * @return {Boolean}\n */\n SortableList.prototype.isListHorizontal = function(element) {\n var isHorizontal = this.config.isHorizontal;\n if (isHorizontal === true || isHorizontal === false) {\n return isHorizontal;\n }\n return isHorizontal(element);\n };\n\n /**\n * Handler for events mousemove touchmove mouseup touchend\n *\n * @private\n * @param {Event} evt\n */\n SortableList.prototype.dragHandler = function(evt) {\n\n evt.preventDefault();\n evt.stopPropagation();\n\n this.calculatePositionOnPage(evt);\n\n // We can not use evt.target here because it will most likely be our proxy.\n // Move the proxy out of the way so we can find the element at the current mouse position.\n this.proxy.offset({top: -1000, left: -1000});\n // Find the element at the current mouse position.\n var element = $(document.elementFromPoint(evt.clientX, evt.clientY));\n\n // Find the list element and the list over the mouse position.\n var mainElement = this.info.element[0],\n isNotSelf = function() {\n return this !== mainElement;\n },\n current = element.closest('.' + CSS.targetListClass + ' > :not(.' + CSS.isDraggedClass + ')').filter(isNotSelf),\n currentList = element.closest('.' + CSS.targetListClass),\n proxy = this.proxy,\n isNotProxy = function() {\n return !proxy || !proxy.length || this !== proxy[0];\n };\n\n // Add the specified class to the list element we are hovering.\n $('.' + CSS.overElementClass).removeClass(CSS.overElementClass);\n current.addClass(CSS.overElementClass);\n\n // Move proxy to the current position.\n this.proxy.offset({top: this.proxyDelta.y + evt.pageY, left: this.proxyDelta.x + evt.pageX});\n\n if (currentList.length && !currentList.children().filter(isNotProxy).length) {\n // Mouse is over an empty list.\n this.moveElement(currentList, $());\n } else if (current.length === 1 && !this.info.element.find(current[0]).length) {\n // Mouse is over an element in a list - find whether we should move the current position\n // above or below this element.\n var coordinates = this.getPositionInNode(evt.pageX, evt.pageY, current);\n if (coordinates) {\n var parent = current.parent(),\n ratio = this.isListHorizontal(parent) ? coordinates.xRatio : coordinates.yRatio,\n subList = current.find('.' + CSS.targetListClass),\n subListEmpty = !subList.children().filter(isNotProxy).filter(isNotSelf).length;\n if (subList.length && subListEmpty && ratio > 0.2 && ratio < 0.8) {\n // This is an element that is a parent of an empty list and we are around the middle of this element.\n // Treat it as if we are over this empty list.\n this.moveElement(subList, $());\n } else if (ratio > 0.5) {\n // Insert after this element.\n this.moveElement(parent, current.next().filter(isNotProxy));\n } else {\n // Insert before this element.\n this.moveElement(parent, current);\n }\n }\n }\n\n if (evt.type === 'mouseup' || evt.type === 'touchend') {\n // Drop the moved element.\n this.info.endX = evt.pageX;\n this.info.endY = evt.pageY;\n this.info.endTime = new Date().getTime();\n this.info.dropped = true;\n this.info.positionChanged = this.hasPositionChanged(this.info);\n var oldinfo = this.info;\n this.executeCallback(SortableList.EVENTS.DROP);\n this.finishDragging();\n\n if (evt.type === 'touchend'\n && this.config.moveHandlerSelector !== null\n && (oldinfo.endTime - oldinfo.startTime < 500)\n && !oldinfo.positionChanged) {\n // The click event is not triggered on touch screens because we call preventDefault in touchstart handler.\n // If the touchend quickly followed touchstart without moving, consider it a \"click\".\n this.clickHandler(evt);\n }\n }\n };\n\n /**\n * Checks if the position of the dragged element in the list has changed\n *\n * @private\n * @param {Object} info\n * @return {Boolean}\n */\n SortableList.prototype.hasPositionChanged = function(info) {\n return info.sourceList[0] !== info.targetList[0] ||\n info.sourceNextElement.length !== info.targetNextElement.length ||\n (info.sourceNextElement.length && info.sourceNextElement[0] !== info.targetNextElement[0]);\n };\n\n /**\n * Moves the current position of the dragged element\n *\n * @private\n * @param {jQuery} parentElement\n * @param {jQuery} beforeElement\n */\n SortableList.prototype.moveElement = function(parentElement, beforeElement) {\n var dragEl = this.info.element;\n if (beforeElement.length && beforeElement[0] === dragEl[0]) {\n // Insert before the current position of the dragged element - nothing to do.\n return;\n }\n if (parentElement[0] === this.info.targetList[0] &&\n beforeElement.length === this.info.targetNextElement.length &&\n beforeElement[0] === this.info.targetNextElement[0]) {\n // Insert in the same location as the current position - nothing to do.\n return;\n }\n\n if (beforeElement.length) {\n // Move the dragged element before the specified element.\n parentElement[0].insertBefore(dragEl[0], beforeElement[0]);\n } else if (this.proxy && this.proxy.parent().length && this.proxy.parent()[0] === parentElement[0]) {\n // We need to move to the end of the list but the last element in this list is a proxy.\n // Always leave the proxy in the end of the list.\n parentElement[0].insertBefore(dragEl[0], this.proxy[0]);\n } else {\n // Insert in the end of a list (when proxy is in another list).\n parentElement[0].appendChild(dragEl[0]);\n }\n\n // Save the current position of the dragged element in the list.\n this.info.targetList = parentElement;\n this.info.targetNextElement = beforeElement;\n this.executeCallback(SortableList.EVENTS.DRAG);\n };\n\n /**\n * Finish dragging (when dropped or cancelled).\n * @private\n */\n SortableList.prototype.finishDragging = function() {\n this.resetDraggedClasses();\n if (this.config.autoScroll) {\n autoScroll.stop();\n }\n $(window).off('mousemove touchmove.notPassive mouseup touchend.notPassive', $.proxy(this.dragHandler, this));\n $(window).off('keypress', $.proxy(this.dragcancelHandler, this));\n this.executeCallback(SortableList.EVENTS.DRAGEND);\n this.info = null;\n };\n\n /**\n * Executes callback specified in sortable list parameters\n *\n * @private\n * @param {String} eventName\n */\n SortableList.prototype.executeCallback = function(eventName) {\n this.info.element.trigger(eventName, this.info);\n };\n\n /**\n * Handler from keypress event (cancel dragging when Esc is pressed)\n *\n * @private\n * @param {Event} evt\n */\n SortableList.prototype.dragcancelHandler = function(evt) {\n if (evt.type !== 'keypress' || evt.originalEvent.keyCode !== 27) {\n // Only cancel dragging when Esc was pressed.\n return;\n }\n // Dragging was cancelled. Return item to the original position.\n this.moveElement(this.info.sourceList, this.info.sourceNextElement);\n this.finishDragging();\n };\n\n /**\n * Returns the name of the current element to be used in the move dialogue\n *\n * @public\n * @param {jQuery} element\n * @return {Promise}\n */\n SortableList.prototype.getElementName = function(element) {\n return $.Deferred().resolve(element.text());\n };\n\n /**\n * Returns the label for the potential move destination, i.e. \"After ElementX\" or \"To the top of the list\"\n *\n * Note that we use \"after\" in the label for better UX\n *\n * @public\n * @param {jQuery} parentElement\n * @param {jQuery} afterElement\n * @return {Promise}\n */\n SortableList.prototype.getDestinationName = function(parentElement, afterElement) {\n if (!afterElement.length) {\n return str.get_string('movecontenttothetop', 'moodle');\n } else {\n return this.getElementName(afterElement)\n .then(function(name) {\n return str.get_string('movecontentafter', 'moodle', name);\n });\n }\n };\n\n /**\n * Returns the title for the move dialogue (\"Move elementY\")\n *\n * @public\n * @param {jQuery} element\n * @param {jQuery} handler\n * @return {Promise}\n */\n SortableList.prototype.getMoveDialogueTitle = function(element, handler) {\n if (handler.attr('title')) {\n return $.Deferred().resolve(handler.attr('title'));\n }\n return this.getElementName(element).then(function(name) {\n return str.get_string('movecontent', 'moodle', name);\n });\n };\n\n /**\n * Returns the list of possible move destinations\n *\n * @private\n * @return {Promise}\n */\n SortableList.prototype.getDestinationsList = function() {\n var addedLists = [],\n targets = $(this.config.targetListSelector),\n destinations = $('').addClass(CSS.keyboardDragClass),\n result = $.when().then(function() {\n return destinations;\n }),\n createLink = $.proxy(function(parentElement, beforeElement, afterElement) {\n if (beforeElement.is(this.info.element) || afterElement.is(this.info.element)) {\n // Can not move before or after itself.\n return;\n }\n if ($.contains(this.info.element[0], parentElement[0])) {\n // Can not move to its own child.\n return;\n }\n result = result\n .then($.proxy(function() {\n return this.getDestinationName(parentElement, afterElement);\n }, this))\n .then(function(txt) {\n var li = $('').appendTo(destinations);\n var a = $('').attr('data-core_sortable_list-quickmove', 1).appendTo(li);\n a.data('parent-element', parentElement).data('before-element', beforeElement).text(txt);\n return destinations;\n });\n }, this),\n addList = function() {\n // Destination lists may be nested. We want to add all move destinations in the same\n // order they appear on the screen for the user.\n if ($.inArray(this, addedLists) !== -1) {\n return;\n }\n addedLists.push(this);\n var list = $(this),\n children = list.children();\n children.each(function() {\n var element = $(this);\n createLink(list, element, element.prev());\n // Add all nested lists.\n element.find(targets).each(addList);\n });\n createLink(list, $(), children.last());\n };\n targets.each(addList);\n return result;\n };\n\n /**\n * Displays the dialogue to move element.\n * @param {jQuery} clickedElement element to return focus to after the modal is closed\n * @private\n */\n SortableList.prototype.displayMoveDialogue = function(clickedElement) {\n ModalFactory.create({\n type: ModalFactory.types.CANCEL,\n title: this.getMoveDialogueTitle(this.info.element, clickedElement),\n body: this.getDestinationsList()\n }).then($.proxy(function(modal) {\n var quickMoveHandler = $.proxy(function(e) {\n e.preventDefault();\n e.stopPropagation();\n this.moveElement($(e.currentTarget).data('parent-element'), $(e.currentTarget).data('before-element'));\n this.info.endTime = new Date().getTime();\n this.info.positionChanged = this.hasPositionChanged(this.info);\n this.info.dropped = true;\n clickedElement.focus();\n this.executeCallback(SortableList.EVENTS.DROP);\n modal.hide();\n }, this);\n modal.getRoot().on('click', '[data-core_sortable_list-quickmove]', quickMoveHandler);\n modal.getRoot().on(ModalEvents.hidden, $.proxy(function() {\n // Always destroy when hidden, it is generated dynamically each time.\n modal.getRoot().off('click', '[data-core_sortable_list-quickmove]', quickMoveHandler);\n modal.destroy();\n this.finishDragging();\n }, this));\n modal.setLarge();\n modal.show();\n return modal;\n }, this)).catch(Notification.exception);\n };\n\n return SortableList;\n\n});\n"],"names":["define","$","log","autoScroll","str","ModalFactory","ModalEvents","Notification","defaultParameters","targetListSelector","moveHandlerSelector","isHorizontal","CSS","registerNotPassiveListeners","eventname","setup","x","ns","handle","includes","addEventListener","passive","options","passivesupported","Object","defineProperty","get","document","removeEventListener","err","event","special","touchstart","touchmove","touchend","SortableList","root","config","info","proxy","proxyDelta","dragCounter","lastEvent","extend","listSelector","this","on","dragStartHandler","clickHandler","EVENTS","DRAGSTART","DRAG","DROP","DRAGEND","prototype","resetDraggedClasses","classes","i","removeClass","remove","calculatePositionOnPage","evt","originalEvent","touches","undefined","touch","pageX","pageY","clientX","Math","round","window","scrollLeft","clientY","scrollTop","type","moveElement","sourceList","sourceNextElement","finishDragging","which","movedElement","target","closest","currentTarget","children","length","stopPropagation","preventDefault","element","next","parent","targetNextElement","targetList","dropped","startX","startY","startTime","Date","getTime","addClass","offset","left","y","top","thisDragCounter","setTimeout","createProxy","dragHandler","dragcancelHandler","start","trigger","executeCallback","clone","append","removeAttr","css","position","keyCode","clickedElement","displayMoveDialogue","getPositionInNode","rect","getBoundingClientRect","scrollY","scrollX","width","height","xRatio","yRatio","isListHorizontal","elementFromPoint","mainElement","isNotSelf","current","filter","currentList","isNotProxy","find","coordinates","ratio","subList","subListEmpty","endX","endY","endTime","positionChanged","hasPositionChanged","oldinfo","parentElement","beforeElement","dragEl","insertBefore","appendChild","stop","off","eventName","getElementName","Deferred","resolve","text","getDestinationName","afterElement","then","name","get_string","getMoveDialogueTitle","handler","attr","getDestinationsList","addedLists","targets","destinations","result","when","createLink","is","contains","txt","li","appendTo","data","addList","inArray","push","list","each","prev","last","create","types","CANCEL","title","body","modal","quickMoveHandler","e","focus","hide","getRoot","hidden","destroy","setLarge","show","catch","exception"],"mappings":"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"}
\ No newline at end of file
diff --git a/lib/amd/src/local/aria/focuslock.js b/lib/amd/src/local/aria/focuslock.js
index 2e628c8e7c0..7ba33e92ed3 100644
--- a/lib/amd/src/local/aria/focuslock.js
+++ b/lib/amd/src/local/aria/focuslock.js
@@ -180,7 +180,6 @@ const attemptFocus = focusTarget => {
focusTarget.focus();
} catch (e) {
// Ignore failures. We will just try to focus the next element in the list.
- // eslint-disable-line
}
ignoreFocusChanges = false;
diff --git a/lib/amd/src/local/reactive/overlay.js b/lib/amd/src/local/reactive/overlay.js
index 2c189e637f4..782632f0bcc 100644
--- a/lib/amd/src/local/reactive/overlay.js
+++ b/lib/amd/src/local/reactive/overlay.js
@@ -67,16 +67,11 @@ export const addOverlay = async(definition, parent) => {
content: definition.content,
css: definition.classes ?? 'file-drop-zone',
};
- let overlay;
- try {
- const {html, js} = await Templates.renderForPromise(overlayTemplate, data);
- Templates.appendNodeContents(parent, html, js);
- overlay = parent.querySelector(selectors.OVERLAY);
- rePositionPreviewInfoElement(overlay);
- init();
- } catch (error) {
- throw error;
- }
+ const {html, js} = await Templates.renderForPromise(overlayTemplate, data);
+ Templates.appendNodeContents(parent, html, js);
+ const overlay = parent.querySelector(selectors.OVERLAY);
+ rePositionPreviewInfoElement(overlay);
+ init();
return overlay;
};
diff --git a/lib/amd/src/sortable_list.js b/lib/amd/src/sortable_list.js
index d85c23d638c..d1ad7d3ba01 100644
--- a/lib/amd/src/sortable_list.js
+++ b/lib/amd/src/sortable_list.js
@@ -103,6 +103,7 @@ function($, log, autoScroll, str, ModalFactory, ModalEvents, Notification) {
try {
options = Object.defineProperty({}, "passive", {
+ // eslint-disable-next-line getter-return
get: function() {
passivesupported = true;
}
diff --git a/lib/editor/tiny/plugins/accessibilitychecker/amd/build/plugin.min.js.map b/lib/editor/tiny/plugins/accessibilitychecker/amd/build/plugin.min.js.map
index 87ef18160dd..cb0c22f3048 100644
--- a/lib/editor/tiny/plugins/accessibilitychecker/amd/build/plugin.min.js.map
+++ b/lib/editor/tiny/plugins/accessibilitychecker/amd/build/plugin.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"plugin.min.js","sources":["../src/plugin.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Tiny Media Manager plugin for Moodle.\n *\n * @module tiny_accessibilitychecker/plugin\n * @copyright 2022, Stevani Andolo \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {getTinyMCE} from 'editor_tiny/loader';\nimport {getPluginMetadata} from 'editor_tiny/utils';\n\nimport {component, pluginName} from './common';\nimport * as Commands from './commands';\nimport * as Configuration from './configuration';\n\nexport default new Promise(async(resolve) => {\n const [\n tinyMCE,\n setupCommands,\n pluginMetadata,\n ] = await Promise.all([\n getTinyMCE(),\n Commands.getSetup(),\n getPluginMetadata(component, pluginName),\n ]);\n\n tinyMCE.PluginManager.add(`${component}/plugin`, (editor) => {\n // Setup the Commands (buttons, menu items, and so on).\n setupCommands(editor);\n\n return pluginMetadata;\n });\n\n // Resolve the Media Plugin and include configuration.\n resolve([`${component}/plugin`, Configuration]);\n});\n"],"names":["Promise","async","tinyMCE","setupCommands","pluginMetadata","all","Commands","getSetup","component","pluginName","PluginManager","add","editor","resolve","Configuration"],"mappings":";;;;;;;kMA6Be,IAAIA,SAAQC,MAAAA,gBAEnBC,QACAC,cACAC,sBACMJ,QAAQK,IAAI,EAClB,wBACAC,SAASC,YACT,4BAAkBC,kBAAWC,sBAGjCP,QAAQQ,cAAcC,cAAOH,8BAAqBI,SAE9CT,cAAcS,QAEPR,kBAIXS,QAAQ,WAAIL,6BAAoBM"}
\ No newline at end of file
+{"version":3,"file":"plugin.min.js","sources":["../src/plugin.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Tiny Media Manager plugin for Moodle.\n *\n * @module tiny_accessibilitychecker/plugin\n * @copyright 2022, Stevani Andolo \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {getTinyMCE} from 'editor_tiny/loader';\nimport {getPluginMetadata} from 'editor_tiny/utils';\n\nimport {component, pluginName} from './common';\nimport * as Commands from './commands';\nimport * as Configuration from './configuration';\n\n// eslint-disable-next-line no-async-promise-executor\nexport default new Promise(async(resolve) => {\n const [\n tinyMCE,\n setupCommands,\n pluginMetadata,\n ] = await Promise.all([\n getTinyMCE(),\n Commands.getSetup(),\n getPluginMetadata(component, pluginName),\n ]);\n\n tinyMCE.PluginManager.add(`${component}/plugin`, (editor) => {\n // Setup the Commands (buttons, menu items, and so on).\n setupCommands(editor);\n\n return pluginMetadata;\n });\n\n // Resolve the Media Plugin and include configuration.\n resolve([`${component}/plugin`, Configuration]);\n});\n"],"names":["Promise","async","tinyMCE","setupCommands","pluginMetadata","all","Commands","getSetup","component","pluginName","PluginManager","add","editor","resolve","Configuration"],"mappings":";;;;;;;kMA8Be,IAAIA,SAAQC,MAAAA,gBAEnBC,QACAC,cACAC,sBACMJ,QAAQK,IAAI,EAClB,wBACAC,SAASC,YACT,4BAAkBC,kBAAWC,sBAGjCP,QAAQQ,cAAcC,cAAOH,8BAAqBI,SAE9CT,cAAcS,QAEPR,kBAIXS,QAAQ,WAAIL,6BAAoBM"}
\ No newline at end of file
diff --git a/lib/editor/tiny/plugins/accessibilitychecker/amd/src/plugin.js b/lib/editor/tiny/plugins/accessibilitychecker/amd/src/plugin.js
index 00cf71f5bc1..4e7292cde38 100644
--- a/lib/editor/tiny/plugins/accessibilitychecker/amd/src/plugin.js
+++ b/lib/editor/tiny/plugins/accessibilitychecker/amd/src/plugin.js
@@ -27,6 +27,7 @@ import {component, pluginName} from './common';
import * as Commands from './commands';
import * as Configuration from './configuration';
+// eslint-disable-next-line no-async-promise-executor
export default new Promise(async(resolve) => {
const [
tinyMCE,
diff --git a/lib/editor/tiny/plugins/autosave/amd/build/plugin.min.js.map b/lib/editor/tiny/plugins/autosave/amd/build/plugin.min.js.map
index 6b9d9e5335c..7143368b39c 100644
--- a/lib/editor/tiny/plugins/autosave/amd/build/plugin.min.js.map
+++ b/lib/editor/tiny/plugins/autosave/amd/build/plugin.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"plugin.min.js","sources":["../src/plugin.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Tiny Autosave plugin for Moodle.\n *\n * @module tiny_autosave/plugin\n * @copyright 2022 Andrew Lyons \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {getTinyMCE} from 'editor_tiny/loader';\nimport {getPluginMetadata} from 'editor_tiny/utils';\n\nimport {component, pluginName} from './common';\nimport * as Options from './options';\nimport * as Autosaver from './autosaver';\n\n// Setup the autosave Plugin.\nexport default new Promise(async(resolve) => {\n const [tinyMCE, pluginMetadata] = await Promise.all([\n getTinyMCE(),\n getPluginMetadata(component, pluginName),\n ]);\n\n // Note: The PluginManager.add function does not accept a Promise.\n // Any asynchronous code must be run before this point.\n tinyMCE.PluginManager.add(pluginName, (editor) => {\n // Register options.\n Options.register(editor);\n\n // Register the Autosaver.\n Autosaver.register(editor);\n\n return pluginMetadata;\n });\n\n resolve(pluginName);\n});\n"],"names":["Promise","async","tinyMCE","pluginMetadata","all","component","pluginName","PluginManager","add","editor","Options","register","Autosaver","resolve"],"mappings":";;;;;;;wLA8Be,IAAIA,SAAQC,MAAAA,gBAChBC,QAASC,sBAAwBH,QAAQI,IAAI,EAChD,yBACA,4BAAkBC,kBAAWC,sBAKjCJ,QAAQK,cAAcC,IAAIF,oBAAaG,SAEnCC,QAAQC,SAASF,QAGjBG,UAAUD,SAASF,QAEZN,kBAGXU,QAAQP"}
\ No newline at end of file
+{"version":3,"file":"plugin.min.js","sources":["../src/plugin.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Tiny Autosave plugin for Moodle.\n *\n * @module tiny_autosave/plugin\n * @copyright 2022 Andrew Lyons \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {getTinyMCE} from 'editor_tiny/loader';\nimport {getPluginMetadata} from 'editor_tiny/utils';\n\nimport {component, pluginName} from './common';\nimport * as Options from './options';\nimport * as Autosaver from './autosaver';\n\n// Setup the autosave Plugin.\n// eslint-disable-next-line no-async-promise-executor\nexport default new Promise(async(resolve) => {\n const [tinyMCE, pluginMetadata] = await Promise.all([\n getTinyMCE(),\n getPluginMetadata(component, pluginName),\n ]);\n\n // Note: The PluginManager.add function does not accept a Promise.\n // Any asynchronous code must be run before this point.\n tinyMCE.PluginManager.add(pluginName, (editor) => {\n // Register options.\n Options.register(editor);\n\n // Register the Autosaver.\n Autosaver.register(editor);\n\n return pluginMetadata;\n });\n\n resolve(pluginName);\n});\n"],"names":["Promise","async","tinyMCE","pluginMetadata","all","component","pluginName","PluginManager","add","editor","Options","register","Autosaver","resolve"],"mappings":";;;;;;;wLA+Be,IAAIA,SAAQC,MAAAA,gBAChBC,QAASC,sBAAwBH,QAAQI,IAAI,EAChD,yBACA,4BAAkBC,kBAAWC,sBAKjCJ,QAAQK,cAAcC,IAAIF,oBAAaG,SAEnCC,QAAQC,SAASF,QAGjBG,UAAUD,SAASF,QAEZN,kBAGXU,QAAQP"}
\ No newline at end of file
diff --git a/lib/editor/tiny/plugins/autosave/amd/src/plugin.js b/lib/editor/tiny/plugins/autosave/amd/src/plugin.js
index 868201d1b5b..73041da62d3 100644
--- a/lib/editor/tiny/plugins/autosave/amd/src/plugin.js
+++ b/lib/editor/tiny/plugins/autosave/amd/src/plugin.js
@@ -28,6 +28,7 @@ import * as Options from './options';
import * as Autosaver from './autosaver';
// Setup the autosave Plugin.
+// eslint-disable-next-line no-async-promise-executor
export default new Promise(async(resolve) => {
const [tinyMCE, pluginMetadata] = await Promise.all([
getTinyMCE(),
diff --git a/lib/editor/tiny/plugins/equation/amd/build/plugin.min.js.map b/lib/editor/tiny/plugins/equation/amd/build/plugin.min.js.map
index 7a5bd871ae5..44772306948 100644
--- a/lib/editor/tiny/plugins/equation/amd/build/plugin.min.js.map
+++ b/lib/editor/tiny/plugins/equation/amd/build/plugin.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"plugin.min.js","sources":["../src/plugin.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Tiny Equation plugin for Moodle.\n *\n * @module tiny_equation/plugin\n * @copyright 2022 Huong Nguyen \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {getTinyMCE} from 'editor_tiny/loader';\nimport {getPluginMetadata} from 'editor_tiny/utils';\n\nimport {component, pluginName} from 'tiny_equation/common';\nimport * as Commands from 'tiny_equation/commands';\nimport * as Configuration from 'tiny_equation/configuration';\nimport * as Options from 'tiny_equation/options';\n\nexport default new Promise(async(resolve) => {\n const [\n tinyMCE,\n setupCommands,\n pluginMetadata,\n ] = await Promise.all([\n getTinyMCE(),\n Commands.getSetup(),\n getPluginMetadata(component, pluginName),\n ]);\n\n tinyMCE.PluginManager.add(`${component}/plugin`, (editor) => {\n // Register options.\n Options.register(editor);\n\n // Setup the Commands (buttons, menu items, and so on).\n setupCommands(editor);\n\n return pluginMetadata;\n });\n\n // Resolve the Equation Plugin and include configuration.\n resolve([`${component}/plugin`, Configuration]);\n});\n"],"names":["Promise","async","tinyMCE","setupCommands","pluginMetadata","all","Commands","getSetup","component","pluginName","PluginManager","add","editor","Options","register","resolve","Configuration"],"mappings":";;;;;;;2OA+Be,IAAIA,SAAQC,MAAAA,gBAEnBC,QACAC,cACAC,sBACMJ,QAAQK,IAAI,EAClB,wBACAC,SAASC,YACT,4BAAkBC,kBAAWC,sBAGjCP,QAAQQ,cAAcC,cAAOH,8BAAqBI,SAE9CC,QAAQC,SAASF,QAGjBT,cAAcS,QAEPR,kBAIXW,QAAQ,WAAIP,6BAAoBQ"}
\ No newline at end of file
+{"version":3,"file":"plugin.min.js","sources":["../src/plugin.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Tiny Equation plugin for Moodle.\n *\n * @module tiny_equation/plugin\n * @copyright 2022 Huong Nguyen \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {getTinyMCE} from 'editor_tiny/loader';\nimport {getPluginMetadata} from 'editor_tiny/utils';\n\nimport {component, pluginName} from 'tiny_equation/common';\nimport * as Commands from 'tiny_equation/commands';\nimport * as Configuration from 'tiny_equation/configuration';\nimport * as Options from 'tiny_equation/options';\n\n// eslint-disable-next-line no-async-promise-executor\nexport default new Promise(async(resolve) => {\n const [\n tinyMCE,\n setupCommands,\n pluginMetadata,\n ] = await Promise.all([\n getTinyMCE(),\n Commands.getSetup(),\n getPluginMetadata(component, pluginName),\n ]);\n\n tinyMCE.PluginManager.add(`${component}/plugin`, (editor) => {\n // Register options.\n Options.register(editor);\n\n // Setup the Commands (buttons, menu items, and so on).\n setupCommands(editor);\n\n return pluginMetadata;\n });\n\n // Resolve the Equation Plugin and include configuration.\n resolve([`${component}/plugin`, Configuration]);\n});\n"],"names":["Promise","async","tinyMCE","setupCommands","pluginMetadata","all","Commands","getSetup","component","pluginName","PluginManager","add","editor","Options","register","resolve","Configuration"],"mappings":";;;;;;;2OAgCe,IAAIA,SAAQC,MAAAA,gBAEnBC,QACAC,cACAC,sBACMJ,QAAQK,IAAI,EAClB,wBACAC,SAASC,YACT,4BAAkBC,kBAAWC,sBAGjCP,QAAQQ,cAAcC,cAAOH,8BAAqBI,SAE9CC,QAAQC,SAASF,QAGjBT,cAAcS,QAEPR,kBAIXW,QAAQ,WAAIP,6BAAoBQ"}
\ No newline at end of file
diff --git a/lib/editor/tiny/plugins/equation/amd/src/plugin.js b/lib/editor/tiny/plugins/equation/amd/src/plugin.js
index 798231477a7..6d5eb3112ee 100644
--- a/lib/editor/tiny/plugins/equation/amd/src/plugin.js
+++ b/lib/editor/tiny/plugins/equation/amd/src/plugin.js
@@ -29,6 +29,7 @@ import * as Commands from 'tiny_equation/commands';
import * as Configuration from 'tiny_equation/configuration';
import * as Options from 'tiny_equation/options';
+// eslint-disable-next-line no-async-promise-executor
export default new Promise(async(resolve) => {
const [
tinyMCE,
diff --git a/lib/editor/tiny/plugins/h5p/amd/build/plugin.min.js.map b/lib/editor/tiny/plugins/h5p/amd/build/plugin.min.js.map
index caf967b7e4b..c5c4b3caeae 100644
--- a/lib/editor/tiny/plugins/h5p/amd/build/plugin.min.js.map
+++ b/lib/editor/tiny/plugins/h5p/amd/build/plugin.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"plugin.min.js","sources":["../src/plugin.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Tiny H5P plugin for Moodle.\n *\n * @module tiny_h5p/plugin\n * @copyright 2022 Andrew Lyons \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {getTinyMCE} from 'editor_tiny/loader';\nimport {getPluginMetadata} from 'editor_tiny/utils';\n\nimport {component, pluginName} from './common';\nimport * as FilterContent from './filtercontent';\nimport * as Commands from './commands';\nimport * as Configuration from './configuration';\nimport * as Options from './options';\n\n// Setup the H5P Plugin to add a button and menu option.\nexport default new Promise(async(resolve) => {\n const [\n tinyMCE,\n setupCommands,\n pluginMetadata,\n ] = await Promise.all([\n getTinyMCE(),\n Commands.getSetup(),\n getPluginMetadata(component, pluginName),\n ]);\n\n // Note: The PluginManager.add function does not accept a Promise.\n // Any asynchronous code must be run before this point.\n tinyMCE.PluginManager.add(`${component}/plugin`, (editor) => {\n // Register options.\n Options.register(editor);\n\n // Setup the Formatter.\n FilterContent.setup(editor);\n\n // Setup the Commands (buttons, menu items, and so on).\n setupCommands(editor);\n\n return pluginMetadata;\n });\n\n // Resolve the H5P Plugin and include configuration.\n resolve([`${component}/plugin`, Configuration]);\n});\n"],"names":["Promise","async","tinyMCE","setupCommands","pluginMetadata","all","Commands","getSetup","component","pluginName","PluginManager","add","editor","Options","register","FilterContent","setup","resolve","Configuration"],"mappings":";;;;;;;gSAgCe,IAAIA,SAAQC,MAAAA,gBAEnBC,QACAC,cACAC,sBACMJ,QAAQK,IAAI,EAClB,wBACAC,SAASC,YACT,4BAAkBC,kBAAWC,sBAKjCP,QAAQQ,cAAcC,cAAOH,8BAAqBI,SAE9CC,QAAQC,SAASF,QAGjBG,cAAcC,MAAMJ,QAGpBT,cAAcS,QAEPR,kBAIXa,QAAQ,WAAIT,6BAAoBU"}
\ No newline at end of file
+{"version":3,"file":"plugin.min.js","sources":["../src/plugin.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Tiny H5P plugin for Moodle.\n *\n * @module tiny_h5p/plugin\n * @copyright 2022 Andrew Lyons \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {getTinyMCE} from 'editor_tiny/loader';\nimport {getPluginMetadata} from 'editor_tiny/utils';\n\nimport {component, pluginName} from './common';\nimport * as FilterContent from './filtercontent';\nimport * as Commands from './commands';\nimport * as Configuration from './configuration';\nimport * as Options from './options';\n\n// Setup the H5P Plugin to add a button and menu option.\n// eslint-disable-next-line no-async-promise-executor\nexport default new Promise(async(resolve) => {\n const [\n tinyMCE,\n setupCommands,\n pluginMetadata,\n ] = await Promise.all([\n getTinyMCE(),\n Commands.getSetup(),\n getPluginMetadata(component, pluginName),\n ]);\n\n // Note: The PluginManager.add function does not accept a Promise.\n // Any asynchronous code must be run before this point.\n tinyMCE.PluginManager.add(`${component}/plugin`, (editor) => {\n // Register options.\n Options.register(editor);\n\n // Setup the Formatter.\n FilterContent.setup(editor);\n\n // Setup the Commands (buttons, menu items, and so on).\n setupCommands(editor);\n\n return pluginMetadata;\n });\n\n // Resolve the H5P Plugin and include configuration.\n resolve([`${component}/plugin`, Configuration]);\n});\n"],"names":["Promise","async","tinyMCE","setupCommands","pluginMetadata","all","Commands","getSetup","component","pluginName","PluginManager","add","editor","Options","register","FilterContent","setup","resolve","Configuration"],"mappings":";;;;;;;gSAiCe,IAAIA,SAAQC,MAAAA,gBAEnBC,QACAC,cACAC,sBACMJ,QAAQK,IAAI,EAClB,wBACAC,SAASC,YACT,4BAAkBC,kBAAWC,sBAKjCP,QAAQQ,cAAcC,cAAOH,8BAAqBI,SAE9CC,QAAQC,SAASF,QAGjBG,cAAcC,MAAMJ,QAGpBT,cAAcS,QAEPR,kBAIXa,QAAQ,WAAIT,6BAAoBU"}
\ No newline at end of file
diff --git a/lib/editor/tiny/plugins/h5p/amd/src/plugin.js b/lib/editor/tiny/plugins/h5p/amd/src/plugin.js
index 68450d4b10a..ea055cf60e6 100644
--- a/lib/editor/tiny/plugins/h5p/amd/src/plugin.js
+++ b/lib/editor/tiny/plugins/h5p/amd/src/plugin.js
@@ -30,6 +30,7 @@ import * as Configuration from './configuration';
import * as Options from './options';
// Setup the H5P Plugin to add a button and menu option.
+// eslint-disable-next-line no-async-promise-executor
export default new Promise(async(resolve) => {
const [
tinyMCE,
diff --git a/lib/editor/tiny/plugins/link/amd/build/plugin.min.js.map b/lib/editor/tiny/plugins/link/amd/build/plugin.min.js.map
index 980545c2cce..87ba765fb44 100644
--- a/lib/editor/tiny/plugins/link/amd/build/plugin.min.js.map
+++ b/lib/editor/tiny/plugins/link/amd/build/plugin.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"plugin.min.js","sources":["../src/plugin.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\nimport {getTinyMCE} from 'editor_tiny/loader';\nimport {getPluginMetadata} from 'editor_tiny/utils';\n\nimport {component, pluginName} from 'tiny_link/common';\nimport * as Commands from 'tiny_link/commands';\nimport * as Configuration from 'tiny_link/configuration';\nimport * as Options from 'tiny_link/options';\n\n/**\n * Tiny Link plugin for Moodle.\n *\n * @module tiny_link/plugin\n * @copyright 2023 Huong Nguyen \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nexport default new Promise(async(resolve) => {\n const [\n tinyMCE,\n setupCommands,\n pluginMetadata,\n ] = await Promise.all([\n getTinyMCE(),\n Commands.getSetup(),\n getPluginMetadata(component, pluginName),\n ]);\n\n tinyMCE.PluginManager.add(`${component}/plugin`, (editor) => {\n // Register options.\n Options.register(editor);\n // Setup the Commands (buttons, menu items, and so on).\n setupCommands(editor);\n\n return pluginMetadata;\n });\n\n // Resolve the Link Plugin and include configuration.\n resolve([`${component}/plugin`, Configuration]);\n});\n"],"names":["Promise","async","tinyMCE","setupCommands","pluginMetadata","all","Commands","getSetup","component","pluginName","PluginManager","add","editor","Options","register","resolve","Configuration"],"mappings":";;;;;;;2OA+Be,IAAIA,SAAQC,MAAAA,gBAEnBC,QACAC,cACAC,sBACMJ,QAAQK,IAAI,EAClB,wBACAC,SAASC,YACT,4BAAkBC,kBAAWC,sBAGjCP,QAAQQ,cAAcC,cAAOH,8BAAqBI,SAE9CC,QAAQC,SAASF,QAEjBT,cAAcS,QAEPR,kBAIXW,QAAQ,WAAIP,6BAAoBQ"}
\ No newline at end of file
+{"version":3,"file":"plugin.min.js","sources":["../src/plugin.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\nimport {getTinyMCE} from 'editor_tiny/loader';\nimport {getPluginMetadata} from 'editor_tiny/utils';\n\nimport {component, pluginName} from 'tiny_link/common';\nimport * as Commands from 'tiny_link/commands';\nimport * as Configuration from 'tiny_link/configuration';\nimport * as Options from 'tiny_link/options';\n\n/**\n * Tiny Link plugin for Moodle.\n *\n * @module tiny_link/plugin\n * @copyright 2023 Huong Nguyen \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n// eslint-disable-next-line no-async-promise-executor\nexport default new Promise(async(resolve) => {\n const [\n tinyMCE,\n setupCommands,\n pluginMetadata,\n ] = await Promise.all([\n getTinyMCE(),\n Commands.getSetup(),\n getPluginMetadata(component, pluginName),\n ]);\n\n tinyMCE.PluginManager.add(`${component}/plugin`, (editor) => {\n // Register options.\n Options.register(editor);\n // Setup the Commands (buttons, menu items, and so on).\n setupCommands(editor);\n\n return pluginMetadata;\n });\n\n // Resolve the Link Plugin and include configuration.\n resolve([`${component}/plugin`, Configuration]);\n});\n"],"names":["Promise","async","tinyMCE","setupCommands","pluginMetadata","all","Commands","getSetup","component","pluginName","PluginManager","add","editor","Options","register","resolve","Configuration"],"mappings":";;;;;;;2OAgCe,IAAIA,SAAQC,MAAAA,gBAEnBC,QACAC,cACAC,sBACMJ,QAAQK,IAAI,EAClB,wBACAC,SAASC,YACT,4BAAkBC,kBAAWC,sBAGjCP,QAAQQ,cAAcC,cAAOH,8BAAqBI,SAE9CC,QAAQC,SAASF,QAEjBT,cAAcS,QAEPR,kBAIXW,QAAQ,WAAIP,6BAAoBQ"}
\ No newline at end of file
diff --git a/lib/editor/tiny/plugins/link/amd/src/plugin.js b/lib/editor/tiny/plugins/link/amd/src/plugin.js
index abe4262e405..7713d36a2b9 100644
--- a/lib/editor/tiny/plugins/link/amd/src/plugin.js
+++ b/lib/editor/tiny/plugins/link/amd/src/plugin.js
@@ -29,6 +29,7 @@ import * as Options from 'tiny_link/options';
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
+// eslint-disable-next-line no-async-promise-executor
export default new Promise(async(resolve) => {
const [
tinyMCE,
diff --git a/lib/editor/tiny/plugins/media/amd/build/plugin.min.js.map b/lib/editor/tiny/plugins/media/amd/build/plugin.min.js.map
index 947b68adac8..993d93f8a90 100644
--- a/lib/editor/tiny/plugins/media/amd/build/plugin.min.js.map
+++ b/lib/editor/tiny/plugins/media/amd/build/plugin.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"plugin.min.js","sources":["../src/plugin.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Tiny Media plugin for Moodle.\n *\n * @module tiny_media/plugin\n * @copyright 2022 Andrew Lyons \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {getTinyMCE} from 'editor_tiny/loader';\nimport {getPluginMetadata} from 'editor_tiny/utils';\n\nimport {component, pluginName} from './common';\nimport * as Commands from './commands';\nimport * as Configuration from './configuration';\nimport * as Options from './options';\n\nexport default new Promise(async(resolve) => {\n const [\n tinyMCE,\n setupCommands,\n pluginMetadata,\n ] = await Promise.all([\n getTinyMCE(),\n Commands.getSetup(),\n getPluginMetadata(component, pluginName),\n ]);\n\n tinyMCE.PluginManager.add(`${component}/plugin`, (editor) => {\n // Register options.\n Options.register(editor);\n\n // Setup the Commands (buttons, menu items, and so on).\n setupCommands(editor);\n\n return pluginMetadata;\n });\n\n // Resolve the Media Plugin and include configuration.\n resolve([`${component}/plugin`, Configuration]);\n});\n"],"names":["Promise","async","tinyMCE","setupCommands","pluginMetadata","all","Commands","getSetup","component","pluginName","PluginManager","add","editor","Options","register","resolve","Configuration"],"mappings":";;;;;;;2OA8Be,IAAIA,SAAQC,MAAAA,gBAEnBC,QACAC,cACAC,sBACMJ,QAAQK,IAAI,EAClB,wBACAC,SAASC,YACT,4BAAkBC,kBAAWC,sBAGjCP,QAAQQ,cAAcC,cAAOH,8BAAqBI,SAE9CC,QAAQC,SAASF,QAGjBT,cAAcS,QAEPR,kBAIXW,QAAQ,WAAIP,6BAAoBQ"}
\ No newline at end of file
+{"version":3,"file":"plugin.min.js","sources":["../src/plugin.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Tiny Media plugin for Moodle.\n *\n * @module tiny_media/plugin\n * @copyright 2022 Andrew Lyons \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {getTinyMCE} from 'editor_tiny/loader';\nimport {getPluginMetadata} from 'editor_tiny/utils';\n\nimport {component, pluginName} from './common';\nimport * as Commands from './commands';\nimport * as Configuration from './configuration';\nimport * as Options from './options';\n\n// eslint-disable-next-line no-async-promise-executor\nexport default new Promise(async(resolve) => {\n const [\n tinyMCE,\n setupCommands,\n pluginMetadata,\n ] = await Promise.all([\n getTinyMCE(),\n Commands.getSetup(),\n getPluginMetadata(component, pluginName),\n ]);\n\n tinyMCE.PluginManager.add(`${component}/plugin`, (editor) => {\n // Register options.\n Options.register(editor);\n\n // Setup the Commands (buttons, menu items, and so on).\n setupCommands(editor);\n\n return pluginMetadata;\n });\n\n // Resolve the Media Plugin and include configuration.\n resolve([`${component}/plugin`, Configuration]);\n});\n"],"names":["Promise","async","tinyMCE","setupCommands","pluginMetadata","all","Commands","getSetup","component","pluginName","PluginManager","add","editor","Options","register","resolve","Configuration"],"mappings":";;;;;;;2OA+Be,IAAIA,SAAQC,MAAAA,gBAEnBC,QACAC,cACAC,sBACMJ,QAAQK,IAAI,EAClB,wBACAC,SAASC,YACT,4BAAkBC,kBAAWC,sBAGjCP,QAAQQ,cAAcC,cAAOH,8BAAqBI,SAE9CC,QAAQC,SAASF,QAGjBT,cAAcS,QAEPR,kBAIXW,QAAQ,WAAIP,6BAAoBQ"}
\ No newline at end of file
diff --git a/lib/editor/tiny/plugins/media/amd/src/plugin.js b/lib/editor/tiny/plugins/media/amd/src/plugin.js
index e794fb8436e..9de6d942ad5 100644
--- a/lib/editor/tiny/plugins/media/amd/src/plugin.js
+++ b/lib/editor/tiny/plugins/media/amd/src/plugin.js
@@ -28,6 +28,7 @@ import * as Commands from './commands';
import * as Configuration from './configuration';
import * as Options from './options';
+// eslint-disable-next-line no-async-promise-executor
export default new Promise(async(resolve) => {
const [
tinyMCE,
diff --git a/lib/editor/tiny/plugins/recordrtc/amd/build/plugin.min.js.map b/lib/editor/tiny/plugins/recordrtc/amd/build/plugin.min.js.map
index c5139d32c81..508e92f5783 100644
--- a/lib/editor/tiny/plugins/recordrtc/amd/build/plugin.min.js.map
+++ b/lib/editor/tiny/plugins/recordrtc/amd/build/plugin.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"plugin.min.js","sources":["../src/plugin.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Tiny Record RTC plugin for Moodle.\n *\n * @module tiny_recordrtc/plugin\n * @copyright 2022, Stevani Andolo \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {getTinyMCE} from 'editor_tiny/loader';\nimport {getPluginMetadata} from 'editor_tiny/utils';\nimport getSetupAudioCommands from './commands_audio';\nimport getSetupVideoCommands from './commands_video';\nimport * as Configuration from './configuration';\nimport * as Options from './options';\nimport {\n component,\n pluginName\n} from './common';\n\nexport default new Promise(async(resolve) => {\n const [\n tinyMCE,\n setupAudioCommands,\n setupVideoCommands,\n pluginMetadata,\n ] = await Promise.all([\n getTinyMCE(),\n getSetupAudioCommands(),\n getSetupVideoCommands(),\n getPluginMetadata(component, pluginName),\n ]);\n\n tinyMCE.PluginManager.add(`${component}/plugin`, (editor) => {\n // Register options.\n Options.register(editor);\n\n // Setup the Commands (buttons, menu items, and so on) for video.\n setupVideoCommands(editor);\n\n // Setup the Commands (buttons, menu items, and so on) for audio.\n setupAudioCommands(editor);\n\n return pluginMetadata;\n });\n\n // Resolve the Media Plugin and include configuration.\n resolve([`${component}/plugin`, Configuration]);\n});\n"],"names":["Promise","async","tinyMCE","setupAudioCommands","setupVideoCommands","pluginMetadata","all","component","pluginName","PluginManager","add","editor","Options","register","resolve","Configuration"],"mappings":";;;;;;;gTAiCe,IAAIA,SAAQC,MAAAA,gBAEnBC,QACAC,mBACAC,mBACAC,sBACML,QAAQM,IAAI,EAClB,yBACA,8BACA,8BACA,4BAAkBC,kBAAWC,sBAGjCN,QAAQO,cAAcC,cAAOH,8BAAqBI,SAE9CC,QAAQC,SAASF,QAGjBP,mBAAmBO,QAGnBR,mBAAmBQ,QAEZN,kBAIXS,QAAQ,WAAIP,6BAAoBQ"}
\ No newline at end of file
+{"version":3,"file":"plugin.min.js","sources":["../src/plugin.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Tiny Record RTC plugin for Moodle.\n *\n * @module tiny_recordrtc/plugin\n * @copyright 2022, Stevani Andolo \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {getTinyMCE} from 'editor_tiny/loader';\nimport {getPluginMetadata} from 'editor_tiny/utils';\nimport getSetupAudioCommands from './commands_audio';\nimport getSetupVideoCommands from './commands_video';\nimport * as Configuration from './configuration';\nimport * as Options from './options';\nimport {\n component,\n pluginName\n} from './common';\n\n// eslint-disable-next-line no-async-promise-executor\nexport default new Promise(async(resolve) => {\n const [\n tinyMCE,\n setupAudioCommands,\n setupVideoCommands,\n pluginMetadata,\n ] = await Promise.all([\n getTinyMCE(),\n getSetupAudioCommands(),\n getSetupVideoCommands(),\n getPluginMetadata(component, pluginName),\n ]);\n\n tinyMCE.PluginManager.add(`${component}/plugin`, (editor) => {\n // Register options.\n Options.register(editor);\n\n // Setup the Commands (buttons, menu items, and so on) for video.\n setupVideoCommands(editor);\n\n // Setup the Commands (buttons, menu items, and so on) for audio.\n setupAudioCommands(editor);\n\n return pluginMetadata;\n });\n\n // Resolve the Media Plugin and include configuration.\n resolve([`${component}/plugin`, Configuration]);\n});\n"],"names":["Promise","async","tinyMCE","setupAudioCommands","setupVideoCommands","pluginMetadata","all","component","pluginName","PluginManager","add","editor","Options","register","resolve","Configuration"],"mappings":";;;;;;;gTAkCe,IAAIA,SAAQC,MAAAA,gBAEnBC,QACAC,mBACAC,mBACAC,sBACML,QAAQM,IAAI,EAClB,yBACA,8BACA,8BACA,4BAAkBC,kBAAWC,sBAGjCN,QAAQO,cAAcC,cAAOH,8BAAqBI,SAE9CC,QAAQC,SAASF,QAGjBP,mBAAmBO,QAGnBR,mBAAmBQ,QAEZN,kBAIXS,QAAQ,WAAIP,6BAAoBQ"}
\ No newline at end of file
diff --git a/lib/editor/tiny/plugins/recordrtc/amd/src/plugin.js b/lib/editor/tiny/plugins/recordrtc/amd/src/plugin.js
index 1a72bce8430..d901119ddc7 100644
--- a/lib/editor/tiny/plugins/recordrtc/amd/src/plugin.js
+++ b/lib/editor/tiny/plugins/recordrtc/amd/src/plugin.js
@@ -31,6 +31,7 @@ import {
pluginName
} from './common';
+// eslint-disable-next-line no-async-promise-executor
export default new Promise(async(resolve) => {
const [
tinyMCE,
diff --git a/mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor-debug.js b/mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor-debug.js
index bbca05bc937..80f64403e28 100644
--- a/mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor-debug.js
+++ b/mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor-debug.js
@@ -4911,6 +4911,7 @@ EDITOR.prototype = {
try {
options = Object.defineProperty({}, "passive", {
+ // eslint-disable-next-line getter-return
get: function() {
passivesupported = true;
}
diff --git a/mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor.js b/mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor.js
index bbca05bc937..80f64403e28 100644
--- a/mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor.js
+++ b/mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor.js
@@ -4911,6 +4911,7 @@ EDITOR.prototype = {
try {
options = Object.defineProperty({}, "passive", {
+ // eslint-disable-next-line getter-return
get: function() {
passivesupported = true;
}
diff --git a/mod/assign/feedback/editpdf/yui/src/editor/js/editor.js b/mod/assign/feedback/editpdf/yui/src/editor/js/editor.js
index aff9d819da6..960a1745b22 100644
--- a/mod/assign/feedback/editpdf/yui/src/editor/js/editor.js
+++ b/mod/assign/feedback/editpdf/yui/src/editor/js/editor.js
@@ -1614,6 +1614,7 @@ EDITOR.prototype = {
try {
options = Object.defineProperty({}, "passive", {
+ // eslint-disable-next-line getter-return
get: function() {
passivesupported = true;
}
diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json
index 2b1985c621b..bf277244ea1 100644
--- a/npm-shrinkwrap.json
+++ b/npm-shrinkwrap.json
@@ -8,22 +8,17 @@
"devDependencies": {
"@babel/core": "7.17.5",
"@babel/eslint-parser": "^7.21.3",
- "@babel/plugin-proposal-class-properties": "7.16.7",
- "@babel/plugin-proposal-json-strings": "7.16.7",
- "@babel/plugin-syntax-dynamic-import": "7.8.3",
- "@babel/plugin-syntax-import-meta": "7.10.4",
+ "@babel/eslint-plugin": "7.19.1",
"@babel/preset-env": "7.16.11",
"@xmldom/xmldom": "^0.8.7",
"ajv": "8.10.0",
"async": "3.2.3",
- "babel-eslint": "10.1.0",
"babel-plugin-system-import-transformer": "^4.0.0",
"babel-plugin-transform-es2015-modules-amd-lazy": "2.0.1",
"babel-preset-minify": "0.5.1",
"cross-env": "^7.0.3",
"docdash": "^1.2.0",
- "eslint": "8.9.0",
- "eslint-plugin-babel": "5.3.1",
+ "eslint": "8.41.0",
"eslint-plugin-jsdoc": "^37.9.4",
"eslint-plugin-promise": "6.0.0",
"fb-watchman": "2.0.1",
@@ -166,6 +161,22 @@
"semver": "bin/semver.js"
}
},
+ "node_modules/@babel/eslint-plugin": {
+ "version": "7.19.1",
+ "resolved": "https://registry.npmjs.org/@babel/eslint-plugin/-/eslint-plugin-7.19.1.tgz",
+ "integrity": "sha512-ElGPkQPapKMa3zVqXHkZYzuL7I5LbRw9UWBUArgWsdWDDb9XcACqOpBib5tRPA9XvbVZYrFUkoQPbiJ4BFvu4w==",
+ "dev": true,
+ "dependencies": {
+ "eslint-rule-composer": "^0.3.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || >=14.0.0"
+ },
+ "peerDependencies": {
+ "@babel/eslint-parser": ">=7.11.0",
+ "eslint": ">=7.5.0"
+ }
+ },
"node_modules/@babel/generator": {
"version": "7.17.3",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.3.tgz",
@@ -905,18 +916,6 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-syntax-import-meta": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
- "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
- "dev": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.10.4"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
"node_modules/@babel/plugin-syntax-json-strings": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
@@ -1721,24 +1720,51 @@
"node": "^12 || ^14 || ^16 || ^17"
}
},
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
+ "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+ "dev": true,
+ "dependencies": {
+ "eslint-visitor-keys": "^3.3.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.5.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz",
+ "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==",
+ "dev": true,
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
"node_modules/@eslint/eslintrc": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.1.0.tgz",
- "integrity": "sha512-C1DfL7XX4nPqGd6jcP01W9pVM1HYCuUkFk1432D7F0v3JSlUIeOYn9oCoi3eoLZ+iwBSb29BMFxxny0YrrEZqg==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz",
+ "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==",
"dev": true,
"dependencies": {
"ajv": "^6.12.4",
"debug": "^4.3.2",
- "espree": "^9.3.1",
- "globals": "^13.9.0",
- "ignore": "^4.0.6",
+ "espree": "^9.5.2",
+ "globals": "^13.19.0",
+ "ignore": "^5.2.0",
"import-fresh": "^3.2.1",
"js-yaml": "^4.1.0",
- "minimatch": "^3.0.4",
+ "minimatch": "^3.1.2",
"strip-json-comments": "^3.1.1"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
}
},
"node_modules/@eslint/eslintrc/node_modules/ajv": {
@@ -1764,9 +1790,9 @@
"dev": true
},
"node_modules/@eslint/eslintrc/node_modules/globals": {
- "version": "13.12.1",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz",
- "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==",
+ "version": "13.20.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz",
+ "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==",
"dev": true,
"dependencies": {
"type-fest": "^0.20.2"
@@ -1778,15 +1804,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/@eslint/eslintrc/node_modules/ignore": {
- "version": "4.0.6",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
- "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
- "dev": true,
- "engines": {
- "node": ">= 4"
- }
- },
"node_modules/@eslint/eslintrc/node_modules/js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
@@ -1799,6 +1816,18 @@
"js-yaml": "bin/js-yaml.js"
}
},
+ "node_modules/@eslint/eslintrc/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/@eslint/eslintrc/node_modules/type-fest": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
@@ -1811,20 +1840,54 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/@eslint/js": {
+ "version": "8.41.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.41.0.tgz",
+ "integrity": "sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA==",
+ "dev": true,
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
"node_modules/@humanwhocodes/config-array": {
- "version": "0.9.3",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.3.tgz",
- "integrity": "sha512-3xSMlXHh03hCcCmFc0rbKp3Ivt2PFEJnQUJDDMTJQ2wkECZWdq4GePs2ctc5H8zV+cHPaq8k2vU8mrQjA6iHdQ==",
+ "version": "0.11.8",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz",
+ "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==",
"dev": true,
"dependencies": {
"@humanwhocodes/object-schema": "^1.2.1",
"debug": "^4.1.1",
- "minimatch": "^3.0.4"
+ "minimatch": "^3.0.5"
},
"engines": {
"node": ">=10.10.0"
}
},
+ "node_modules/@humanwhocodes/config-array/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
"node_modules/@humanwhocodes/object-schema": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
@@ -1866,12 +1929,12 @@
}
},
"node_modules/@nodelib/fs.scandir": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
- "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==",
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
"dev": true,
"dependencies": {
- "@nodelib/fs.stat": "2.0.3",
+ "@nodelib/fs.stat": "2.0.5",
"run-parallel": "^1.1.9"
},
"engines": {
@@ -1879,21 +1942,21 @@
}
},
"node_modules/@nodelib/fs.stat": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz",
- "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==",
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
"dev": true,
"engines": {
"node": ">= 8"
}
},
"node_modules/@nodelib/fs.walk": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz",
- "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==",
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
"dev": true,
"dependencies": {
- "@nodelib/fs.scandir": "2.1.3",
+ "@nodelib/fs.scandir": "2.1.5",
"fastq": "^1.6.0"
},
"engines": {
@@ -2168,9 +2231,9 @@
"dev": true
},
"node_modules/acorn": {
- "version": "8.7.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz",
- "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==",
+ "version": "8.8.2",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz",
+ "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==",
"dev": true,
"bin": {
"acorn": "bin/acorn"
@@ -2415,27 +2478,6 @@
"url": "https://tidelift.com/funding/github/npm/autoprefixer"
}
},
- "node_modules/babel-eslint": {
- "version": "10.1.0",
- "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz",
- "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==",
- "deprecated": "babel-eslint is now @babel/eslint-parser. This package will no longer receive updates.",
- "dev": true,
- "dependencies": {
- "@babel/code-frame": "^7.0.0",
- "@babel/parser": "^7.7.0",
- "@babel/traverse": "^7.7.0",
- "@babel/types": "^7.7.0",
- "eslint-visitor-keys": "^1.0.0",
- "resolve": "^1.12.0"
- },
- "engines": {
- "node": ">=6"
- },
- "peerDependencies": {
- "eslint": ">= 4.12.1"
- }
- },
"node_modules/babel-helper-evaluate-path": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.5.0.tgz",
@@ -4449,46 +4491,50 @@
}
},
"node_modules/eslint": {
- "version": "8.9.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.9.0.tgz",
- "integrity": "sha512-PB09IGwv4F4b0/atrbcMFboF/giawbBLVC7fyDamk5Wtey4Jh2K+rYaBhCAbUyEI4QzB1ly09Uglc9iCtFaG2Q==",
+ "version": "8.41.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.41.0.tgz",
+ "integrity": "sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q==",
"dev": true,
"dependencies": {
- "@eslint/eslintrc": "^1.1.0",
- "@humanwhocodes/config-array": "^0.9.2",
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.4.0",
+ "@eslint/eslintrc": "^2.0.3",
+ "@eslint/js": "8.41.0",
+ "@humanwhocodes/config-array": "^0.11.8",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@nodelib/fs.walk": "^1.2.8",
"ajv": "^6.10.0",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
"debug": "^4.3.2",
"doctrine": "^3.0.0",
"escape-string-regexp": "^4.0.0",
- "eslint-scope": "^7.1.1",
- "eslint-utils": "^3.0.0",
- "eslint-visitor-keys": "^3.3.0",
- "espree": "^9.3.1",
- "esquery": "^1.4.0",
+ "eslint-scope": "^7.2.0",
+ "eslint-visitor-keys": "^3.4.1",
+ "espree": "^9.5.2",
+ "esquery": "^1.4.2",
"esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3",
"file-entry-cache": "^6.0.1",
- "functional-red-black-tree": "^1.0.1",
- "glob-parent": "^6.0.1",
- "globals": "^13.6.0",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "globals": "^13.19.0",
+ "graphemer": "^1.4.0",
"ignore": "^5.2.0",
"import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4",
"is-glob": "^4.0.0",
+ "is-path-inside": "^3.0.3",
"js-yaml": "^4.1.0",
"json-stable-stringify-without-jsonify": "^1.0.1",
"levn": "^0.4.1",
"lodash.merge": "^4.6.2",
- "minimatch": "^3.0.4",
+ "minimatch": "^3.1.2",
"natural-compare": "^1.4.0",
"optionator": "^0.9.1",
- "regexpp": "^3.2.0",
"strip-ansi": "^6.0.1",
"strip-json-comments": "^3.1.0",
- "text-table": "^0.2.0",
- "v8-compile-cache": "^2.0.3"
+ "text-table": "^0.2.0"
},
"bin": {
"eslint": "bin/eslint.js"
@@ -4500,21 +4546,6 @@
"url": "https://opencollective.com/eslint"
}
},
- "node_modules/eslint-plugin-babel": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-babel/-/eslint-plugin-babel-5.3.1.tgz",
- "integrity": "sha512-VsQEr6NH3dj664+EyxJwO4FCYm/00JhYb3Sk3ft8o+fpKuIfQ9TaW6uVUfvwMXHcf/lsnRIoyFPsLMyiWCSL/g==",
- "dev": true,
- "dependencies": {
- "eslint-rule-composer": "^0.3.0"
- },
- "engines": {
- "node": ">=4"
- },
- "peerDependencies": {
- "eslint": ">=4.0.0"
- }
- },
"node_modules/eslint-plugin-jsdoc": {
"version": "37.9.4",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-37.9.4.tgz",
@@ -4593,40 +4624,16 @@
"node": ">=8.0.0"
}
},
- "node_modules/eslint-utils": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
- "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
+ "node_modules/eslint-visitor-keys": {
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz",
+ "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==",
"dev": true,
- "dependencies": {
- "eslint-visitor-keys": "^2.0.0"
- },
"engines": {
- "node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
- "url": "https://github.com/sponsors/mysticatea"
- },
- "peerDependencies": {
- "eslint": ">=5"
- }
- },
- "node_modules/eslint-utils/node_modules/eslint-visitor-keys": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
- "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
- "dev": true,
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/eslint-visitor-keys": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz",
- "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==",
- "dev": true,
- "engines": {
- "node": ">=4"
+ "url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint/node_modules/ajv": {
@@ -4727,9 +4734,9 @@
}
},
"node_modules/eslint/node_modules/eslint-scope": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
- "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz",
+ "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==",
"dev": true,
"dependencies": {
"esrecurse": "^4.3.0",
@@ -4737,15 +4744,9 @@
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- }
- },
- "node_modules/eslint/node_modules/eslint-visitor-keys": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
- "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
- "dev": true,
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint/node_modules/estraverse": {
@@ -4801,9 +4802,9 @@
}
},
"node_modules/eslint/node_modules/globals": {
- "version": "13.12.1",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz",
- "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==",
+ "version": "13.20.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz",
+ "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==",
"dev": true,
"dependencies": {
"type-fest": "^0.20.2"
@@ -4849,6 +4850,18 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/eslint/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/eslint/node_modules/optionator": {
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
@@ -4972,26 +4985,20 @@
}
},
"node_modules/espree": {
- "version": "9.3.1",
- "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz",
- "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==",
+ "version": "9.5.2",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz",
+ "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==",
"dev": true,
"dependencies": {
- "acorn": "^8.7.0",
- "acorn-jsx": "^5.3.1",
- "eslint-visitor-keys": "^3.3.0"
+ "acorn": "^8.8.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^3.4.1"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- }
- },
- "node_modules/espree/node_modules/eslint-visitor-keys": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
- "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
- "dev": true,
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
}
},
"node_modules/esprima": {
@@ -5008,9 +5015,9 @@
}
},
"node_modules/esquery": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
- "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
+ "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
"dev": true,
"dependencies": {
"estraverse": "^5.1.0"
@@ -5363,6 +5370,79 @@
"node": ">=6"
}
},
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/find-up/node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/find-up/node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/find-up/node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/find-up/node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/find-versions": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.2.0.tgz",
@@ -5500,32 +5580,12 @@
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
- "node_modules/fsevents": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
- "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
- "dev": true,
- "hasInstallScript": true,
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
"node_modules/function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true
},
- "node_modules/functional-red-black-tree": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
- "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
- "dev": true
- },
"node_modules/gaze": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
@@ -6131,6 +6191,12 @@
"integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==",
"dev": true
},
+ "node_modules/graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+ "dev": true
+ },
"node_modules/gray-matter": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-3.1.1.tgz",
@@ -7372,6 +7438,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-path-inside": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/is-plain-obj": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
@@ -9480,6 +9555,15 @@
"integrity": "sha1-hZB92GBaoGq7PdKV1QuyuPpN0Rc=",
"dev": true
},
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
@@ -9958,6 +10042,26 @@
"node": ">=0.10.0"
}
},
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
"node_modules/quick-lru": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz",
@@ -10159,18 +10263,6 @@
"@babel/runtime": "^7.8.4"
}
},
- "node_modules/regexpp": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
- "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
- "dev": true,
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/mysticatea"
- }
- },
"node_modules/regexpu-core": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.0.1.tgz",
@@ -10403,10 +10495,27 @@
}
},
"node_modules/run-parallel": {
- "version": "1.1.9",
- "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz",
- "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==",
- "dev": true
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
},
"node_modules/safe-buffer": {
"version": "5.1.2",
@@ -11375,15 +11484,6 @@
"node": ">=8"
}
},
- "node_modules/stylelint/node_modules/path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/stylelint/node_modules/read-pkg": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
@@ -12573,6 +12673,15 @@
}
}
},
+ "@babel/eslint-plugin": {
+ "version": "7.19.1",
+ "resolved": "https://registry.npmjs.org/@babel/eslint-plugin/-/eslint-plugin-7.19.1.tgz",
+ "integrity": "sha512-ElGPkQPapKMa3zVqXHkZYzuL7I5LbRw9UWBUArgWsdWDDb9XcACqOpBib5tRPA9XvbVZYrFUkoQPbiJ4BFvu4w==",
+ "dev": true,
+ "requires": {
+ "eslint-rule-composer": "^0.3.0"
+ }
+ },
"@babel/generator": {
"version": "7.17.3",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.3.tgz",
@@ -13094,15 +13203,6 @@
"@babel/helper-plugin-utils": "^7.8.3"
}
},
- "@babel/plugin-syntax-import-meta": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
- "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
- "dev": true,
- "requires": {
- "@babel/helper-plugin-utils": "^7.10.4"
- }
- },
"@babel/plugin-syntax-json-strings": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
@@ -13660,20 +13760,35 @@
"jsdoc-type-pratt-parser": "~2.2.3"
}
},
+ "@eslint-community/eslint-utils": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
+ "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+ "dev": true,
+ "requires": {
+ "eslint-visitor-keys": "^3.3.0"
+ }
+ },
+ "@eslint-community/regexpp": {
+ "version": "4.5.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz",
+ "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==",
+ "dev": true
+ },
"@eslint/eslintrc": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.1.0.tgz",
- "integrity": "sha512-C1DfL7XX4nPqGd6jcP01W9pVM1HYCuUkFk1432D7F0v3JSlUIeOYn9oCoi3eoLZ+iwBSb29BMFxxny0YrrEZqg==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz",
+ "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==",
"dev": true,
"requires": {
"ajv": "^6.12.4",
"debug": "^4.3.2",
- "espree": "^9.3.1",
- "globals": "^13.9.0",
- "ignore": "^4.0.6",
+ "espree": "^9.5.2",
+ "globals": "^13.19.0",
+ "ignore": "^5.2.0",
"import-fresh": "^3.2.1",
"js-yaml": "^4.1.0",
- "minimatch": "^3.0.4",
+ "minimatch": "^3.1.2",
"strip-json-comments": "^3.1.1"
},
"dependencies": {
@@ -13696,20 +13811,14 @@
"dev": true
},
"globals": {
- "version": "13.12.1",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz",
- "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==",
+ "version": "13.20.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz",
+ "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==",
"dev": true,
"requires": {
"type-fest": "^0.20.2"
}
},
- "ignore": {
- "version": "4.0.6",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
- "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
- "dev": true
- },
"js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
@@ -13719,6 +13828,15 @@
"argparse": "^2.0.1"
}
},
+ "minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
"type-fest": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
@@ -13727,17 +13845,40 @@
}
}
},
+ "@eslint/js": {
+ "version": "8.41.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.41.0.tgz",
+ "integrity": "sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA==",
+ "dev": true
+ },
"@humanwhocodes/config-array": {
- "version": "0.9.3",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.3.tgz",
- "integrity": "sha512-3xSMlXHh03hCcCmFc0rbKp3Ivt2PFEJnQUJDDMTJQ2wkECZWdq4GePs2ctc5H8zV+cHPaq8k2vU8mrQjA6iHdQ==",
+ "version": "0.11.8",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz",
+ "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==",
"dev": true,
"requires": {
"@humanwhocodes/object-schema": "^1.2.1",
"debug": "^4.1.1",
- "minimatch": "^3.0.4"
+ "minimatch": "^3.0.5"
+ },
+ "dependencies": {
+ "minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ }
}
},
+ "@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true
+ },
"@humanwhocodes/object-schema": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
@@ -13776,28 +13917,28 @@
}
},
"@nodelib/fs.scandir": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
- "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==",
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
"dev": true,
"requires": {
- "@nodelib/fs.stat": "2.0.3",
+ "@nodelib/fs.stat": "2.0.5",
"run-parallel": "^1.1.9"
}
},
"@nodelib/fs.stat": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz",
- "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==",
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
"dev": true
},
"@nodelib/fs.walk": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz",
- "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==",
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
"dev": true,
"requires": {
- "@nodelib/fs.scandir": "2.1.3",
+ "@nodelib/fs.scandir": "2.1.5",
"fastq": "^1.6.0"
}
},
@@ -14036,9 +14177,9 @@
"dev": true
},
"acorn": {
- "version": "8.7.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz",
- "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==",
+ "version": "8.8.2",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz",
+ "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==",
"dev": true
},
"acorn-jsx": {
@@ -14208,20 +14349,6 @@
"postcss-value-parser": "^4.0.3"
}
},
- "babel-eslint": {
- "version": "10.1.0",
- "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz",
- "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==",
- "dev": true,
- "requires": {
- "@babel/code-frame": "^7.0.0",
- "@babel/parser": "^7.7.0",
- "@babel/traverse": "^7.7.0",
- "@babel/types": "^7.7.0",
- "eslint-visitor-keys": "^1.0.0",
- "resolve": "^1.12.0"
- }
- },
"babel-helper-evaluate-path": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.5.0.tgz",
@@ -15869,46 +15996,50 @@
}
},
"eslint": {
- "version": "8.9.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.9.0.tgz",
- "integrity": "sha512-PB09IGwv4F4b0/atrbcMFboF/giawbBLVC7fyDamk5Wtey4Jh2K+rYaBhCAbUyEI4QzB1ly09Uglc9iCtFaG2Q==",
+ "version": "8.41.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.41.0.tgz",
+ "integrity": "sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q==",
"dev": true,
"requires": {
- "@eslint/eslintrc": "^1.1.0",
- "@humanwhocodes/config-array": "^0.9.2",
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.4.0",
+ "@eslint/eslintrc": "^2.0.3",
+ "@eslint/js": "8.41.0",
+ "@humanwhocodes/config-array": "^0.11.8",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@nodelib/fs.walk": "^1.2.8",
"ajv": "^6.10.0",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
"debug": "^4.3.2",
"doctrine": "^3.0.0",
"escape-string-regexp": "^4.0.0",
- "eslint-scope": "^7.1.1",
- "eslint-utils": "^3.0.0",
- "eslint-visitor-keys": "^3.3.0",
- "espree": "^9.3.1",
- "esquery": "^1.4.0",
+ "eslint-scope": "^7.2.0",
+ "eslint-visitor-keys": "^3.4.1",
+ "espree": "^9.5.2",
+ "esquery": "^1.4.2",
"esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3",
"file-entry-cache": "^6.0.1",
- "functional-red-black-tree": "^1.0.1",
- "glob-parent": "^6.0.1",
- "globals": "^13.6.0",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "globals": "^13.19.0",
+ "graphemer": "^1.4.0",
"ignore": "^5.2.0",
"import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4",
"is-glob": "^4.0.0",
+ "is-path-inside": "^3.0.3",
"js-yaml": "^4.1.0",
"json-stable-stringify-without-jsonify": "^1.0.1",
"levn": "^0.4.1",
"lodash.merge": "^4.6.2",
- "minimatch": "^3.0.4",
+ "minimatch": "^3.1.2",
"natural-compare": "^1.4.0",
"optionator": "^0.9.1",
- "regexpp": "^3.2.0",
"strip-ansi": "^6.0.1",
"strip-json-comments": "^3.1.0",
- "text-table": "^0.2.0",
- "v8-compile-cache": "^2.0.3"
+ "text-table": "^0.2.0"
},
"dependencies": {
"ajv": {
@@ -15981,21 +16112,15 @@
"dev": true
},
"eslint-scope": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
- "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz",
+ "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==",
"dev": true,
"requires": {
"esrecurse": "^4.3.0",
"estraverse": "^5.2.0"
}
},
- "eslint-visitor-keys": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
- "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
- "dev": true
- },
"estraverse": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
@@ -16037,9 +16162,9 @@
}
},
"globals": {
- "version": "13.12.1",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz",
- "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==",
+ "version": "13.20.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz",
+ "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==",
"dev": true,
"requires": {
"type-fest": "^0.20.2"
@@ -16070,6 +16195,15 @@
"type-check": "~0.4.0"
}
},
+ "minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
"optionator": {
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
@@ -16155,15 +16289,6 @@
}
}
},
- "eslint-plugin-babel": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-babel/-/eslint-plugin-babel-5.3.1.tgz",
- "integrity": "sha512-VsQEr6NH3dj664+EyxJwO4FCYm/00JhYb3Sk3ft8o+fpKuIfQ9TaW6uVUfvwMXHcf/lsnRIoyFPsLMyiWCSL/g==",
- "dev": true,
- "requires": {
- "eslint-rule-composer": "^0.3.0"
- }
- },
"eslint-plugin-jsdoc": {
"version": "37.9.4",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-37.9.4.tgz",
@@ -16221,46 +16346,21 @@
"estraverse": "^4.1.1"
}
},
- "eslint-utils": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
- "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
- "dev": true,
- "requires": {
- "eslint-visitor-keys": "^2.0.0"
- },
- "dependencies": {
- "eslint-visitor-keys": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
- "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
- "dev": true
- }
- }
- },
"eslint-visitor-keys": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz",
- "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==",
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz",
+ "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==",
"dev": true
},
"espree": {
- "version": "9.3.1",
- "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz",
- "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==",
+ "version": "9.5.2",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz",
+ "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==",
"dev": true,
"requires": {
- "acorn": "^8.7.0",
- "acorn-jsx": "^5.3.1",
- "eslint-visitor-keys": "^3.3.0"
- },
- "dependencies": {
- "eslint-visitor-keys": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
- "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
- "dev": true
- }
+ "acorn": "^8.8.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^3.4.1"
}
},
"esprima": {
@@ -16270,9 +16370,9 @@
"dev": true
},
"esquery": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
- "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
+ "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
"dev": true,
"requires": {
"estraverse": "^5.1.0"
@@ -16560,6 +16660,51 @@
}
}
},
+ "find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "dependencies": {
+ "locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^5.0.0"
+ }
+ },
+ "p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "requires": {
+ "yocto-queue": "^0.1.0"
+ }
+ },
+ "p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^3.0.2"
+ }
+ },
+ "yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true
+ }
+ }
+ },
"find-versions": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.2.0.tgz",
@@ -16672,25 +16817,12 @@
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
- "fsevents": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
- "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
- "dev": true,
- "optional": true
- },
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true
},
- "functional-red-black-tree": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
- "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
- "dev": true
- },
"gaze": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
@@ -17170,6 +17302,12 @@
"integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==",
"dev": true
},
+ "graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+ "dev": true
+ },
"gray-matter": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-3.1.1.tgz",
@@ -18076,6 +18214,12 @@
"integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==",
"dev": true
},
+ "is-path-inside": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+ "dev": true
+ },
"is-plain-obj": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
@@ -19717,6 +19861,12 @@
"integrity": "sha1-hZB92GBaoGq7PdKV1QuyuPpN0Rc=",
"dev": true
},
+ "path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true
+ },
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
@@ -20089,6 +20239,12 @@
"strict-uri-encode": "^1.0.0"
}
},
+ "queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true
+ },
"quick-lru": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz",
@@ -20257,12 +20413,6 @@
"@babel/runtime": "^7.8.4"
}
},
- "regexpp": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
- "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
- "dev": true
- },
"regexpu-core": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.0.1.tgz",
@@ -20446,10 +20596,13 @@
}
},
"run-parallel": {
- "version": "1.1.9",
- "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz",
- "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==",
- "dev": true
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "requires": {
+ "queue-microtask": "^1.2.2"
+ }
},
"safe-buffer": {
"version": "5.1.2",
@@ -21205,12 +21358,6 @@
"lines-and-columns": "^1.1.6"
}
},
- "path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true
- },
"read-pkg": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
diff --git a/package.json b/package.json
index fe711467f01..3d8f926f921 100644
--- a/package.json
+++ b/package.json
@@ -5,22 +5,17 @@
"devDependencies": {
"@babel/core": "7.17.5",
"@babel/eslint-parser": "^7.21.3",
- "@babel/plugin-proposal-class-properties": "7.16.7",
- "@babel/plugin-proposal-json-strings": "7.16.7",
- "@babel/plugin-syntax-dynamic-import": "7.8.3",
- "@babel/plugin-syntax-import-meta": "7.10.4",
+ "@babel/eslint-plugin": "7.19.1",
"@babel/preset-env": "7.16.11",
"@xmldom/xmldom": "^0.8.7",
"ajv": "8.10.0",
"async": "3.2.3",
- "babel-eslint": "10.1.0",
"babel-plugin-system-import-transformer": "^4.0.0",
"babel-plugin-transform-es2015-modules-amd-lazy": "2.0.1",
"babel-preset-minify": "0.5.1",
"cross-env": "^7.0.3",
"docdash": "^1.2.0",
- "eslint": "8.9.0",
- "eslint-plugin-babel": "5.3.1",
+ "eslint": "8.41.0",
"eslint-plugin-jsdoc": "^37.9.4",
"eslint-plugin-promise": "6.0.0",
"fb-watchman": "2.0.1",