Warning: Cannot modify header information - headers already sent by (output started at /var/www/jonas-eriksen.dk/pic/private/index.php:1) in /var/www/jonas-eriksen.dk/pic/private/index.php on line 215
popper.min.js000064400000044054152335330400007176 0ustar00/** * @popperjs/core v2.9.1 - MIT License */ "use strict";!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Popper={})}(this,(function(e){function t(e){return{width:(e=e.getBoundingClientRect()).width,height:e.height,top:e.top,right:e.right,bottom:e.bottom,left:e.left,x:e.left,y:e.top}}function n(e){return null==e?window:"[object Window]"!==e.toString()?(e=e.ownerDocument)&&e.defaultView||window:e}function o(e){return{scrollLeft:(e=n(e)).pageXOffset,scrollTop:e.pageYOffset}}function r(e){return e instanceof n(e).Element||e instanceof Element}function i(e){return e instanceof n(e).HTMLElement||e instanceof HTMLElement}function a(e){return"undefined"!=typeof ShadowRoot&&(e instanceof n(e).ShadowRoot||e instanceof ShadowRoot)}function s(e){return e?(e.nodeName||"").toLowerCase():null}function f(e){return((r(e)?e.ownerDocument:e.document)||window.document).documentElement}function p(e){return t(f(e)).left+o(e).scrollLeft}function c(e){return n(e).getComputedStyle(e)}function l(e){return e=c(e),/auto|scroll|overlay|hidden/.test(e.overflow+e.overflowY+e.overflowX)}function u(e,r,a){void 0===a&&(a=!1);var c=f(r);e=t(e);var u=i(r),d={scrollLeft:0,scrollTop:0},m={x:0,y:0};return(u||!u&&!a)&&(("body"!==s(r)||l(c))&&(d=r!==n(r)&&i(r)?{scrollLeft:r.scrollLeft,scrollTop:r.scrollTop}:o(r)),i(r)?((m=t(r)).x+=r.clientLeft,m.y+=r.clientTop):c&&(m.x=p(c))),{x:e.left+d.scrollLeft-m.x,y:e.top+d.scrollTop-m.y,width:e.width,height:e.height}}function d(e){var n=t(e),o=e.offsetWidth,r=e.offsetHeight;return 1>=Math.abs(n.width-o)&&(o=n.width),1>=Math.abs(n.height-r)&&(r=n.height),{x:e.offsetLeft,y:e.offsetTop,width:o,height:r}}function m(e){return"html"===s(e)?e:e.assignedSlot||e.parentNode||(a(e)?e.host:null)||f(e)}function h(e){return 0<=["html","body","#document"].indexOf(s(e))?e.ownerDocument.body:i(e)&&l(e)?e:h(m(e))}function v(e,t){var o;void 0===t&&(t=[]);var r=h(e);return e=r===(null==(o=e.ownerDocument)?void 0:o.body),o=n(r),r=e?[o].concat(o.visualViewport||[],l(r)?r:[]):r,t=t.concat(r),e?t:t.concat(v(m(r)))}function g(e){return i(e)&&"fixed"!==c(e).position?e.offsetParent:null}function y(e){for(var t=n(e),o=g(e);o&&0<=["table","td","th"].indexOf(s(o))&&"static"===c(o).position;)o=g(o);if(o&&("html"===s(o)||"body"===s(o)&&"static"===c(o).position))return t;if(!o)e:{for(o=-1!==navigator.userAgent.toLowerCase().indexOf("firefox"),e=m(e);i(e)&&0>["html","body"].indexOf(s(e));){var r=c(e);if("none"!==r.transform||"none"!==r.perspective||"paint"===r.contain||-1!==["transform","perspective"].indexOf(r.willChange)||o&&"filter"===r.willChange||o&&r.filter&&"none"!==r.filter){o=e;break e}e=e.parentNode}o=null}return o||t}function b(e){function t(e){o.add(e.name),[].concat(e.requires||[],e.requiresIfExists||[]).forEach((function(e){o.has(e)||(e=n.get(e))&&t(e)})),r.push(e)}var n=new Map,o=new Set,r=[];return e.forEach((function(e){n.set(e.name,e)})),e.forEach((function(e){o.has(e.name)||t(e)})),r}function w(e){var t;return function(){return t||(t=new Promise((function(n){Promise.resolve().then((function(){t=void 0,n(e())}))}))),t}}function x(e){return e.split("-")[0]}function O(e,t){var n=t.getRootNode&&t.getRootNode();if(e.contains(t))return!0;if(n&&a(n))do{if(t&&e.isSameNode(t))return!0;t=t.parentNode||t.host}while(t);return!1}function j(e){return Object.assign({},e,{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height})}function E(e,r){if("viewport"===r){r=n(e);var a=f(e);r=r.visualViewport;var s=a.clientWidth;a=a.clientHeight;var l=0,u=0;r&&(s=r.width,a=r.height,/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(l=r.offsetLeft,u=r.offsetTop)),e=j(e={width:s,height:a,x:l+p(e),y:u})}else i(r)?((e=t(r)).top+=r.clientTop,e.left+=r.clientLeft,e.bottom=e.top+r.clientHeight,e.right=e.left+r.clientWidth,e.width=r.clientWidth,e.height=r.clientHeight,e.x=e.left,e.y=e.top):(u=f(e),e=f(u),s=o(u),r=null==(a=u.ownerDocument)?void 0:a.body,a=_(e.scrollWidth,e.clientWidth,r?r.scrollWidth:0,r?r.clientWidth:0),l=_(e.scrollHeight,e.clientHeight,r?r.scrollHeight:0,r?r.clientHeight:0),u=-s.scrollLeft+p(u),s=-s.scrollTop,"rtl"===c(r||e).direction&&(u+=_(e.clientWidth,r?r.clientWidth:0)-a),e=j({width:a,height:l,x:u,y:s}));return e}function D(e,t,n){return t="clippingParents"===t?function(e){var t=v(m(e)),n=0<=["absolute","fixed"].indexOf(c(e).position)&&i(e)?y(e):e;return r(n)?t.filter((function(e){return r(e)&&O(e,n)&&"body"!==s(e)})):[]}(e):[].concat(t),(n=(n=[].concat(t,[n])).reduce((function(t,n){return n=E(e,n),t.top=_(n.top,t.top),t.right=U(n.right,t.right),t.bottom=U(n.bottom,t.bottom),t.left=_(n.left,t.left),t}),E(e,n[0]))).width=n.right-n.left,n.height=n.bottom-n.top,n.x=n.left,n.y=n.top,n}function L(e){return 0<=["top","bottom"].indexOf(e)?"x":"y"}function P(e){var t=e.reference,n=e.element,o=(e=e.placement)?x(e):null;e=e?e.split("-")[1]:null;var r=t.x+t.width/2-n.width/2,i=t.y+t.height/2-n.height/2;switch(o){case"top":r={x:r,y:t.y-n.height};break;case"bottom":r={x:r,y:t.y+t.height};break;case"right":r={x:t.x+t.width,y:i};break;case"left":r={x:t.x-n.width,y:i};break;default:r={x:t.x,y:t.y}}if(null!=(o=o?L(o):null))switch(i="y"===o?"height":"width",e){case"start":r[o]-=t[i]/2-n[i]/2;break;case"end":r[o]+=t[i]/2-n[i]/2}return r}function M(e){return Object.assign({},{top:0,right:0,bottom:0,left:0},e)}function k(e,t){return t.reduce((function(t,n){return t[n]=e,t}),{})}function W(e,n){void 0===n&&(n={});var o=n;n=void 0===(n=o.placement)?e.placement:n;var i=o.boundary,a=void 0===i?"clippingParents":i,s=void 0===(i=o.rootBoundary)?"viewport":i;i=void 0===(i=o.elementContext)?"popper":i;var p=o.altBoundary,c=void 0!==p&&p;o=M("number"!=typeof(o=void 0===(o=o.padding)?0:o)?o:k(o,C));var l=e.elements.reference;p=e.rects.popper,a=D(r(c=e.elements[c?"popper"===i?"reference":"popper":i])?c:c.contextElement||f(e.elements.popper),a,s),c=P({reference:s=t(l),element:p,strategy:"absolute",placement:n}),p=j(Object.assign({},p,c)),s="popper"===i?p:s;var u={top:a.top-s.top+o.top,bottom:s.bottom-a.bottom+o.bottom,left:a.left-s.left+o.left,right:s.right-a.right+o.right};if(e=e.modifiersData.offset,"popper"===i&&e){var d=e[n];Object.keys(u).forEach((function(e){var t=0<=["right","bottom"].indexOf(e)?1:-1,n=0<=["top","bottom"].indexOf(e)?"y":"x";u[e]+=d[n]*t}))}return u}function A(){for(var e=arguments.length,t=Array(e),n=0;n(g.devicePixelRatio||1)?"translate("+e+"px, "+u+"px)":"translate3d("+e+"px, "+u+"px, 0)",m)):Object.assign({},o,((t={})[v]=a?u+"px":"",t[h]=d?e+"px":"",t.transform="",t))}function H(e){return e.replace(/left|right|bottom|top/g,(function(e){return $[e]}))}function R(e){return e.replace(/start|end/g,(function(e){return ee[e]}))}function S(e,t,n){return void 0===n&&(n={x:0,y:0}),{top:e.top-t.height-n.y,right:e.right-t.width+n.x,bottom:e.bottom-t.height+n.y,left:e.left-t.width-n.x}}function q(e){return["top","right","bottom","left"].some((function(t){return 0<=e[t]}))}var C=["top","bottom","right","left"],N=C.reduce((function(e,t){return e.concat([t+"-start",t+"-end"])}),[]),V=[].concat(C,["auto"]).reduce((function(e,t){return e.concat([t,t+"-start",t+"-end"])}),[]),I="beforeRead read afterRead beforeMain main afterMain beforeWrite write afterWrite".split(" "),_=Math.max,U=Math.min,z=Math.round,F={placement:"bottom",modifiers:[],strategy:"absolute"},X={passive:!0},Y={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(e){var t=e.state,o=e.instance,r=(e=e.options).scroll,i=void 0===r||r,a=void 0===(e=e.resize)||e,s=n(t.elements.popper),f=[].concat(t.scrollParents.reference,t.scrollParents.popper);return i&&f.forEach((function(e){e.addEventListener("scroll",o.update,X)})),a&&s.addEventListener("resize",o.update,X),function(){i&&f.forEach((function(e){e.removeEventListener("scroll",o.update,X)})),a&&s.removeEventListener("resize",o.update,X)}},data:{}},G={name:"popperOffsets",enabled:!0,phase:"read",fn:function(e){var t=e.state;t.modifiersData[e.name]=P({reference:t.rects.reference,element:t.rects.popper,strategy:"absolute",placement:t.placement})},data:{}},J={top:"auto",right:"auto",bottom:"auto",left:"auto"},K={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(e){var t=e.state,n=e.options;e=void 0===(e=n.gpuAcceleration)||e;var o=n.adaptive;o=void 0===o||o,n=void 0===(n=n.roundOffsets)||n,e={placement:x(t.placement),popper:t.elements.popper,popperRect:t.rects.popper,gpuAcceleration:e},null!=t.modifiersData.popperOffsets&&(t.styles.popper=Object.assign({},t.styles.popper,T(Object.assign({},e,{offsets:t.modifiersData.popperOffsets,position:t.options.strategy,adaptive:o,roundOffsets:n})))),null!=t.modifiersData.arrow&&(t.styles.arrow=Object.assign({},t.styles.arrow,T(Object.assign({},e,{offsets:t.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:n})))),t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-placement":t.placement})},data:{}},Q={name:"applyStyles",enabled:!0,phase:"write",fn:function(e){var t=e.state;Object.keys(t.elements).forEach((function(e){var n=t.styles[e]||{},o=t.attributes[e]||{},r=t.elements[e];i(r)&&s(r)&&(Object.assign(r.style,n),Object.keys(o).forEach((function(e){var t=o[e];!1===t?r.removeAttribute(e):r.setAttribute(e,!0===t?"":t)})))}))},effect:function(e){var t=e.state,n={popper:{position:t.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(t.elements.popper.style,n.popper),t.styles=n,t.elements.arrow&&Object.assign(t.elements.arrow.style,n.arrow),function(){Object.keys(t.elements).forEach((function(e){var o=t.elements[e],r=t.attributes[e]||{};e=Object.keys(t.styles.hasOwnProperty(e)?t.styles[e]:n[e]).reduce((function(e,t){return e[t]="",e}),{}),i(o)&&s(o)&&(Object.assign(o.style,e),Object.keys(r).forEach((function(e){o.removeAttribute(e)})))}))}},requires:["computeStyles"]},Z={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(e){var t=e.state,n=e.name,o=void 0===(e=e.options.offset)?[0,0]:e,r=(e=V.reduce((function(e,n){var r=t.rects,i=x(n),a=0<=["left","top"].indexOf(i)?-1:1,s="function"==typeof o?o(Object.assign({},r,{placement:n})):o;return r=(r=s[0])||0,s=((s=s[1])||0)*a,i=0<=["left","right"].indexOf(i)?{x:s,y:r}:{x:r,y:s},e[n]=i,e}),{}))[t.placement],i=r.x;r=r.y,null!=t.modifiersData.popperOffsets&&(t.modifiersData.popperOffsets.x+=i,t.modifiersData.popperOffsets.y+=r),t.modifiersData[n]=e}},$={left:"right",right:"left",bottom:"top",top:"bottom"},ee={start:"end",end:"start"},te={name:"flip",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options;if(e=e.name,!t.modifiersData[e]._skip){var o=n.mainAxis;o=void 0===o||o;var r=n.altAxis;r=void 0===r||r;var i=n.fallbackPlacements,a=n.padding,s=n.boundary,f=n.rootBoundary,p=n.altBoundary,c=n.flipVariations,l=void 0===c||c,u=n.allowedAutoPlacements;c=x(n=t.options.placement),i=i||(c!==n&&l?function(e){if("auto"===x(e))return[];var t=H(e);return[R(e),t,R(t)]}(n):[H(n)]);var d=[n].concat(i).reduce((function(e,n){return e.concat("auto"===x(n)?function(e,t){void 0===t&&(t={});var n=t.boundary,o=t.rootBoundary,r=t.padding,i=t.flipVariations,a=t.allowedAutoPlacements,s=void 0===a?V:a,f=t.placement.split("-")[1];0===(i=(t=f?i?N:N.filter((function(e){return e.split("-")[1]===f})):C).filter((function(e){return 0<=s.indexOf(e)}))).length&&(i=t);var p=i.reduce((function(t,i){return t[i]=W(e,{placement:i,boundary:n,rootBoundary:o,padding:r})[x(i)],t}),{});return Object.keys(p).sort((function(e,t){return p[e]-p[t]}))}(t,{placement:n,boundary:s,rootBoundary:f,padding:a,flipVariations:l,allowedAutoPlacements:u}):n)}),[]);n=t.rects.reference,i=t.rects.popper;var m=new Map;c=!0;for(var h=d[0],v=0;vi[O]&&(b=H(b)),O=H(b),w=[],o&&w.push(0>=j[y]),r&&w.push(0>=j[b],0>=j[O]),w.every((function(e){return e}))){h=g,c=!1;break}m.set(g,w)}if(c)for(o=function(e){var t=d.find((function(t){if(t=m.get(t))return t.slice(0,e).every((function(e){return e}))}));if(t)return h=t,"break"},r=l?3:1;0{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t},n=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let s=t.getAttribute("href");if(!s||!s.includes("#")&&!s.startsWith("."))return null;s.includes("#")&&!s.startsWith("#")&&(s="#"+s.split("#")[1]),e=s&&"#"!==s?s.trim():null}return e},o=t=>{const e=n(t);return e&&document.querySelector(e)?e:null},r=t=>{const e=n(t);return e?document.querySelector(e):null},a=t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:s}=window.getComputedStyle(t);const i=Number.parseFloat(e),n=Number.parseFloat(s);return i||n?(e=e.split(",")[0],s=s.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(s))):0},l=t=>{t.dispatchEvent(new Event("transitionend"))},c=t=>(t[0]||t).nodeType,h=(t,e)=>{let s=!1;const i=e+5;t.addEventListener("transitionend",(function e(){s=!0,t.removeEventListener("transitionend",e)})),setTimeout(()=>{s||l(t)},i)},d=(t,e,s)=>{Object.keys(s).forEach(i=>{const n=s[i],o=e[i],r=o&&c(o)?"element":null==(a=o)?""+a:{}.toString.call(a).match(/\s([a-z]+)/i)[1].toLowerCase();var a;if(!new RegExp(n).test(r))throw new TypeError(t.toUpperCase()+": "+`Option "${i}" provided type "${r}" `+`but expected type "${n}".`)})},u=t=>{if(!t)return!1;if(t.style&&t.parentNode&&t.parentNode.style){const e=getComputedStyle(t),s=getComputedStyle(t.parentNode);return"none"!==e.display&&"none"!==s.display&&"hidden"!==e.visibility}return!1},g=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),f=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?f(t.parentNode):null},p=()=>function(){},m=t=>t.offsetHeight,_=()=>{const{jQuery:t}=window;return t&&!document.body.hasAttribute("data-bs-no-jquery")?t:null},b=()=>"rtl"===document.documentElement.dir,v=(t,e)=>{var s;s=()=>{const s=_();if(s){const i=s.fn[t];s.fn[t]=e.jQueryInterface,s.fn[t].Constructor=e,s.fn[t].noConflict=()=>(s.fn[t]=i,e.jQueryInterface)}},"loading"===document.readyState?document.addEventListener("DOMContentLoaded",s):s()},y=new Map;var w={set(t,e,s){y.has(t)||y.set(t,new Map);const i=y.get(t);i.has(e)||0===i.size?i.set(e,s):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(i.keys())[0]}.`)},get:(t,e)=>y.has(t)&&y.get(t).get(e)||null,remove(t,e){if(!y.has(t))return;const s=y.get(t);s.delete(e),0===s.size&&y.delete(t)}};const E=/[^.]*(?=\..*)\.|.*/,T=/\..*/,A=/::\d+$/,L={};let k=1;const C={mouseenter:"mouseover",mouseleave:"mouseout"},D=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function S(t,e){return e&&`${e}::${k++}`||t.uidEvent||k++}function N(t){const e=S(t);return t.uidEvent=e,L[e]=L[e]||{},L[e]}function O(t,e,s=null){const i=Object.keys(t);for(let n=0,o=i.length;n{!function(t,e,s,i){const n=e[s]||{};Object.keys(n).forEach(o=>{if(o.includes(i)){const i=n[o];j(t,e,s,i.originalHandler,i.delegationSelector)}})}(t,l,s,e.slice(1))});const h=l[r]||{};Object.keys(h).forEach(s=>{const i=s.replace(A,"");if(!a||e.includes(i)){const e=h[s];j(t,l,r,e.originalHandler,e.delegationSelector)}})},trigger(t,e,s){if("string"!=typeof e||!t)return null;const i=_(),n=e.replace(T,""),o=e!==n,r=D.has(n);let a,l=!0,c=!0,h=!1,d=null;return o&&i&&(a=i.Event(e,s),i(t).trigger(a),l=!a.isPropagationStopped(),c=!a.isImmediatePropagationStopped(),h=a.isDefaultPrevented()),r?(d=document.createEvent("HTMLEvents"),d.initEvent(n,l,!0)):d=new CustomEvent(e,{bubbles:l,cancelable:!0}),void 0!==s&&Object.keys(s).forEach(t=>{Object.defineProperty(d,t,{get:()=>s[t]})}),h&&d.preventDefault(),c&&t.dispatchEvent(d),d.defaultPrevented&&void 0!==a&&a.preventDefault(),d}};class M{constructor(t){(t="string"==typeof t?document.querySelector(t):t)&&(this._element=t,w.set(this._element,this.constructor.DATA_KEY,this))}dispose(){w.remove(this._element,this.constructor.DATA_KEY),this._element=null}static getInstance(t){return w.get(t,this.DATA_KEY)}static get VERSION(){return"5.0.0-beta3"}}class H extends M{static get DATA_KEY(){return"bs.alert"}close(t){const e=t?this._getRootElement(t):this._element,s=this._triggerCloseEvent(e);null===s||s.defaultPrevented||this._removeElement(e)}_getRootElement(t){return r(t)||t.closest(".alert")}_triggerCloseEvent(t){return P.trigger(t,"close.bs.alert")}_removeElement(t){if(t.classList.remove("show"),!t.classList.contains("fade"))return void this._destroyElement(t);const e=a(t);P.one(t,"transitionend",()=>this._destroyElement(t)),h(t,e)}_destroyElement(t){t.parentNode&&t.parentNode.removeChild(t),P.trigger(t,"closed.bs.alert")}static jQueryInterface(t){return this.each((function(){let e=w.get(this,"bs.alert");e||(e=new H(this)),"close"===t&&e[t](this)}))}static handleDismiss(t){return function(e){e&&e.preventDefault(),t.close(this)}}}P.on(document,"click.bs.alert.data-api",'[data-bs-dismiss="alert"]',H.handleDismiss(new H)),v("alert",H);class R extends M{static get DATA_KEY(){return"bs.button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){let e=w.get(this,"bs.button");e||(e=new R(this)),"toggle"===t&&e[t]()}))}}function B(t){return"true"===t||"false"!==t&&(t===Number(t).toString()?Number(t):""===t||"null"===t?null:t)}function W(t){return t.replace(/[A-Z]/g,t=>"-"+t.toLowerCase())}P.on(document,"click.bs.button.data-api",'[data-bs-toggle="button"]',t=>{t.preventDefault();const e=t.target.closest('[data-bs-toggle="button"]');let s=w.get(e,"bs.button");s||(s=new R(e)),s.toggle()}),v("button",R);const $={setDataAttribute(t,e,s){t.setAttribute("data-bs-"+W(e),s)},removeDataAttribute(t,e){t.removeAttribute("data-bs-"+W(e))},getDataAttributes(t){if(!t)return{};const e={};return Object.keys(t.dataset).filter(t=>t.startsWith("bs")).forEach(s=>{let i=s.replace(/^bs/,"");i=i.charAt(0).toLowerCase()+i.slice(1,i.length),e[i]=B(t.dataset[s])}),e},getDataAttribute:(t,e)=>B(t.getAttribute("data-bs-"+W(e))),offset(t){const e=t.getBoundingClientRect();return{top:e.top+document.body.scrollTop,left:e.left+document.body.scrollLeft}},position:t=>({top:t.offsetTop,left:t.offsetLeft})},U={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter(t=>t.matches(e)),parents(t,e){const s=[];let i=t.parentNode;for(;i&&i.nodeType===Node.ELEMENT_NODE&&3!==i.nodeType;)i.matches(e)&&s.push(i),i=i.parentNode;return s},prev(t,e){let s=t.previousElementSibling;for(;s;){if(s.matches(e))return[s];s=s.previousElementSibling}return[]},next(t,e){let s=t.nextElementSibling;for(;s;){if(s.matches(e))return[s];s=s.nextElementSibling}return[]}},F={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},K={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},z="next",Y="prev",q="left",Q="right";class X extends M{constructor(t,e){super(t),this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._indicatorsElement=U.findOne(".carousel-indicators",this._element),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent),this._addEventListeners()}static get Default(){return F}static get DATA_KEY(){return"bs.carousel"}next(){this._isSliding||this._slide(z)}nextWhenVisible(){!document.hidden&&u(this._element)&&this.next()}prev(){this._isSliding||this._slide(Y)}pause(t){t||(this._isPaused=!0),U.findOne(".carousel-item-next, .carousel-item-prev",this._element)&&(l(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null}cycle(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config&&this._config.interval&&!this._isPaused&&(this._updateInterval(),this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))}to(t){this._activeElement=U.findOne(".active.carousel-item",this._element);const e=this._getItemIndex(this._activeElement);if(t>this._items.length-1||t<0)return;if(this._isSliding)return void P.one(this._element,"slid.bs.carousel",()=>this.to(t));if(e===t)return this.pause(),void this.cycle();const s=t>e?z:Y;this._slide(s,this._items[t])}dispose(){P.off(this._element,".bs.carousel"),this._items=null,this._config=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null,super.dispose()}_getConfig(t){return t={...F,...t},d("carousel",t,K),t}_handleSwipe(){const t=Math.abs(this.touchDeltaX);if(t<=40)return;const e=t/this.touchDeltaX;this.touchDeltaX=0,e&&this._slide(e>0?Q:q)}_addEventListeners(){this._config.keyboard&&P.on(this._element,"keydown.bs.carousel",t=>this._keydown(t)),"hover"===this._config.pause&&(P.on(this._element,"mouseenter.bs.carousel",t=>this.pause(t)),P.on(this._element,"mouseleave.bs.carousel",t=>this.cycle(t))),this._config.touch&&this._touchSupported&&this._addTouchEventListeners()}_addTouchEventListeners(){const t=t=>{!this._pointerEvent||"pen"!==t.pointerType&&"touch"!==t.pointerType?this._pointerEvent||(this.touchStartX=t.touches[0].clientX):this.touchStartX=t.clientX},e=t=>{this.touchDeltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this.touchStartX},s=t=>{!this._pointerEvent||"pen"!==t.pointerType&&"touch"!==t.pointerType||(this.touchDeltaX=t.clientX-this.touchStartX),this._handleSwipe(),"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout(t=>this.cycle(t),500+this._config.interval))};U.find(".carousel-item img",this._element).forEach(t=>{P.on(t,"dragstart.bs.carousel",t=>t.preventDefault())}),this._pointerEvent?(P.on(this._element,"pointerdown.bs.carousel",e=>t(e)),P.on(this._element,"pointerup.bs.carousel",t=>s(t)),this._element.classList.add("pointer-event")):(P.on(this._element,"touchstart.bs.carousel",e=>t(e)),P.on(this._element,"touchmove.bs.carousel",t=>e(t)),P.on(this._element,"touchend.bs.carousel",t=>s(t)))}_keydown(t){/input|textarea/i.test(t.target.tagName)||("ArrowLeft"===t.key?(t.preventDefault(),this._slide(q)):"ArrowRight"===t.key&&(t.preventDefault(),this._slide(Q)))}_getItemIndex(t){return this._items=t&&t.parentNode?U.find(".carousel-item",t.parentNode):[],this._items.indexOf(t)}_getItemByOrder(t,e){const s=t===z,i=t===Y,n=this._getItemIndex(e),o=this._items.length-1;if((i&&0===n||s&&n===o)&&!this._config.wrap)return e;const r=(n+(i?-1:1))%this._items.length;return-1===r?this._items[this._items.length-1]:this._items[r]}_triggerSlideEvent(t,e){const s=this._getItemIndex(t),i=this._getItemIndex(U.findOne(".active.carousel-item",this._element));return P.trigger(this._element,"slide.bs.carousel",{relatedTarget:t,direction:e,from:i,to:s})}_setActiveIndicatorElement(t){if(this._indicatorsElement){const e=U.findOne(".active",this._indicatorsElement);e.classList.remove("active"),e.removeAttribute("aria-current");const s=U.find("[data-bs-target]",this._indicatorsElement);for(let e=0;e{o.classList.remove(d,u),o.classList.add("active"),i.classList.remove("active",u,d),this._isSliding=!1,setTimeout(()=>{P.trigger(this._element,"slid.bs.carousel",{relatedTarget:o,direction:g,from:n,to:r})},0)}),h(i,t)}else i.classList.remove("active"),o.classList.add("active"),this._isSliding=!1,P.trigger(this._element,"slid.bs.carousel",{relatedTarget:o,direction:g,from:n,to:r});l&&this.cycle()}}_directionToOrder(t){return[Q,q].includes(t)?b()?t===Q?Y:z:t===Q?z:Y:t}_orderToDirection(t){return[z,Y].includes(t)?b()?t===z?q:Q:t===z?Q:q:t}static carouselInterface(t,e){let s=w.get(t,"bs.carousel"),i={...F,...$.getDataAttributes(t)};"object"==typeof e&&(i={...i,...e});const n="string"==typeof e?e:i.slide;if(s||(s=new X(t,i)),"number"==typeof e)s.to(e);else if("string"==typeof n){if(void 0===s[n])throw new TypeError(`No method named "${n}"`);s[n]()}else i.interval&&i.ride&&(s.pause(),s.cycle())}static jQueryInterface(t){return this.each((function(){X.carouselInterface(this,t)}))}static dataApiClickHandler(t){const e=r(this);if(!e||!e.classList.contains("carousel"))return;const s={...$.getDataAttributes(e),...$.getDataAttributes(this)},i=this.getAttribute("data-bs-slide-to");i&&(s.interval=!1),X.carouselInterface(e,s),i&&w.get(e,"bs.carousel").to(i),t.preventDefault()}}P.on(document,"click.bs.carousel.data-api","[data-bs-slide], [data-bs-slide-to]",X.dataApiClickHandler),P.on(window,"load.bs.carousel.data-api",()=>{const t=U.find('[data-bs-ride="carousel"]');for(let e=0,s=t.length;et===this._element);null!==i&&n.length&&(this._selector=i,this._triggerArray.push(e))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}static get Default(){return V}static get DATA_KEY(){return"bs.collapse"}toggle(){this._element.classList.contains("show")?this.hide():this.show()}show(){if(this._isTransitioning||this._element.classList.contains("show"))return;let t,e;this._parent&&(t=U.find(".show, .collapsing",this._parent).filter(t=>"string"==typeof this._config.parent?t.getAttribute("data-bs-parent")===this._config.parent:t.classList.contains("collapse")),0===t.length&&(t=null));const s=U.findOne(this._selector);if(t){const i=t.find(t=>s!==t);if(e=i?w.get(i,"bs.collapse"):null,e&&e._isTransitioning)return}if(P.trigger(this._element,"show.bs.collapse").defaultPrevented)return;t&&t.forEach(t=>{s!==t&&Z.collapseInterface(t,"hide"),e||w.set(t,"bs.collapse",null)});const i=this._getDimension();this._element.classList.remove("collapse"),this._element.classList.add("collapsing"),this._element.style[i]=0,this._triggerArray.length&&this._triggerArray.forEach(t=>{t.classList.remove("collapsed"),t.setAttribute("aria-expanded",!0)}),this.setTransitioning(!0);const n="scroll"+(i[0].toUpperCase()+i.slice(1)),o=a(this._element);P.one(this._element,"transitionend",()=>{this._element.classList.remove("collapsing"),this._element.classList.add("collapse","show"),this._element.style[i]="",this.setTransitioning(!1),P.trigger(this._element,"shown.bs.collapse")}),h(this._element,o),this._element.style[i]=this._element[n]+"px"}hide(){if(this._isTransitioning||!this._element.classList.contains("show"))return;if(P.trigger(this._element,"hide.bs.collapse").defaultPrevented)return;const t=this._getDimension();this._element.style[t]=this._element.getBoundingClientRect()[t]+"px",m(this._element),this._element.classList.add("collapsing"),this._element.classList.remove("collapse","show");const e=this._triggerArray.length;if(e>0)for(let t=0;t{this.setTransitioning(!1),this._element.classList.remove("collapsing"),this._element.classList.add("collapse"),P.trigger(this._element,"hidden.bs.collapse")}),h(this._element,s)}setTransitioning(t){this._isTransitioning=t}dispose(){super.dispose(),this._config=null,this._parent=null,this._triggerArray=null,this._isTransitioning=null}_getConfig(t){return(t={...V,...t}).toggle=Boolean(t.toggle),d("collapse",t,G),t}_getDimension(){return this._element.classList.contains("width")?"width":"height"}_getParent(){let{parent:t}=this._config;c(t)?void 0===t.jquery&&void 0===t[0]||(t=t[0]):t=U.findOne(t);const e=`[data-bs-toggle="collapse"][data-bs-parent="${t}"]`;return U.find(e,t).forEach(t=>{const e=r(t);this._addAriaAndCollapsedClass(e,[t])}),t}_addAriaAndCollapsedClass(t,e){if(!t||!e.length)return;const s=t.classList.contains("show");e.forEach(t=>{s?t.classList.remove("collapsed"):t.classList.add("collapsed"),t.setAttribute("aria-expanded",s)})}static collapseInterface(t,e){let s=w.get(t,"bs.collapse");const i={...V,...$.getDataAttributes(t),..."object"==typeof e&&e?e:{}};if(!s&&i.toggle&&"string"==typeof e&&/show|hide/.test(e)&&(i.toggle=!1),s||(s=new Z(t,i)),"string"==typeof e){if(void 0===s[e])throw new TypeError(`No method named "${e}"`);s[e]()}}static jQueryInterface(t){return this.each((function(){Z.collapseInterface(this,t)}))}}P.on(document,"click.bs.collapse.data-api",'[data-bs-toggle="collapse"]',(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();const e=$.getDataAttributes(this),s=o(this);U.find(s).forEach(t=>{const s=w.get(t,"bs.collapse");let i;s?(null===s._parent&&"string"==typeof e.parent&&(s._config.parent=e.parent,s._parent=s._getParent()),i="toggle"):i=e,Z.collapseInterface(t,i)})})),v("collapse",Z);const J=new RegExp("ArrowUp|ArrowDown|Escape"),tt=b()?"top-end":"top-start",et=b()?"top-start":"top-end",st=b()?"bottom-end":"bottom-start",it=b()?"bottom-start":"bottom-end",nt=b()?"left-start":"right-start",ot=b()?"right-start":"left-start",rt={offset:[0,2],boundary:"clippingParents",reference:"toggle",display:"dynamic",popperConfig:null},at={offset:"(array|string|function)",boundary:"(string|element)",reference:"(string|element|object)",display:"string",popperConfig:"(null|object|function)"};class lt extends M{constructor(t,e){super(t),this._popper=null,this._config=this._getConfig(e),this._menu=this._getMenuElement(),this._inNavbar=this._detectNavbar(),this._addEventListeners()}static get Default(){return rt}static get DefaultType(){return at}static get DATA_KEY(){return"bs.dropdown"}toggle(){if(this._element.disabled||this._element.classList.contains("disabled"))return;const t=this._element.classList.contains("show");lt.clearMenus(),t||this.show()}show(){if(this._element.disabled||this._element.classList.contains("disabled")||this._menu.classList.contains("show"))return;const t=lt.getParentFromElement(this._element),e={relatedTarget:this._element};if(!P.trigger(this._element,"show.bs.dropdown",e).defaultPrevented){if(this._inNavbar)$.setDataAttribute(this._menu,"popper","none");else{if(void 0===s)throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");let e=this._element;"parent"===this._config.reference?e=t:c(this._config.reference)?(e=this._config.reference,void 0!==this._config.reference.jquery&&(e=this._config.reference[0])):"object"==typeof this._config.reference&&(e=this._config.reference);const i=this._getPopperConfig(),n=i.modifiers.find(t=>"applyStyles"===t.name&&!1===t.enabled);this._popper=s.createPopper(e,this._menu,i),n&&$.setDataAttribute(this._menu,"popper","static")}"ontouchstart"in document.documentElement&&!t.closest(".navbar-nav")&&[].concat(...document.body.children).forEach(t=>P.on(t,"mouseover",null,(function(){}))),this._element.focus(),this._element.setAttribute("aria-expanded",!0),this._menu.classList.toggle("show"),this._element.classList.toggle("show"),P.trigger(this._element,"shown.bs.dropdown",e)}}hide(){if(this._element.disabled||this._element.classList.contains("disabled")||!this._menu.classList.contains("show"))return;const t={relatedTarget:this._element};P.trigger(this._element,"hide.bs.dropdown",t).defaultPrevented||(this._popper&&this._popper.destroy(),this._menu.classList.toggle("show"),this._element.classList.toggle("show"),$.removeDataAttribute(this._menu,"popper"),P.trigger(this._element,"hidden.bs.dropdown",t))}dispose(){P.off(this._element,".bs.dropdown"),this._menu=null,this._popper&&(this._popper.destroy(),this._popper=null),super.dispose()}update(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.update()}_addEventListeners(){P.on(this._element,"click.bs.dropdown",t=>{t.preventDefault(),this.toggle()})}_getConfig(t){if(t={...this.constructor.Default,...$.getDataAttributes(this._element),...t},d("dropdown",t,this.constructor.DefaultType),"object"==typeof t.reference&&!c(t.reference)&&"function"!=typeof t.reference.getBoundingClientRect)throw new TypeError("dropdown".toUpperCase()+': Option "reference" provided type "object" without a required "getBoundingClientRect" method.');return t}_getMenuElement(){return U.next(this._element,".dropdown-menu")[0]}_getPlacement(){const t=this._element.parentNode;if(t.classList.contains("dropend"))return nt;if(t.classList.contains("dropstart"))return ot;const e="end"===getComputedStyle(this._menu).getPropertyValue("--bs-position").trim();return t.classList.contains("dropup")?e?et:tt:e?it:st}_detectNavbar(){return null!==this._element.closest(".navbar")}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map(t=>Number.parseInt(t,10)):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return"static"===this._config.display&&(t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,..."function"==typeof this._config.popperConfig?this._config.popperConfig(t):this._config.popperConfig}}static dropdownInterface(t,e){let s=w.get(t,"bs.dropdown");if(s||(s=new lt(t,"object"==typeof e?e:null)),"string"==typeof e){if(void 0===s[e])throw new TypeError(`No method named "${e}"`);s[e]()}}static jQueryInterface(t){return this.each((function(){lt.dropdownInterface(this,t)}))}static clearMenus(t){if(t){if(2===t.button||"keyup"===t.type&&"Tab"!==t.key)return;if(/input|select|textarea|form/i.test(t.target.tagName))return}const e=U.find('[data-bs-toggle="dropdown"]');for(let s=0,i=e.length;st.composedPath().includes(e)))continue;if("keyup"===t.type&&"Tab"===t.key&&o.contains(t.target))continue}P.trigger(e[s],"hide.bs.dropdown",n).defaultPrevented||("ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach(t=>P.off(t,"mouseover",null,(function(){}))),e[s].setAttribute("aria-expanded","false"),i._popper&&i._popper.destroy(),o.classList.remove("show"),e[s].classList.remove("show"),$.removeDataAttribute(o,"popper"),P.trigger(e[s],"hidden.bs.dropdown",n))}}}static getParentFromElement(t){return r(t)||t.parentNode}static dataApiKeydownHandler(t){if(/input|textarea/i.test(t.target.tagName)?"Space"===t.key||"Escape"!==t.key&&("ArrowDown"!==t.key&&"ArrowUp"!==t.key||t.target.closest(".dropdown-menu")):!J.test(t.key))return;if(t.preventDefault(),t.stopPropagation(),this.disabled||this.classList.contains("disabled"))return;const e=lt.getParentFromElement(this),s=this.classList.contains("show");if("Escape"===t.key)return(this.matches('[data-bs-toggle="dropdown"]')?this:U.prev(this,'[data-bs-toggle="dropdown"]')[0]).focus(),void lt.clearMenus();if(!s&&("ArrowUp"===t.key||"ArrowDown"===t.key))return void(this.matches('[data-bs-toggle="dropdown"]')?this:U.prev(this,'[data-bs-toggle="dropdown"]')[0]).click();if(!s||"Space"===t.key)return void lt.clearMenus();const i=U.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",e).filter(u);if(!i.length)return;let n=i.indexOf(t.target);"ArrowUp"===t.key&&n>0&&n--,"ArrowDown"===t.key&&nthis.hide(t)),P.on(this._dialog,"mousedown.dismiss.bs.modal",()=>{P.one(this._element,"mouseup.dismiss.bs.modal",t=>{t.target===this._element&&(this._ignoreBackdropClick=!0)})}),this._showBackdrop(()=>this._showElement(t)))}hide(t){if(t&&t.preventDefault(),!this._isShown||this._isTransitioning)return;if(P.trigger(this._element,"hide.bs.modal").defaultPrevented)return;this._isShown=!1;const e=this._isAnimated();if(e&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),P.off(document,"focusin.bs.modal"),this._element.classList.remove("show"),P.off(this._element,"click.dismiss.bs.modal"),P.off(this._dialog,"mousedown.dismiss.bs.modal"),e){const t=a(this._element);P.one(this._element,"transitionend",t=>this._hideModal(t)),h(this._element,t)}else this._hideModal()}dispose(){[window,this._element,this._dialog].forEach(t=>P.off(t,".bs.modal")),super.dispose(),P.off(document,"focusin.bs.modal"),this._config=null,this._dialog=null,this._backdrop=null,this._isShown=null,this._isBodyOverflowing=null,this._ignoreBackdropClick=null,this._isTransitioning=null,this._scrollbarWidth=null}handleUpdate(){this._adjustDialog()}_getConfig(t){return t={...ct,...t},d("modal",t,ht),t}_showElement(t){const e=this._isAnimated(),s=U.findOne(".modal-body",this._dialog);this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0,s&&(s.scrollTop=0),e&&m(this._element),this._element.classList.add("show"),this._config.focus&&this._enforceFocus();const i=()=>{this._config.focus&&this._element.focus(),this._isTransitioning=!1,P.trigger(this._element,"shown.bs.modal",{relatedTarget:t})};if(e){const t=a(this._dialog);P.one(this._dialog,"transitionend",i),h(this._dialog,t)}else i()}_enforceFocus(){P.off(document,"focusin.bs.modal"),P.on(document,"focusin.bs.modal",t=>{document===t.target||this._element===t.target||this._element.contains(t.target)||this._element.focus()})}_setEscapeEvent(){this._isShown?P.on(this._element,"keydown.dismiss.bs.modal",t=>{this._config.keyboard&&"Escape"===t.key?(t.preventDefault(),this.hide()):this._config.keyboard||"Escape"!==t.key||this._triggerBackdropTransition()}):P.off(this._element,"keydown.dismiss.bs.modal")}_setResizeEvent(){this._isShown?P.on(window,"resize.bs.modal",()=>this._adjustDialog()):P.off(window,"resize.bs.modal")}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._showBackdrop(()=>{document.body.classList.remove("modal-open"),this._resetAdjustments(),this._resetScrollbar(),P.trigger(this._element,"hidden.bs.modal")})}_removeBackdrop(){this._backdrop.parentNode.removeChild(this._backdrop),this._backdrop=null}_showBackdrop(t){const e=this._isAnimated();if(this._isShown&&this._config.backdrop){if(this._backdrop=document.createElement("div"),this._backdrop.className="modal-backdrop",e&&this._backdrop.classList.add("fade"),document.body.appendChild(this._backdrop),P.on(this._element,"click.dismiss.bs.modal",t=>{this._ignoreBackdropClick?this._ignoreBackdropClick=!1:t.target===t.currentTarget&&("static"===this._config.backdrop?this._triggerBackdropTransition():this.hide())}),e&&m(this._backdrop),this._backdrop.classList.add("show"),!e)return void t();const s=a(this._backdrop);P.one(this._backdrop,"transitionend",t),h(this._backdrop,s)}else if(!this._isShown&&this._backdrop){this._backdrop.classList.remove("show");const s=()=>{this._removeBackdrop(),t()};if(e){const t=a(this._backdrop);P.one(this._backdrop,"transitionend",s),h(this._backdrop,t)}else s()}else t()}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(P.trigger(this._element,"hidePrevented.bs.modal").defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight;t||(this._element.style.overflowY="hidden"),this._element.classList.add("modal-static");const e=a(this._dialog);P.off(this._element,"transitionend"),P.one(this._element,"transitionend",()=>{this._element.classList.remove("modal-static"),t||(P.one(this._element,"transitionend",()=>{this._element.style.overflowY=""}),h(this._element,e))}),h(this._element,e),this._element.focus()}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight;(!this._isBodyOverflowing&&t&&!b()||this._isBodyOverflowing&&!t&&b())&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),(this._isBodyOverflowing&&!t&&!b()||!this._isBodyOverflowing&&t&&b())&&(this._element.style.paddingRight=this._scrollbarWidth+"px")}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}_checkScrollbar(){const t=document.body.getBoundingClientRect();this._isBodyOverflowing=Math.round(t.left+t.right)t+this._scrollbarWidth),this._setElementAttributes(".sticky-top","marginRight",t=>t-this._scrollbarWidth),this._setElementAttributes("body","paddingRight",t=>t+this._scrollbarWidth)),document.body.classList.add("modal-open")}_setElementAttributes(t,e,s){U.find(t).forEach(t=>{if(t!==document.body&&window.innerWidth>t.clientWidth+this._scrollbarWidth)return;const i=t.style[e],n=window.getComputedStyle(t)[e];$.setDataAttribute(t,e,i),t.style[e]=s(Number.parseFloat(n))+"px"})}_resetScrollbar(){this._resetElementAttributes(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top","paddingRight"),this._resetElementAttributes(".sticky-top","marginRight"),this._resetElementAttributes("body","paddingRight")}_resetElementAttributes(t,e){U.find(t).forEach(t=>{const s=$.getDataAttribute(t,e);void 0===s&&t===document.body?t.style[e]="":($.removeDataAttribute(t,e),t.style[e]=s)})}_getScrollbarWidth(){const t=document.createElement("div");t.className="modal-scrollbar-measure",document.body.appendChild(t);const e=t.getBoundingClientRect().width-t.clientWidth;return document.body.removeChild(t),e}static jQueryInterface(t,e){return this.each((function(){let s=w.get(this,"bs.modal");const i={...ct,...$.getDataAttributes(this),..."object"==typeof t&&t?t:{}};if(s||(s=new dt(this,i)),"string"==typeof t){if(void 0===s[t])throw new TypeError(`No method named "${t}"`);s[t](e)}}))}}P.on(document,"click.bs.modal.data-api",'[data-bs-toggle="modal"]',(function(t){const e=r(this);"A"!==this.tagName&&"AREA"!==this.tagName||t.preventDefault(),P.one(e,"show.bs.modal",t=>{t.defaultPrevented||P.one(e,"hidden.bs.modal",()=>{u(this)&&this.focus()})});let s=w.get(e,"bs.modal");if(!s){const t={...$.getDataAttributes(e),...$.getDataAttributes(this)};s=new dt(e,t)}s.toggle(this)})),v("modal",dt);const ut=()=>{const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)},gt=(t,e,s)=>{const i=ut();U.find(t).forEach(t=>{if(t!==document.body&&window.innerWidth>t.clientWidth+i)return;const n=t.style[e],o=window.getComputedStyle(t)[e];$.setDataAttribute(t,e,n),t.style[e]=s(Number.parseFloat(o))+"px"})},ft=(t,e)=>{U.find(t).forEach(t=>{const s=$.getDataAttribute(t,e);void 0===s&&t===document.body?t.style.removeProperty(e):($.removeDataAttribute(t,e),t.style[e]=s)})},pt={backdrop:!0,keyboard:!0,scroll:!1},mt={backdrop:"boolean",keyboard:"boolean",scroll:"boolean"};class _t extends M{constructor(t,e){super(t),this._config=this._getConfig(e),this._isShown=!1,this._addEventListeners()}static get Default(){return pt}static get DATA_KEY(){return"bs.offcanvas"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||P.trigger(this._element,"show.bs.offcanvas",{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._element.style.visibility="visible",this._config.backdrop&&document.body.classList.add("offcanvas-backdrop"),this._config.scroll||((t=ut())=>{document.body.style.overflow="hidden",gt(".fixed-top, .fixed-bottom, .is-fixed","paddingRight",e=>e+t),gt(".sticky-top","marginRight",e=>e-t),gt("body","paddingRight",e=>e+t)})(),this._element.classList.add("offcanvas-toggling"),this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add("show"),setTimeout(()=>{this._element.classList.remove("offcanvas-toggling"),P.trigger(this._element,"shown.bs.offcanvas",{relatedTarget:t}),this._enforceFocusOnElement(this._element)},a(this._element)))}hide(){this._isShown&&(P.trigger(this._element,"hide.bs.offcanvas").defaultPrevented||(this._element.classList.add("offcanvas-toggling"),P.off(document,"focusin.bs.offcanvas"),this._element.blur(),this._isShown=!1,this._element.classList.remove("show"),setTimeout(()=>{this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._element.style.visibility="hidden",this._config.backdrop&&document.body.classList.remove("offcanvas-backdrop"),this._config.scroll||(document.body.style.overflow="auto",ft(".fixed-top, .fixed-bottom, .is-fixed","paddingRight"),ft(".sticky-top","marginRight"),ft("body","paddingRight")),P.trigger(this._element,"hidden.bs.offcanvas"),this._element.classList.remove("offcanvas-toggling")},a(this._element))))}_getConfig(t){return t={...pt,...$.getDataAttributes(this._element),..."object"==typeof t?t:{}},d("offcanvas",t,mt),t}_enforceFocusOnElement(t){P.off(document,"focusin.bs.offcanvas"),P.on(document,"focusin.bs.offcanvas",e=>{document===e.target||t===e.target||t.contains(e.target)||t.focus()}),t.focus()}_addEventListeners(){P.on(this._element,"click.dismiss.bs.offcanvas",'[data-bs-dismiss="offcanvas"]',()=>this.hide()),P.on(document,"keydown",t=>{this._config.keyboard&&"Escape"===t.key&&this.hide()}),P.on(document,"click.bs.offcanvas.data-api",t=>{const e=U.findOne(o(t.target));this._element.contains(t.target)||e===this._element||this.hide()})}static jQueryInterface(t){return this.each((function(){const e=w.get(this,"bs.offcanvas")||new _t(this,"object"==typeof t?t:{});if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}P.on(document,"click.bs.offcanvas.data-api",'[data-bs-toggle="offcanvas"]',(function(t){const e=r(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),g(this))return;P.one(e,"hidden.bs.offcanvas",()=>{u(this)&&this.focus()});const s=U.findOne(".offcanvas.show, .offcanvas-toggling");s&&s!==e||(w.get(e,"bs.offcanvas")||new _t(e)).toggle(this)})),P.on(window,"load.bs.offcanvas.data-api",()=>{U.find(".offcanvas.show").forEach(t=>(w.get(t,"bs.offcanvas")||new _t(t)).show())}),v("offcanvas",_t);const bt=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),vt=/^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/i,yt=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i,wt=(t,e)=>{const s=t.nodeName.toLowerCase();if(e.includes(s))return!bt.has(s)||Boolean(vt.test(t.nodeValue)||yt.test(t.nodeValue));const i=e.filter(t=>t instanceof RegExp);for(let t=0,e=i.length;t{wt(t,a)||s.removeAttribute(t.nodeName)})}return i.body.innerHTML}const Tt=new RegExp("(^|\\s)bs-tooltip\\S+","g"),At=new Set(["sanitize","allowList","sanitizeFn"]),Lt={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(array|string|function)",container:"(string|element|boolean)",fallbackPlacements:"array",boundary:"(string|element)",customClass:"(string|function)",sanitize:"boolean",sanitizeFn:"(null|function)",allowList:"object",popperConfig:"(null|object|function)"},kt={AUTO:"auto",TOP:"top",RIGHT:b()?"left":"right",BOTTOM:"bottom",LEFT:b()?"right":"left"},Ct={animation:!0,template:'',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:[0,0],container:!1,fallbackPlacements:["top","right","bottom","left"],boundary:"clippingParents",customClass:"",sanitize:!0,sanitizeFn:null,allowList:{"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},popperConfig:null},Dt={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"};class St extends M{constructor(t,e){if(void 0===s)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t),this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.config=this._getConfig(e),this.tip=null,this._setListeners()}static get Default(){return Ct}static get NAME(){return"tooltip"}static get DATA_KEY(){return"bs.tooltip"}static get Event(){return Dt}static get EVENT_KEY(){return".bs.tooltip"}static get DefaultType(){return Lt}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(t){if(this._isEnabled)if(t){const e=this._initializeOnDelegatedTarget(t);e._activeTrigger.click=!e._activeTrigger.click,e._isWithActiveTrigger()?e._enter(null,e):e._leave(null,e)}else{if(this.getTipElement().classList.contains("show"))return void this._leave(null,this);this._enter(null,this)}}dispose(){clearTimeout(this._timeout),P.off(this._element,this.constructor.EVENT_KEY),P.off(this._element.closest(".modal"),"hide.bs.modal",this._hideModalHandler),this.tip&&this.tip.parentNode&&this.tip.parentNode.removeChild(this.tip),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.config=null,this.tip=null,super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this.isWithContent()||!this._isEnabled)return;const t=P.trigger(this._element,this.constructor.Event.SHOW),e=f(this._element),n=null===e?this._element.ownerDocument.documentElement.contains(this._element):e.contains(this._element);if(t.defaultPrevented||!n)return;const o=this.getTipElement(),r=i(this.constructor.NAME);o.setAttribute("id",r),this._element.setAttribute("aria-describedby",r),this.setContent(),this.config.animation&&o.classList.add("fade");const l="function"==typeof this.config.placement?this.config.placement.call(this,o,this._element):this.config.placement,c=this._getAttachment(l);this._addAttachmentClass(c);const d=this._getContainer();w.set(o,this.constructor.DATA_KEY,this),this._element.ownerDocument.documentElement.contains(this.tip)||(d.appendChild(o),P.trigger(this._element,this.constructor.Event.INSERTED)),this._popper?this._popper.update():this._popper=s.createPopper(this._element,o,this._getPopperConfig(c)),o.classList.add("show");const u="function"==typeof this.config.customClass?this.config.customClass():this.config.customClass;u&&o.classList.add(...u.split(" ")),"ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach(t=>{P.on(t,"mouseover",(function(){}))});const g=()=>{const t=this._hoverState;this._hoverState=null,P.trigger(this._element,this.constructor.Event.SHOWN),"out"===t&&this._leave(null,this)};if(this.tip.classList.contains("fade")){const t=a(this.tip);P.one(this.tip,"transitionend",g),h(this.tip,t)}else g()}hide(){if(!this._popper)return;const t=this.getTipElement(),e=()=>{this._isWithActiveTrigger()||("show"!==this._hoverState&&t.parentNode&&t.parentNode.removeChild(t),this._cleanTipClass(),this._element.removeAttribute("aria-describedby"),P.trigger(this._element,this.constructor.Event.HIDDEN),this._popper&&(this._popper.destroy(),this._popper=null))};if(!P.trigger(this._element,this.constructor.Event.HIDE).defaultPrevented){if(t.classList.remove("show"),"ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach(t=>P.off(t,"mouseover",p)),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,this.tip.classList.contains("fade")){const s=a(t);P.one(t,"transitionend",e),h(t,s)}else e();this._hoverState=""}}update(){null!==this._popper&&this._popper.update()}isWithContent(){return Boolean(this.getTitle())}getTipElement(){if(this.tip)return this.tip;const t=document.createElement("div");return t.innerHTML=this.config.template,this.tip=t.children[0],this.tip}setContent(){const t=this.getTipElement();this.setElementContent(U.findOne(".tooltip-inner",t),this.getTitle()),t.classList.remove("fade","show")}setElementContent(t,e){if(null!==t)return"object"==typeof e&&c(e)?(e.jquery&&(e=e[0]),void(this.config.html?e.parentNode!==t&&(t.innerHTML="",t.appendChild(e)):t.textContent=e.textContent)):void(this.config.html?(this.config.sanitize&&(e=Et(e,this.config.allowList,this.config.sanitizeFn)),t.innerHTML=e):t.textContent=e)}getTitle(){let t=this._element.getAttribute("data-bs-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this._element):this.config.title),t}updateAttachment(t){return"right"===t?"end":"left"===t?"start":t}_initializeOnDelegatedTarget(t,e){const s=this.constructor.DATA_KEY;return(e=e||w.get(t.delegateTarget,s))||(e=new this.constructor(t.delegateTarget,this._getDelegateConfig()),w.set(t.delegateTarget,s,e)),e}_getOffset(){const{offset:t}=this.config;return"string"==typeof t?t.split(",").map(t=>Number.parseInt(t,10)):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{altBoundary:!0,fallbackPlacements:this.config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this.config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"onChange",enabled:!0,phase:"afterWrite",fn:t=>this._handlePopperPlacementChange(t)}],onFirstUpdate:t=>{t.options.placement!==t.placement&&this._handlePopperPlacementChange(t)}};return{...e,..."function"==typeof this.config.popperConfig?this.config.popperConfig(e):this.config.popperConfig}}_addAttachmentClass(t){this.getTipElement().classList.add("bs-tooltip-"+this.updateAttachment(t))}_getContainer(){return!1===this.config.container?document.body:c(this.config.container)?this.config.container:U.findOne(this.config.container)}_getAttachment(t){return kt[t.toUpperCase()]}_setListeners(){this.config.trigger.split(" ").forEach(t=>{if("click"===t)P.on(this._element,this.constructor.Event.CLICK,this.config.selector,t=>this.toggle(t));else if("manual"!==t){const e="hover"===t?this.constructor.Event.MOUSEENTER:this.constructor.Event.FOCUSIN,s="hover"===t?this.constructor.Event.MOUSELEAVE:this.constructor.Event.FOCUSOUT;P.on(this._element,e,this.config.selector,t=>this._enter(t)),P.on(this._element,s,this.config.selector,t=>this._leave(t))}}),this._hideModalHandler=()=>{this._element&&this.hide()},P.on(this._element.closest(".modal"),"hide.bs.modal",this._hideModalHandler),this.config.selector?this.config={...this.config,trigger:"manual",selector:""}:this._fixTitle()}_fixTitle(){const t=this._element.getAttribute("title"),e=typeof this._element.getAttribute("data-bs-original-title");(t||"string"!==e)&&(this._element.setAttribute("data-bs-original-title",t||""),!t||this._element.getAttribute("aria-label")||this._element.textContent||this._element.setAttribute("aria-label",t),this._element.setAttribute("title",""))}_enter(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusin"===t.type?"focus":"hover"]=!0),e.getTipElement().classList.contains("show")||"show"===e._hoverState?e._hoverState="show":(clearTimeout(e._timeout),e._hoverState="show",e.config.delay&&e.config.delay.show?e._timeout=setTimeout(()=>{"show"===e._hoverState&&e.show()},e.config.delay.show):e.show())}_leave(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusout"===t.type?"focus":"hover"]=e._element.contains(t.relatedTarget)),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState="out",e.config.delay&&e.config.delay.hide?e._timeout=setTimeout(()=>{"out"===e._hoverState&&e.hide()},e.config.delay.hide):e.hide())}_isWithActiveTrigger(){for(const t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1}_getConfig(t){const e=$.getDataAttributes(this._element);return Object.keys(e).forEach(t=>{At.has(t)&&delete e[t]}),t&&"object"==typeof t.container&&t.container.jquery&&(t.container=t.container[0]),"number"==typeof(t={...this.constructor.Default,...e,..."object"==typeof t&&t?t:{}}).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),d("tooltip",t,this.constructor.DefaultType),t.sanitize&&(t.template=Et(t.template,t.allowList,t.sanitizeFn)),t}_getDelegateConfig(){const t={};if(this.config)for(const e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t}_cleanTipClass(){const t=this.getTipElement(),e=t.getAttribute("class").match(Tt);null!==e&&e.length>0&&e.map(t=>t.trim()).forEach(e=>t.classList.remove(e))}_handlePopperPlacementChange(t){const{state:e}=t;e&&(this.tip=e.elements.popper,this._cleanTipClass(),this._addAttachmentClass(this._getAttachment(e.placement)))}static jQueryInterface(t){return this.each((function(){let e=w.get(this,"bs.tooltip");const s="object"==typeof t&&t;if((e||!/dispose|hide/.test(t))&&(e||(e=new St(this,s)),"string"==typeof t)){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}v("tooltip",St);const Nt=new RegExp("(^|\\s)bs-popover\\S+","g"),Ot={...St.Default,placement:"right",offset:[0,8],trigger:"click",content:"",template:''},xt={...St.DefaultType,content:"(string|element|function)"},It={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"};class jt extends St{static get Default(){return Ot}static get NAME(){return"popover"}static get DATA_KEY(){return"bs.popover"}static get Event(){return It}static get EVENT_KEY(){return".bs.popover"}static get DefaultType(){return xt}isWithContent(){return this.getTitle()||this._getContent()}setContent(){const t=this.getTipElement();this.setElementContent(U.findOne(".popover-header",t),this.getTitle());let e=this._getContent();"function"==typeof e&&(e=e.call(this._element)),this.setElementContent(U.findOne(".popover-body",t),e),t.classList.remove("fade","show")}_addAttachmentClass(t){this.getTipElement().classList.add("bs-popover-"+this.updateAttachment(t))}_getContent(){return this._element.getAttribute("data-bs-content")||this.config.content}_cleanTipClass(){const t=this.getTipElement(),e=t.getAttribute("class").match(Nt);null!==e&&e.length>0&&e.map(t=>t.trim()).forEach(e=>t.classList.remove(e))}static jQueryInterface(t){return this.each((function(){let e=w.get(this,"bs.popover");const s="object"==typeof t?t:null;if((e||!/dispose|hide/.test(t))&&(e||(e=new jt(this,s),w.set(this,"bs.popover",e)),"string"==typeof t)){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}v("popover",jt);const Pt={offset:10,method:"auto",target:""},Mt={offset:"number",method:"string",target:"(string|element)"};class Ht extends M{constructor(t,e){super(t),this._scrollElement="BODY"===this._element.tagName?window:this._element,this._config=this._getConfig(e),this._selector=`${this._config.target} .nav-link, ${this._config.target} .list-group-item, ${this._config.target} .dropdown-item`,this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,P.on(this._scrollElement,"scroll.bs.scrollspy",()=>this._process()),this.refresh(),this._process()}static get Default(){return Pt}static get DATA_KEY(){return"bs.scrollspy"}refresh(){const t=this._scrollElement===this._scrollElement.window?"offset":"position",e="auto"===this._config.method?t:this._config.method,s="position"===e?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),U.find(this._selector).map(t=>{const i=o(t),n=i?U.findOne(i):null;if(n){const t=n.getBoundingClientRect();if(t.width||t.height)return[$[e](n).top+s,i]}return null}).filter(t=>t).sort((t,e)=>t[0]-e[0]).forEach(t=>{this._offsets.push(t[0]),this._targets.push(t[1])})}dispose(){super.dispose(),P.off(this._scrollElement,".bs.scrollspy"),this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null}_getConfig(t){if("string"!=typeof(t={...Pt,..."object"==typeof t&&t?t:{}}).target&&c(t.target)){let{id:e}=t.target;e||(e=i("scrollspy"),t.target.id=e),t.target="#"+e}return d("scrollspy",t,Mt),t}_getScrollTop(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop}_getScrollHeight(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)}_getOffsetHeight(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height}_process(){const t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),s=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=s){const t=this._targets[this._targets.length-1];this._activeTarget!==t&&this._activate(t)}else{if(this._activeTarget&&t0)return this._activeTarget=null,void this._clear();for(let e=this._offsets.length;e--;)this._activeTarget!==this._targets[e]&&t>=this._offsets[e]&&(void 0===this._offsets[e+1]||t`${e}[data-bs-target="${t}"],${e}[href="${t}"]`),s=U.findOne(e.join(","));s.classList.contains("dropdown-item")?(U.findOne(".dropdown-toggle",s.closest(".dropdown")).classList.add("active"),s.classList.add("active")):(s.classList.add("active"),U.parents(s,".nav, .list-group").forEach(t=>{U.prev(t,".nav-link, .list-group-item").forEach(t=>t.classList.add("active")),U.prev(t,".nav-item").forEach(t=>{U.children(t,".nav-link").forEach(t=>t.classList.add("active"))})})),P.trigger(this._scrollElement,"activate.bs.scrollspy",{relatedTarget:t})}_clear(){U.find(this._selector).filter(t=>t.classList.contains("active")).forEach(t=>t.classList.remove("active"))}static jQueryInterface(t){return this.each((function(){let e=w.get(this,"bs.scrollspy");if(e||(e=new Ht(this,"object"==typeof t&&t)),"string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}P.on(window,"load.bs.scrollspy.data-api",()=>{U.find('[data-bs-spy="scroll"]').forEach(t=>new Ht(t,$.getDataAttributes(t)))}),v("scrollspy",Ht);class Rt extends M{static get DATA_KEY(){return"bs.tab"}show(){if(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&this._element.classList.contains("active")||g(this._element))return;let t;const e=r(this._element),s=this._element.closest(".nav, .list-group");if(s){const e="UL"===s.nodeName||"OL"===s.nodeName?":scope > li > .active":".active";t=U.find(e,s),t=t[t.length-1]}const i=t?P.trigger(t,"hide.bs.tab",{relatedTarget:this._element}):null;if(P.trigger(this._element,"show.bs.tab",{relatedTarget:t}).defaultPrevented||null!==i&&i.defaultPrevented)return;this._activate(this._element,s);const n=()=>{P.trigger(t,"hidden.bs.tab",{relatedTarget:this._element}),P.trigger(this._element,"shown.bs.tab",{relatedTarget:t})};e?this._activate(e,e.parentNode,n):n()}_activate(t,e,s){const i=(!e||"UL"!==e.nodeName&&"OL"!==e.nodeName?U.children(e,".active"):U.find(":scope > li > .active",e))[0],n=s&&i&&i.classList.contains("fade"),o=()=>this._transitionComplete(t,i,s);if(i&&n){const t=a(i);i.classList.remove("show"),P.one(i,"transitionend",o),h(i,t)}else o()}_transitionComplete(t,e,s){if(e){e.classList.remove("active");const t=U.findOne(":scope > .dropdown-menu .active",e.parentNode);t&&t.classList.remove("active"),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!1)}t.classList.add("active"),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),m(t),t.classList.contains("fade")&&t.classList.add("show"),t.parentNode&&t.parentNode.classList.contains("dropdown-menu")&&(t.closest(".dropdown")&&U.find(".dropdown-toggle").forEach(t=>t.classList.add("active")),t.setAttribute("aria-expanded",!0)),s&&s()}static jQueryInterface(t){return this.each((function(){const e=w.get(this,"bs.tab")||new Rt(this);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}P.on(document,"click.bs.tab.data-api",'[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',(function(t){t.preventDefault(),(w.get(this,"bs.tab")||new Rt(this)).show()})),v("tab",Rt);const Bt={animation:"boolean",autohide:"boolean",delay:"number"},Wt={animation:!0,autohide:!0,delay:5e3};class $t extends M{constructor(t,e){super(t),this._config=this._getConfig(e),this._timeout=null,this._setListeners()}static get DefaultType(){return Bt}static get Default(){return Wt}static get DATA_KEY(){return"bs.toast"}show(){if(P.trigger(this._element,"show.bs.toast").defaultPrevented)return;this._clearTimeout(),this._config.animation&&this._element.classList.add("fade");const t=()=>{this._element.classList.remove("showing"),this._element.classList.add("show"),P.trigger(this._element,"shown.bs.toast"),this._config.autohide&&(this._timeout=setTimeout(()=>{this.hide()},this._config.delay))};if(this._element.classList.remove("hide"),m(this._element),this._element.classList.add("showing"),this._config.animation){const e=a(this._element);P.one(this._element,"transitionend",t),h(this._element,e)}else t()}hide(){if(!this._element.classList.contains("show"))return;if(P.trigger(this._element,"hide.bs.toast").defaultPrevented)return;const t=()=>{this._element.classList.add("hide"),P.trigger(this._element,"hidden.bs.toast")};if(this._element.classList.remove("show"),this._config.animation){const e=a(this._element);P.one(this._element,"transitionend",t),h(this._element,e)}else t()}dispose(){this._clearTimeout(),this._element.classList.contains("show")&&this._element.classList.remove("show"),P.off(this._element,"click.dismiss.bs.toast"),super.dispose(),this._config=null}_getConfig(t){return t={...Wt,...$.getDataAttributes(this._element),..."object"==typeof t&&t?t:{}},d("toast",t,this.constructor.DefaultType),t}_setListeners(){P.on(this._element,"click.dismiss.bs.toast",'[data-bs-dismiss="toast"]',()=>this.hide())}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){let e=w.get(this,"bs.toast");if(e||(e=new $t(this,"object"==typeof t&&t)),"string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return v("toast",$t),{Alert:H,Button:R,Carousel:X,Collapse:Z,Dropdown:lt,Modal:dt,Offcanvas:_t,Popover:jt,ScrollSpy:Ht,Tab:Rt,Toast:$t,Tooltip:St}})); Setting/SettingLicense.php000064400000001102152336352270011614 0ustar00 $data) { $this->choices[] = $key; $this->lang[$this->key . '_o_' . $key] = $data['name']; // stored in setting } parent::initialize($default, $local, $protected); } } Setting/SettingUndefined.php000064400000002312152336352270012137 0ustar00getKey(), $undefined_setting_match )) { $undefined_setting_key = $undefined_setting_match[1]; } else { $undefined_setting_key = $this->getKey(); } $label = '$' . 'conf' . '[\'' . $this->getArrayKey() . '\']'; $input = $plugin->getLang($this->errorMessage); return array($label, $input); } } Setting/SettingRegex.php000064400000002010152336352270011303 0ustar00local; if(!parent::update($input)) return false; $this->local = $local; // see if the regex compiles and runs (we don't check for effectiveness) $regex = $this->delimiter . $input . $this->delimiter . $this->pregflags; $lastError = error_get_last(); @preg_match($regex, 'testdata'); if(preg_last_error() != PREG_NO_ERROR || error_get_last() != $lastError) { $this->input = $input; $this->error = true; return false; } $this->local = $input; return true; } } Setting/SettingOnoff.php000064400000003157152336352300011307 0ustar00isProtected()) { $value = $this->protected; $disable = ' disabled="disabled"'; } else { $value = is_null($this->local) ? $this->default : $this->local; } $key = htmlspecialchars($this->key); $checked = ($value) ? ' checked="checked"' : ''; $label = ''; $input = '
'; return array($label, $input); } /** @inheritdoc */ public function update($input) { if($this->isProtected()) return false; $input = ($input) ? 1 : 0; $value = is_null($this->local) ? $this->default : $this->local; if($value == $input) return false; $this->local = $input; return true; } } Setting/SettingCompression.php000064400000001161152336352300012532 0ustar00choices[] = 'gz'; if(function_exists('bzopen')) $this->choices[] = 'bz2'; parent::initialize($default, $local, $protected); } } Setting/SettingArray.php000064400000005517152336352300011320 0ustar00isProtected()) return false; $input = $this->fromString($input); $value = is_null($this->local) ? $this->default : $this->local; if($value == $input) return false; foreach($input as $item) { if($this->pattern && !preg_match($this->pattern, $item)) { $this->error = true; $this->input = $input; return false; } } $this->local = $input; return true; } /** * Escaping * * @param string $string * @return string */ protected function escape($string) { $tr = array("\\" => '\\\\', "'" => '\\\''); return "'" . strtr(cleanText($string), $tr) . "'"; } /** @inheritdoc */ public function out($var, $fmt = 'php') { if($fmt != 'php') return ''; $vals = array_map(array($this, 'escape'), $this->local); $out = '$' . $var . "['" . $this->getArrayKey() . "'] = array(" . join(', ', $vals) . ");\n"; return $out; } /** @inheritdoc */ public function html(\admin_plugin_config $plugin, $echo = false) { $disable = ''; if($this->isProtected()) { $value = $this->protected; $disable = 'disabled="disabled"'; } else { if($echo && $this->error) { $value = $this->input; } else { $value = is_null($this->local) ? $this->default : $this->local; } } $key = htmlspecialchars($this->key); $value = htmlspecialchars($this->fromArray($value)); $label = ''; $input = ''; return array($label, $input); } } Setting/SettingSavedir.php000064400000001054152336352300011627 0ustar00isProtected()) return false; $value = is_null($this->local) ? $this->default : $this->local; if($value == $input) return false; if(!init_path($input)) { $this->error = true; $this->input = $input; return false; } $this->local = $input; return true; } } Setting/SettingEmail.php000064400000003055152336352300011264 0ustar00isProtected()) return false; $value = is_null($this->local) ? $this->default : $this->local; if($value == $input) return false; if($input === '') { $this->local = $input; return true; } $mail = $input; if($this->placeholders) { // replace variables with pseudo values $mail = str_replace('@USER@', 'joe', $mail); $mail = str_replace('@NAME@', 'Joe Schmoe', $mail); $mail = str_replace('@MAIL@', 'joe@example.com', $mail); } // multiple mail addresses? if($this->multiple) { $mails = array_filter(array_map('trim', explode(',', $mail))); } else { $mails = array($mail); } // check them all foreach($mails as $mail) { // only check the address part if(preg_match('#(.*?)<(.*?)>#', $mail, $matches)) { $addr = $matches[2]; } else { $addr = $mail; } if(!mail_isvalid($addr)) { $this->error = true; $this->input = $input; return false; } } $this->local = $input; return true; } } Setting/SettingAuthtype.php000064400000004034152336352300012036 0ustar00getList('auth') as $plugin) { $this->choices[] = $plugin; } parent::initialize($default, $local, $protected); } /** @inheritdoc */ public function update($input) { /** @var $plugin_controller \dokuwiki\Extension\PluginController */ global $plugin_controller; // is an update possible/requested? $local = $this->local; // save this, parent::update() may change it if(!parent::update($input)) return false; // nothing changed or an error caught by parent $this->local = $local; // restore original, more error checking to come // attempt to load the plugin $auth_plugin = $plugin_controller->load('auth', $input); // @TODO: throw an error in plugin controller instead of returning null if(is_null($auth_plugin)) { $this->error = true; msg('Cannot load Auth Plugin "' . $input . '"', -1); return false; } // verify proper instantiation (is this really a plugin?) @TODO use instanceof? implement interface? if(is_object($auth_plugin) && !method_exists($auth_plugin, 'getPluginName')) { $this->error = true; msg('Cannot create Auth Plugin "' . $input . '"', -1); return false; } // did we change the auth type? logout global $conf; if($conf['authtype'] != $input) { msg('Authentication system changed. Please re-login.'); auth_logoff(); } $this->local = $input; return true; } } Setting/SettingMulticheckbox.php000064400000013063152336352310013037 0ustar00isProtected()) return false; // split any combined values + convert from array to comma separated string $input = ($input) ? $input : array(); $input = $this->array2str($input); $value = is_null($this->local) ? $this->default : $this->local; if($value == $input) return false; if($this->pattern && !preg_match($this->pattern, $input)) { $this->error = true; $this->input = $input; return false; } $this->local = $input; return true; } /** @inheritdoc */ public function html(\admin_plugin_config $plugin, $echo = false) { $disable = ''; if($this->isProtected()) { $value = $this->protected; $disable = 'disabled="disabled"'; } else { if($echo && $this->error) { $value = $this->input; } else { $value = is_null($this->local) ? $this->default : $this->local; } } $key = htmlspecialchars($this->key); // convert from comma separated list into array + combine complimentary actions $value = $this->str2array($value); $default = $this->str2array($this->default); $input = ''; foreach($this->choices as $choice) { $idx = array_search($choice, $value); $idx_default = array_search($choice, $default); $checked = ($idx !== false) ? 'checked="checked"' : ''; // @todo ideally this would be handled using a second class of "default" $class = (($idx !== false) == (false !== $idx_default)) ? " selectiondefault" : ""; $prompt = ($plugin->getLang($this->key . '_' . $choice) ? $plugin->getLang($this->key . '_' . $choice) : htmlspecialchars($choice)); $input .= '
' . "\n"; $input .= '\n"; $input .= '\n"; $input .= "
\n"; // remove this action from the disabledactions array if($idx !== false) unset($value[$idx]); if($idx_default !== false) unset($default[$idx_default]); } // handle any remaining values if($this->other != 'never') { $other = join(',', $value); // test equivalent to ($this->_other == 'always' || ($other && $this->_other == 'exists') // use != 'exists' rather than == 'always' to ensure invalid values default to 'always' if($this->other != 'exists' || $other) { $class = ( (count($default) == count($value)) && (count($value) == count(array_intersect($value, $default))) ) ? " selectiondefault" : ""; $input .= '
' . "\n"; $input .= '\n"; $input .= '\n"; $input .= "
\n"; } } $label = ''; return array($label, $input); } /** * convert comma separated list to an array and combine any complimentary values * * @param string $str * @return array */ protected function str2array($str) { $array = explode(',', $str); if(!empty($this->combine)) { foreach($this->combine as $key => $combinators) { $idx = array(); foreach($combinators as $val) { if(($idx[] = array_search($val, $array)) === false) break; } if(count($idx) && $idx[count($idx) - 1] !== false) { foreach($idx as $i) unset($array[$i]); $array[] = $key; } } } return $array; } /** * convert array of values + other back to a comma separated list, incl. splitting any combined values * * @param array $input * @return string */ protected function array2str($input) { // handle other $other = trim($input['other']); $other = !empty($other) ? explode(',', str_replace(' ', '', $input['other'])) : array(); unset($input['other']); $array = array_unique(array_merge($input, $other)); // deconstruct any combinations if(!empty($this->combine)) { foreach($this->combine as $key => $combinators) { $idx = array_search($key, $array); if($idx !== false) { unset($array[$idx]); $array = array_merge($array, $combinators); } } } return join(',', array_unique($array)); } } Setting/SettingFieldset.php000064400000000466152336352310012000 0ustar00isProtected()) { $value = $this->protected; $disable = 'disabled="disabled"'; } else { if($echo && $this->error) { $value = $this->input; } else { $value = is_null($this->local) ? $this->default : $this->local; } } $key = htmlspecialchars($this->key); $value = htmlspecialchars($value); $label = ''; $input = ''; return array($label, $input); } } Setting/SettingRenderer.php000064400000003426152336352320012007 0ustar00 */ namespace dokuwiki\plugin\config\core\Setting; /** * Class setting_renderer */ class SettingRenderer extends SettingMultichoice { protected $prompts = array(); protected $format = null; /** @inheritdoc */ public function initialize($default = null, $local = null, $protected = null) { $format = $this->format; foreach(plugin_list('renderer') as $plugin) { $renderer = plugin_load('renderer', $plugin); if(method_exists($renderer, 'canRender') && $renderer->canRender($format)) { $this->choices[] = $plugin; $info = $renderer->getInfo(); $this->prompts[$plugin] = $info['name']; } } parent::initialize($default, $local, $protected); } /** @inheritdoc */ public function html(\admin_plugin_config $plugin, $echo = false) { // make some language adjustments (there must be a better way) // transfer some plugin names to the config plugin foreach($this->choices as $choice) { if(!$plugin->getLang($this->key . '_o_' . $choice)) { if(!isset($this->prompts[$choice])) { $plugin->addLang( $this->key . '_o_' . $choice, sprintf($plugin->getLang('renderer__core'), $choice) ); } else { $plugin->addLang( $this->key . '_o_' . $choice, sprintf($plugin->getLang('renderer__plugin'), $this->prompts[$choice]) ); } } } return parent::html($plugin, $echo); } } Setting/SettingSepchar.php000064400000000632152336352330011623 0ustar00choices[] = $str[$i]; // call foundation class constructor parent::__construct($key, $param); } } Setting/SettingNoKnownClass.php000064400000000527152336352330012620 0ustar00local) return false; $this->local = $input; return true; } return parent::update($input); } } Setting/SettingImConvert.php000064400000001135152336352340012144 0ustar00isProtected()) return false; $input = trim($input); $value = is_null($this->local) ? $this->default : $this->local; if($value == $input) return false; if($input && !file_exists($input)) { $this->error = true; $this->input = $input; return false; } $this->local = $input; return true; } } Setting/SettingHidden.php000064400000000310152336352340011423 0ustar00key = $key; if(is_array($params)) { foreach($params as $property => $value) { $property = trim($property, '_'); // we don't use underscores anymore $this->$property = $value; } } } /** * Set the current values for the setting $key * * This is used to initialize the setting with the data read form the config files. * * @see update() to set a new value * @param mixed $default default setting value * @param mixed $local local setting value * @param mixed $protected protected setting value */ public function initialize($default = null, $local = null, $protected = null) { $this->default = $this->cleanValue($default); $this->local = $this->cleanValue($local); $this->protected = $this->cleanValue($protected); } /** * update changed setting with validated user provided value $input * - if changed value fails validation check, save it to $this->input (to allow echoing later) * - if changed value passes validation check, set $this->local to the new value * * @param mixed $input the new value * @return boolean true if changed, false otherwise */ public function update($input) { if(is_null($input)) return false; if($this->isProtected()) return false; $input = $this->cleanValue($input); $value = is_null($this->local) ? $this->default : $this->local; if($value == $input) return false; // validate new value if($this->pattern && !preg_match($this->pattern, $input)) { $this->error = true; $this->input = $input; return false; } // update local copy of this setting with new value $this->local = $input; // setting ready for update return true; } /** * Clean a value read from a config before using it internally * * Default implementation returns $value as is. Subclasses can override. * Note: null should always be returned as null! * * This is applied in initialize() and update() * * @param mixed $value * @return mixed */ protected function cleanValue($value) { return $value; } /** * Should this type of config have a default? * * @return bool */ public function shouldHaveDefault() { return true; } /** * Get this setting's unique key * * @return string */ public function getKey() { return $this->key; } /** * Get the key of this setting marked up human readable * * @param bool $url link to dokuwiki.org manual? * @return string */ public function getPrettyKey($url = true) { $out = str_replace(Configuration::KEYMARKER, "»", $this->key); if($url && !strstr($out, '»')) {//provide no urls for plugins, etc. if($out == 'start') { // exception, because this config name is clashing with our actual start page return '' . $out . ''; } else { return '' . $out . ''; } } return $out; } /** * Returns setting key as an array key separator * * This is used to create form output * * @return string key */ public function getArrayKey() { return str_replace(Configuration::KEYMARKER, "']['", $this->key); } /** * What type of configuration is this * * Returns one of * * 'plugin' for plugin configuration * 'template' for template configuration * 'dokuwiki' for core configuration * * @return string */ public function getType() { if(substr($this->getKey(), 0, 10) == 'plugin' . Configuration::KEYMARKER) { return 'plugin'; } else if(substr($this->getKey(), 0, 7) == 'tpl' . Configuration::KEYMARKER) { return 'template'; } else { return 'dokuwiki'; } } /** * Build html for label and input of setting * * @param \admin_plugin_config $plugin object of config plugin * @param bool $echo true: show inputted value, when error occurred, otherwise the stored setting * @return string[] with content array(string $label_html, string $input_html) */ public function html(\admin_plugin_config $plugin, $echo = false) { $disable = ''; if($this->isProtected()) { $value = $this->protected; $disable = 'disabled="disabled"'; } else { if($echo && $this->error) { $value = $this->input; } else { $value = is_null($this->local) ? $this->default : $this->local; } } $key = htmlspecialchars($this->key); $value = formText($value); $label = ''; $input = ''; return array($label, $input); } /** * Should the current local value be saved? * * @see out() to run when this returns true * @return bool */ public function shouldBeSaved() { if($this->isProtected()) return false; if($this->local === null) return false; if($this->default == $this->local) return false; return true; } /** * Generate string to save local setting value to file according to $fmt * * @see shouldBeSaved() to check if this should be called * @param string $var name of variable * @param string $fmt save format * @return string */ public function out($var, $fmt = 'php') { if($fmt != 'php') return ''; $tr = array("\\" => '\\\\', "'" => '\\\''); // escape the value $out = '$' . $var . "['" . $this->getArrayKey() . "'] = '" . strtr(cleanText($this->local), $tr) . "';\n"; return $out; } /** * Returns the localized prompt * * @param \admin_plugin_config $plugin object of config plugin * @return string text */ public function prompt(\admin_plugin_config $plugin) { $prompt = $plugin->getLang($this->key); if(!$prompt) $prompt = htmlspecialchars(str_replace(array('____', '_'), ' ', $this->key)); return $prompt; } /** * Is setting protected * * @return bool */ public function isProtected() { return !is_null($this->protected); } /** * Is setting the default? * * @return bool */ public function isDefault() { return !$this->isProtected() && is_null($this->local); } /** * Has an error? * * @return bool */ public function hasError() { return $this->error; } /** * Returns caution * * @return false|string caution string, otherwise false for invalid caution */ public function caution() { if(empty($this->caution)) return false; if(!in_array($this->caution, Setting::$validCautions)) { throw new \RuntimeException( 'Invalid caution string (' . $this->caution . ') in metadata for setting "' . $this->key . '"' ); } return $this->caution; } } Setting/SettingNoDefault.php000064400000000550152336352350012120 0ustar00addLang($this->key . '_revisions', $lang['btn_revs']); foreach($this->choices as $choice) { if(isset($lang['btn_' . $choice])) $plugin->addLang($this->key . '_' . $choice, $lang['btn_' . $choice]); } return parent::html($plugin, $echo); } } Setting/SettingDirchoice.php000064400000001656152336352360012141 0ustar00_choices with a list of directories $list = array(); if($dh = @opendir($this->dir)) { while(false !== ($entry = readdir($dh))) { if($entry == '.' || $entry == '..') continue; if($this->pattern && !preg_match($this->pattern, $entry)) continue; $file = (is_link($this->dir . $entry)) ? readlink($this->dir . $entry) : $this->dir . $entry; if(is_dir($file)) $list[] = $entry; } closedir($dh); } sort($list); $this->choices = $list; parent::initialize($default, $local, $protected); } } Setting/SettingMultichoice.php000064400000004540152336352360012510 0ustar00isProtected()) { $value = $this->protected; $disable = ' disabled="disabled"'; } else { $value = is_null($this->local) ? $this->default : $this->local; } // ensure current value is included if(!in_array($value, $this->choices)) { $this->choices[] = $value; } // disable if no other choices if(!$this->isProtected() && count($this->choices) <= 1) { $disable = ' disabled="disabled"'; $nochoice = $plugin->getLang('nochoice'); } $key = htmlspecialchars($this->key); $label = ''; $input = "
\n"; $input .= ' $nochoice \n"; $input .= "
\n"; return array($label, $input); } /** @inheritdoc */ public function update($input) { if(is_null($input)) return false; if($this->isProtected()) return false; $value = is_null($this->local) ? $this->default : $this->local; if($value == $input) return false; if(!in_array($input, $this->choices)) return false; $this->local = $input; return true; } } Setting/SettingNumeric.php000064400000002444152336352370011647 0ustar00local; $valid = parent::update($input); if($valid && !(is_null($this->min) && is_null($this->max))) { $numeric_local = (int) eval('return ' . $this->local . ';'); if((!is_null($this->min) && $numeric_local < $this->min) || (!is_null($this->max) && $numeric_local > $this->max)) { $this->error = true; $this->input = $input; $this->local = $local; $valid = false; } } return $valid; } /** @inheritdoc */ public function out($var, $fmt = 'php') { if($fmt != 'php') return ''; $local = $this->local === '' ? "''" : $this->local; $out = '$' . $var . "['" . $this->getArrayKey() . "'] = " . $local . ";\n"; return $out; } } Setting/SettingPassword.php000064400000002170152336352370012043 0ustar00isProtected()) return false; if(!$input) return false; if($this->pattern && !preg_match($this->pattern, $input)) { $this->error = true; $this->input = $input; return false; } $this->local = conf_encodeString($input, $this->code); return true; } /** @inheritdoc */ public function html(\admin_plugin_config $plugin, $echo = false) { $disable = $this->isProtected() ? 'disabled="disabled"' : ''; $key = htmlspecialchars($this->key); $label = ''; $input = ''; return array($label, $input); } } Configuration.php000064400000014046152336352400010074 0ustar00 * @author Ben Coburn * @author Andreas Gohr */ class Configuration { const KEYMARKER = '____'; /** @var Setting[] metadata as array of Settings objects */ protected $settings = array(); /** @var Setting[] undefined and problematic settings */ protected $undefined = array(); /** @var array all metadata */ protected $metadata; /** @var array all default settings */ protected $default; /** @var array all local settings */ protected $local; /** @var array all protected settings */ protected $protected; /** @var bool have the settings been changed since loading from disk? */ protected $changed = false; /** @var Loader */ protected $loader; /** @var Writer */ protected $writer; /** * ConfigSettings constructor. */ public function __construct() { $this->loader = new Loader(new ConfigParser()); $this->writer = new Writer(); $this->metadata = $this->loader->loadMeta(); $this->default = $this->loader->loadDefaults(); $this->local = $this->loader->loadLocal(); $this->protected = $this->loader->loadProtected(); $this->initSettings(); } /** * Get all settings * * @return Setting[] */ public function getSettings() { return $this->settings; } /** * Get all unknown or problematic settings * * @return Setting[] */ public function getUndefined() { return $this->undefined; } /** * Have the settings been changed since loading from disk? * * @return bool */ public function hasChanged() { return $this->changed; } /** * Check if the config can be written * * @return bool */ public function isLocked() { return $this->writer->isLocked(); } /** * Update the settings using the data provided * * @param array $input as posted * @return bool true if all updates went through, false on errors */ public function updateSettings($input) { $ok = true; foreach($this->settings as $key => $obj) { $value = isset($input[$key]) ? $input[$key] : null; if($obj->update($value)) { $this->changed = true; } if($obj->hasError()) $ok = false; } return $ok; } /** * Save the settings * * This save the current state as defined in this object, including the * undefined settings * * @throws \Exception */ public function save() { // only save the undefined settings that have not been handled in settings $undefined = array_diff_key($this->undefined, $this->settings); $this->writer->save(array_merge($this->settings, $undefined)); } /** * Touch the settings * * @throws \Exception */ public function touch() { $this->writer->touch(); } /** * Load the extension language strings * * @return array */ public function getLangs() { return $this->loader->loadLangs(); } /** * Initalizes the $settings and $undefined properties */ protected function initSettings() { $keys = array_merge( array_keys($this->metadata), array_keys($this->default), array_keys($this->local), array_keys($this->protected) ); $keys = array_unique($keys); foreach($keys as $key) { $obj = $this->instantiateClass($key); if($obj->shouldHaveDefault() && !isset($this->default[$key])) { $this->undefined[$key] = new SettingNoDefault($key); } $d = isset($this->default[$key]) ? $this->default[$key] : null; $l = isset($this->local[$key]) ? $this->local[$key] : null; $p = isset($this->protected[$key]) ? $this->protected[$key] : null; $obj->initialize($d, $l, $p); } } /** * Instantiates the proper class for the given config key * * The class is added to the $settings or $undefined arrays and returned * * @param string $key * @return Setting */ protected function instantiateClass($key) { if(isset($this->metadata[$key])) { $param = $this->metadata[$key]; $class = $this->determineClassName(array_shift($param), $key); // first param is class $obj = new $class($key, $param); $this->settings[$key] = $obj; } else { $obj = new SettingUndefined($key); $this->undefined[$key] = $obj; } return $obj; } /** * Return the class to load * * @param string $class the class name as given in the meta file * @param string $key the settings key * @return string */ protected function determineClassName($class, $key) { // try namespaced class first if(is_string($class)) { $modern = str_replace('_', '', ucwords($class, '_')); $modern = '\\dokuwiki\\plugin\\config\\core\\Setting\\Setting' . $modern; if($modern && class_exists($modern)) return $modern; // try class as given if(class_exists($class)) return $class; // class wasn't found add to errors $this->undefined[$key] = new SettingNoKnownClass($key); } else { // no class given, add to errors $this->undefined[$key] = new SettingNoClass($key); } return '\\dokuwiki\\plugin\\config\\core\\Setting\\Setting'; } } ConfigParser.php000064400000005204152336352400007643 0ustar00 */ class ConfigParser { /** @var string variable to parse from the file */ protected $varname = 'conf'; /** @var string the key to mark sub arrays */ protected $keymarker = Configuration::KEYMARKER; /** * Parse the given PHP file into an array * * When the given files does not exist, this returns an empty array * * @param string $file * @return array */ public function parse($file) { if(!file_exists($file)) return array(); $config = array(); $contents = @php_strip_whitespace($file); $pattern = '/\$' . $this->varname . '\[[\'"]([^=]+)[\'"]\] ?= ?(.*?);(?=[^;]*(?:\$' . $this->varname . '|$))/s'; $matches = array(); preg_match_all($pattern, $contents, $matches, PREG_SET_ORDER); for($i = 0; $i < count($matches); $i++) { $value = $matches[$i][2]; // merge multi-dimensional array indices using the keymarker $key = preg_replace('/.\]\[./', $this->keymarker, $matches[$i][1]); // handle arrays if(preg_match('/^array ?\((.*)\)/', $value, $match)) { $arr = explode(',', $match[1]); // remove quotes from quoted strings & unescape escaped data $len = count($arr); for($j = 0; $j < $len; $j++) { $arr[$j] = trim($arr[$j]); $arr[$j] = $this->readValue($arr[$j]); } $value = $arr; } else { $value = $this->readValue($value); } $config[$key] = $value; } return $config; } /** * Convert php string into value * * @param string $value * @return bool|string */ protected function readValue($value) { $removequotes_pattern = '/^(\'|")(.*)(? '\\', '\\\'' => '\'', '\\"' => '"' ); if($value == 'true') { $value = true; } elseif($value == 'false') { $value = false; } else { // remove quotes from quoted strings & unescape escaped data $value = preg_replace($removequotes_pattern, '$2', $value); $value = strtr($value, $unescape_pairs); } return $value; } } Loader.php000064400000016023152336352410006471 0ustar00parser = $parser; $this->plugins = plugin_list(); $this->template = $conf['template']; // allow plugins to remove configurable plugins Event::createAndTrigger('PLUGIN_CONFIG_PLUGINLIST', $this->plugins); } /** * Read the settings meta data * * Reads the main file, plugins and template settings meta data * * @return array */ public function loadMeta() { // load main file $meta = array(); include DOKU_PLUGIN . 'config/settings/config.metadata.php'; // plugins foreach($this->plugins as $plugin) { $meta = array_merge( $meta, $this->loadExtensionMeta( DOKU_PLUGIN . $plugin . '/conf/metadata.php', 'plugin', $plugin ) ); } // current template $meta = array_merge( $meta, $this->loadExtensionMeta( tpl_incdir() . '/conf/metadata.php', 'tpl', $this->template ) ); return $meta; } /** * Read the default values * * Reads the main file, plugins and template defaults * * @return array */ public function loadDefaults() { // load main files global $config_cascade; $conf = $this->loadConfigs($config_cascade['main']['default']); // plugins foreach($this->plugins as $plugin) { $conf = array_merge( $conf, $this->loadExtensionConf( DOKU_PLUGIN . $plugin . '/conf/default.php', 'plugin', $plugin ) ); } // current template $conf = array_merge( $conf, $this->loadExtensionConf( tpl_incdir() . '/conf/default.php', 'tpl', $this->template ) ); return $conf; } /** * Reads the language strings * * Only reads extensions, main one is loaded the usual way * * @return array */ public function loadLangs() { $lang = array(); // plugins foreach($this->plugins as $plugin) { $lang = array_merge( $lang, $this->loadExtensionLang( DOKU_PLUGIN . $plugin . '/', 'plugin', $plugin ) ); } // current template $lang = array_merge( $lang, $this->loadExtensionLang( tpl_incdir() . '/', 'tpl', $this->template ) ); return $lang; } /** * Read the local settings * * @return array */ public function loadLocal() { global $config_cascade; return $this->loadConfigs($config_cascade['main']['local']); } /** * Read the protected settings * * @return array */ public function loadProtected() { global $config_cascade; return $this->loadConfigs($config_cascade['main']['protected']); } /** * Read the config values from the given files * * @param string[] $files paths to config php's * @return array */ protected function loadConfigs($files) { $conf = array(); foreach($files as $file) { $conf = array_merge($conf, $this->parser->parse($file)); } return $conf; } /** * Read settings file from an extension * * This is used to read the settings.php files of plugins and templates * * @param string $file php file to read * @param string $type should be 'plugin' or 'tpl' * @param string $extname name of the extension * @return array */ protected function loadExtensionMeta($file, $type, $extname) { if(!file_exists($file)) return array(); $prefix = $type . Configuration::KEYMARKER . $extname . Configuration::KEYMARKER; // include file $meta = array(); include $file; if(empty($meta)) return array(); // read data $data = array(); $data[$prefix . $type . '_settings_name'] = ['fieldset']; foreach($meta as $key => $value) { if($value[0] == 'fieldset') continue; //plugins only get one fieldset $data[$prefix . $key] = $value; } return $data; } /** * Read a default file from an extension * * This is used to read the default.php files of plugins and templates * * @param string $file php file to read * @param string $type should be 'plugin' or 'tpl' * @param string $extname name of the extension * @return array */ protected function loadExtensionConf($file, $type, $extname) { if(!file_exists($file)) return array(); $prefix = $type . Configuration::KEYMARKER . $extname . Configuration::KEYMARKER; // parse file $conf = $this->parser->parse($file); if(empty($conf)) return array(); // read data $data = array(); foreach($conf as $key => $value) { $data[$prefix . $key] = $value; } return $data; } /** * Read the language file of an extension * * @param string $dir directory of the extension * @param string $type should be 'plugin' or 'tpl' * @param string $extname name of the extension * @return array */ protected function loadExtensionLang($dir, $type, $extname) { global $conf; $ll = $conf['lang']; $prefix = $type . Configuration::KEYMARKER . $extname . Configuration::KEYMARKER; // include files $lang = array(); if(file_exists($dir . 'lang/en/settings.php')) { include $dir . 'lang/en/settings.php'; } if($ll != 'en' && file_exists($dir . 'lang/' . $ll . '/settings.php')) { include $dir . 'lang/' . $ll . '/settings.php'; } // set up correct keys $strings = array(); foreach($lang as $key => $val) { $strings[$prefix . $key] = $val; } // add fieldset key $strings[$prefix . $type . '_settings_name'] = ucwords(str_replace('_', ' ', $extname)); return $strings; } } Writer.php000064400000006503152336352410006541 0ustar00savefile = end($config_cascade['main']['local']); } /** * Save the given settings * * @param Setting[] $settings * @throws \Exception */ public function save($settings) { global $conf; if($this->isLocked()) throw new \Exception('no save'); // backup current file (remove any existing backup) if(file_exists($this->savefile)) { if(file_exists($this->savefile . '.bak.php')) @unlink($this->savefile . '.bak.php'); if(!io_rename($this->savefile, $this->savefile . '.bak.php')) throw new \Exception('no backup'); } if(!$fh = @fopen($this->savefile, 'wb')) { io_rename($this->savefile . '.bak.php', $this->savefile); // problem opening, restore the backup throw new \Exception('no save'); } $out = $this->getHeader(); foreach($settings as $setting) { if($setting->shouldBeSaved()) { $out .= $setting->out('conf', 'php'); } } fwrite($fh, $out); fclose($fh); if($conf['fperm']) chmod($this->savefile, $conf['fperm']); $this->opcacheUpdate($this->savefile); } /** * Update last modified time stamp of the config file * * Will invalidate all DokuWiki caches * * @throws \Exception when the config isn't writable */ public function touch() { if($this->isLocked()) throw new \Exception('no save'); @touch($this->savefile); $this->opcacheUpdate($this->savefile); } /** * Invalidate the opcache of the given file * * @todo this should probably be moved to core * @param string $file */ protected function opcacheUpdate($file) { if(!function_exists('opcache_invalidate')) return; opcache_invalidate($file); } /** * Configuration is considered locked if there is no local settings filename * or the directory its in is not writable or the file exists and is not writable * * @return bool true: locked, false: writable */ public function isLocked() { if(!$this->savefile) return true; if(!is_writable(dirname($this->savefile))) return true; if(file_exists($this->savefile) && !is_writable($this->savefile)) return true; return false; } /** * Returns the PHP intro header for the config file * * @return string */ protected function getHeader() { return join( "\n", array( 'header, ' * Auto-generated by config plugin', ' * Run for user: ' . $_SERVER['REMOTE_USER'], ' * Date: ' . date('r'), ' */', '', '' ) ); } }