',button:'',option:'',promptMessage:'',inputs:{text:'',textarea:'',email:'',select:'',checkbox:'',radio:'',date:'',time:'',number:'',password:'',range:''}},p={locale:"en",backdrop:"static",animate:!0,className:null,closeButton:!0,show:!0,container:"body",value:"",inputType:"text",errorMessage:null,swapButtonOrder:!1,centerVertical:!1,multiple:!1,scrollable:!1,reusable:!1,relatedTarget:null,size:null,id:null};function i(t,e,o){return s.extend(!0,{},t,function(t,e){var o=t.length;let a={};if(o<1||2").attr("label",e.group)),o=r[e.group]);let a=s(u.option);a.attr("value",e.value).text(e.text),o.append(a)}),f(r,function(t,e){i.append(e)}),i.val(n.value),n.bootstrap<5&&i.removeClass("form-select").addClass("form-control");break;case"checkbox":let e=s.isArray(n.value)?n.value:[n.value];if(!(l=n.inputOptions||[]).length)throw new Error('prompt with "inputType" set to "checkbox" requires at least one option');i=s(''),f(l,function(t,o){if(o.value===c||o.text===c)throw new Error('each option needs a "value" property and a "text" property');let a=s(u.inputs[n.inputType]);a.find("input").attr("value",o.value),a.find("label").append("\n"+o.text),f(e,function(t,e){e===o.value&&a.find("input").prop("checked",!0)}),i.append(a)});break;case"radio":if(n.value!==c&&s.isArray(n.value))throw new Error('prompt with "inputType" set to "radio" requires a single, non-array value for "value"');if(!(l=n.inputOptions||[]).length)throw new Error('prompt with "inputType" set to "radio" requires at least one option');i=s('');let a=!0;f(l,function(t,e){if(e.value===c||e.text===c)throw new Error('each option needs a "value" property and a "text" property');let o=s(u.inputs[n.inputType]);o.find("input").attr("value",e.value),o.find("label").append("\n"+e.text),n.value!==c&&e.value===n.value&&(o.find("input").prop("checked",!0),a=!1),i.append(o)}),a&&i.find('input[type="radio"]').first().prop("checked",!0)}return t.append(i),t.on("submit",function(t){t.preventDefault(),t.stopPropagation(),e.find(".bootbox-accept").trigger("click")}),""!==s.trim(n.message)&&(a=s(u.promptMessage).html(n.message),t.prepend(a)),n.message=t,(e=r.dialog(n)).off("shown.bs.modal",m),e.on("shown.bs.modal",function(){i.focus()}),!0===o&&e.modal("show"),e},r});
\ No newline at end of file
diff --git a/resources/bootbox.js/6.0.2/bootbox.min.jsm b/resources/bootbox.js/6.0.2/bootbox.min.jsm
new file mode 100644
index 00000000..34a85563
--- /dev/null
+++ b/resources/bootbox.js/6.0.2/bootbox.min.jsm
@@ -0,0 +1,7 @@
+/**
+ * Bootbox.js — alert, confirm, prompt, and flexible dialogs for the Bootstrap framework
+ * @version: 6.0.2
+ * @project: https://github.com/bootboxjs/bootbox
+ * @license: MIT http://bootboxjs.com/license.txt
+ */
+((t,e)=>{'function'==typeof define&&define.amd?define(['jquery'],e):'object'==typeof exports?module.exports=e(require('jquery')):t.bootbox=e(t.jQuery)})(this,function e(s,p){let r={};r.VERSION='6.0.2';let l={en:{OK:'OK',CANCEL:'Cancel',CONFIRM:'OK'}},c={dialog:'
',header:'
',footer:'',closeButton:'',form:'',button:'',option:'',promptMessage:'',inputs:{text:'',textarea:'',email:'',select:'',checkbox:'',radio:'',date:'',time:'',number:'',password:'',range:''}},u={locale:'en',backdrop:'static',animate:!0,className:null,closeButton:!0,show:!0,container:'body',value:'',inputType:'text',errorMessage:null,swapButtonOrder:!1,centerVertical:!1,multiple:!1,scrollable:!1,reusable:!1,relatedTarget:null,size:null,id:null};function i(t,e,o){return s.extend(!0,{},t,((t,e)=>{var o=t.length;let a={};if(o<1||2{var r={};for(let t=0,e=o.length;t((e=l[e])||l.en)[t])(n,a)}}return r})(e=r&&r[0]&&(o=r[0].locale||u.locale,r[0].swapButtonOrder||u.swapButtonOrder)?e.reverse():e,o)};{t=i(t,r,a);var n=e;let o={};return f(n,function(t,e){o[e]=!0}),f(t.buttons,function(t){if(o[t]===p)throw new Error('button key "'+t+'" is not allowed (options are '+n.join(' ')+')')}),t}}function b(t){return Object.keys(t).length}function f(t,o){let a=0;s.each(t,function(t,e){o(t,e,a++)})}function m(t){t.data.dialog.find('.bootbox-accept').first().trigger('focus')}function h(t){t.target===t.data.dialog[0]&&t.data.dialog.remove()}function w(t){t.target===t.data.dialog[0]&&(t.data.dialog.off('escape.close.bb'),t.data.dialog.off('click'))}function g(t,e,o){t.stopPropagation(),t.preventDefault(),'function'==typeof o&&!1===o.call(e,t)||e.modal('hide')}function y(t){return/([01][0-9]|2[0-3]):[0-5][0-9]?:[0-5][0-9]/.test(t)}function v(t){return/(\d{4})-(\d{2})-(\d{2})/.test(t)}return r.locales=function(t){return t?l[t]:l},r.addLocale=function(t,o){return s.each(['OK','CANCEL','CONFIRM'],function(t,e){if(!o[e])throw new Error('Please supply a translation for "'+e+'"')}),l[t]={OK:o.OK,CANCEL:o.CANCEL,CONFIRM:o.CONFIRM},r},r.removeLocale=function(t){if('en'===t)throw new Error('"en" is used as the default and fallback locale and cannot be removed.');return delete l[t],r},r.setLocale=function(t){return r.setDefaults('locale',t)},r.setDefaults=function(){let t={};return 2===arguments.length?t[arguments[0]]=arguments[1]:t=arguments[0],s.extend(u,t),r},r.hideAll=function(){return s('.bootbox').modal('hide'),r},r.init=function(t){return e(t||s)},r.dialog=function(t){if(s.fn.modal===p)throw new Error('"$.fn.modal" is not defined; please double check you have included the Bootstrap JavaScript library. See https://getbootstrap.com/docs/5.1/getting-started/introduction/ for more details.');t=(a=>{let r,n;if('object'!=typeof a)throw new Error('Please supply an object of options');if(a.message)return(a=s.extend({},u,a)).backdrop?a.backdrop='string'!=typeof a.backdrop||'static'!==a.backdrop.toLowerCase()||'static':a.backdrop=!1!==a.backdrop&&0!==a.backdrop&&'static',a.buttons||(a.buttons={}),r=a.buttons,n=b(r),f(r,function(t,e,o){if('object'!=typeof(e='function'==typeof e?r[t]={callback:e}:e))throw new Error('button with key "'+t+'" must be an object');if(e.label||(e.label=t),!e.className){let t=!1;t=a.swapButtonOrder?0===o:o===n-1,n<=2&&t?e.className='btn-primary':e.className='btn-secondary btn-default'}}),a;throw new Error('"message" option must not be null or an empty string.')})(t),s.fn.modal.Constructor.VERSION?(t.fullBootstrapVersion=s.fn.modal.Constructor.VERSION,a=t.fullBootstrapVersion.indexOf('.'),t.bootstrap=t.fullBootstrapVersion.substring(0,a)):(t.bootstrap='2',t.fullBootstrapVersion='2.3.2',console.warn('Bootbox will *mostly* work with Bootstrap 2, but we do not officially support it. Please upgrade, if possible.'));let o=s(c.dialog);var e=o.find('.modal-dialog'),a=o.find('.modal-body'),r=s(c.header);let n=s(c.footer);var i=t.buttons;let l={onEscape:t.onEscape};if(a.find('.bootbox-body').html(t.message),0{let a=!1,r=!0,n=!0;if('date'===t)e===p||(r=v(e))?o===p||(n=v(o))||console.warn('Browsers which natively support the "date" input type expect date values to be of the form "YYYY-MM-DD" (see ISO-8601 https://www.iso.org/iso-8601-date-and-time-format.html). Bootbox does not enforce this rule, but your max value may not be enforced by this browser.'):console.warn('Browsers which natively support the "date" input type expect date values to be of the form "YYYY-MM-DD" (see ISO-8601 https://www.iso.org/iso-8601-date-and-time-format.html). Bootbox does not enforce this rule, but your min value may not be enforced by this browser.');else if('time'===t){if(e!==p&&!(r=y(e)))throw new Error('"min" is not a valid time. See https://www.w3.org/TR/2012/WD-html-markup-20120315/datatypes.html#form.data.time for more information.');if(o!==p&&!(n=y(o)))throw new Error('"max" is not a valid time. See https://www.w3.org/TR/2012/WD-html-markup-20120315/datatypes.html#form.data.time for more information.')}else{if(e!==p&&isNaN(e))throw r=!1,new Error('"min" must be a valid number. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-min for more information.');if(o!==p&&isNaN(o))throw n=!1,new Error('"max" must be a valid number. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-max for more information.')}if(r&&n){if(o<=e)throw new Error('"max" must be greater than "min". See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-max for more information.');a=!0}return a})(n.inputType,n.min,n.max)&&(n.min!==p&&i.attr('min',n.min),n.max!==p)&&i.attr('max',n.max);break;case'select':let r={};if(l=n.inputOptions||[],!Array.isArray(l))throw new Error('Please pass an array of input options');if(!l.length)throw new Error('prompt with "inputType" set to "select" requires at least one option');n.required&&i.prop({required:!0}),n.multiple&&i.prop({multiple:!0}),f(l,function(t,e){let o=i;if(e.value===p||e.text===p)throw new Error('each option needs a "value" property and a "text" property');e.group&&(r[e.group]||(r[e.group]=s('').attr('label',e.group)),o=r[e.group]);var a=s(c.option);a.attr('value',e.value).text(e.text),o.append(a)}),f(r,function(t,e){i.append(e)}),i.val(n.value),n.bootstrap<5&&i.removeClass('form-select').addClass('form-control');break;case'checkbox':let e=Array.isArray(n.value)?n.value:[n.value];if(!(l=n.inputOptions||[]).length)throw new Error('prompt with "inputType" set to "checkbox" requires at least one option');i=s(''),f(l,function(t,o){if(o.value===p||o.text===p)throw new Error('each option needs a "value" property and a "text" property');let a=s(c.inputs[n.inputType]);a.find('input').attr('value',o.value),a.find('label').append('\n'+o.text),f(e,function(t,e){e===o.value&&a.find('input').prop('checked',!0)}),i.append(a)});break;case'radio':if(n.value!==p&&Array.isArray(n.value))throw new Error('prompt with "inputType" set to "radio" requires a single, non-array value for "value"');if(!(l=n.inputOptions||[]).length)throw new Error('prompt with "inputType" set to "radio" requires at least one option');i=s('');let a=!0;f(l,function(t,e){if(e.value===p||e.text===p)throw new Error('each option needs a "value" property and a "text" property');var o=s(c.inputs[n.inputType]);o.find('input').attr('value',e.value),o.find('label').append('\n'+e.text),n.value!==p&&e.value===n.value&&(o.find('input').prop('checked',!0),a=!1),i.append(o)}),a&&i.find('input[type="radio"]').first().prop('checked',!0)}return t.append(i),t.on('submit',function(t){t.preventDefault(),t.stopPropagation(),e.find('.bootbox-accept').trigger('click')}),n.message&&''!==n.message.trim()&&(a=s(c.promptMessage).html(n.message),t.prepend(a)),n.message=t,(e=r.dialog(n)).off('shown.bs.modal',m),e.on('shown.bs.modal',function(){i.focus()}),!0===o&&e.modal('show'),e},r});
\ No newline at end of file