diff --git a/tags-standalone.min.js b/tags-standalone.min.js index 4f09213..173bf7d 100644 --- a/tags-standalone.min.js +++ b/tags-standalone.min.js @@ -1,2 +1,2 @@ -function q(n){return n instanceof Element}function U(n,e){let t=e&&q(e)?e:document;return q(n)?n:t.querySelector(n)}function E(n,e){return U(n,e)}var xe="addEventListener",j=xe;var Ae="removeEventListener",N=Ae;var Le=(()=>{let n=!1;try{let e=Object.defineProperty({},"passive",{get(){return n=!0,n}});document[j]("DOMContentLoaded",function t(){document[N]("DOMContentLoaded",t,e)},e)}catch(e){throw Error("Passive events are not supported")}return n})(),ce=Le;var Ce=ce?{passive:!0}:!1,K=Ce;function S(n,e){n.classList.add(e)}function x(n,e){return n.classList.contains(e)}function p(n,e){n.classList.remove(e)}var je="aria-expanded",_=je;var Ne="show",m=Ne;var Te="data-bs-toggle",J=Te;var Ie=["dropdown","dropup","dropstart","dropend"],g=Ie;var De="dropdown-menu",Q=De;function L(n,e){let t=new CustomEvent(n,{cancelable:!0});return e instanceof Object&&Object.keys(e).forEach(s=>{Object.defineProperty(t,s,{value:e[s]})}),t}function O(n){let e=n.closest("A");return n&&(n.hasAttribute("href")&&n.href.slice(-1)==="#"||e&&e.hasAttribute("href")&&e.href.slice(-1)==="#")}function T(n){n.focus()}function k(n){return n==="true"?!0:n==="false"?!1:Number.isNaN(+n)?n===""||n==="null"?null:n:+n}var qe=n=>Object.keys(n),P=qe;function Y(n,e,t,s){let r={...n.dataset},i={},l={};return P(r).forEach(o=>{let d=s&&o.includes(s)?o.replace(s,"").replace(/[A-Z]/,h=>h.toLowerCase()):o;l[d]=k(r[o])}),P(t).forEach(o=>{t[o]=k(t[o])}),P(e).forEach(o=>{o in t?i[o]=t[o]:o in l?i[o]=l[o]:i[o]=e[o]}),i}var V=class{constructor(e,t,s,r){let i=this,l=E(t);l[e]&&l[e].dispose(),i.element=l,s&&Object.keys(s).length&&(i.options=Y(l,s,r||{},"bs")),l[e]=i}dispose(e){let t=this;t.element[e]=null,Object.keys(t).forEach(s=>{t[s]=null})}};var[u]=g,v="Dropdown",Z=`[${J}="${u}"]`,I=g[1],H=g[2],M=g[3],A=`${Q}-end`,he=["d-block","invisible"],Oe=[u,I],ue=[H,M],ke={offset:5,display:"dynamic"},G=L(`show.bs.${u}`),fe=L(`shown.bs.${u}`),X=L(`hide.bs.${u}`),pe=L(`hidden.bs.${u}`);function ee(n,e){let{element:t,menu:s,originalClass:r,menuEnd:i,options:l}=n,{offset:o}=l,d=t.parentElement;if(["margin","top","bottom","left","right"].forEach(c=>{s.style[c]=""}),p(d,"position-static"),!e){let c=x(s,A);d.className=r.join(" "),c&&!i?p(s,A):!c&&i&&S(s,A);return}let a=g.find(c=>r.includes(c))||u,f={dropdown:[o,0,0],dropup:[0,0,o],dropstart:[-1,o,0],dropend:[-1,0,0,o]},D={dropdown:{top:"100%"},dropup:{top:"auto",bottom:"100%"},dropstart:{left:"auto",right:"100%"},dropend:{left:"100%",right:"auto"},menuEnd:{right:0,left:"auto"}};he.forEach(c=>S(s,c));let we=new RegExp(`\\b(${u}|${I}|${H}|${M})+`),z={w:t.offsetWidth,h:t.offsetHeight},y={w:s.offsetWidth,h:s.offsetHeight},se=document.documentElement,ie=document.body,ne=se.clientWidth||ie.clientWidth,re=se.clientHeight||ie.clientHeight,w=t.getBoundingClientRect(),Ee=w.left+z.w-y.w<0,oe=w.left-y.w<0,Se=w.left+y.w>=ne,le=w.left+y.w+z.w>=ne,W=w.top+y.h>=re,ae=w.top+y.h+z.h>=re,de=w.top-y.h<0;ue.includes(a)&&oe&&le&&(a=u),ue.includes(a)&&W&&(a=I),a===H&&oe&&!W&&(a=M),a===M&&le&&!W&&(a=H),a===I&&de&&!ae&&(a=u),a===u&&ae&&!de&&(a=I),f=f[a],s.style.margin=`${f.map(c=>c&&`${c}px`).join(" ")}`,Object.keys(D[a]).forEach(c=>{s.style[c]=D[a][c]}),x(d,a)||(d.className=d.className.replace(we,a)),Oe.includes(a)&&(!i&&Se?S(s,A):i&&Ee&&p(s,A),x(s,A)&&Object.keys(D.menuEnd).forEach(c=>{s.style[c]=D.menuEnd[c]})),he.forEach(c=>p(s,c))}function me(n){let e=n.open?j:N;document[e]("click",ve),document[e]("focus",ve),document[e]("keydown",Ve),document[e]("keyup",$e),n.options.display==="dynamic"&&(window[e]("scroll",be,K),window[e]("resize",be,K))}function ge(n,e){let t=e?j:N;n.element[t]("click",Pe)}function te(){let n=g.concat("btn-group").map(e=>document.getElementsByClassName(`${e} ${m}`)).find(e=>e.length);return n&&n.length?Array.from(n[0].children).find(e=>e.hasAttribute(J)):null}function ve(n){let{target:e,type:t}=n;if(!e.closest)return;let s=te(),r=s&&s.parentNode,i=s&&s[v],l=i&&i.menu,o=e.closest(Z)!==null,d=r&&r.contains(e)&&(e.tagName==="form"||e.closest("form")!==null);t==="click"&&O(e)&&n.preventDefault(),!(t==="focus"&&(e===s||e===l||l.contains(e)))&&(d||o||i&&i.hide(s))}function Pe(n){let e=this;e[v].toggle(e),O(n.target)&&n.preventDefault()}function Ve(n){(n.which===38||n.which===40)&&n.preventDefault()}function $e({which:n}){let e=te(),t=e[v],{menu:s,menuItems:r,open:i}=t,l=document.activeElement,o=l===e,d=s.contains(l),h=l.parentNode===s||l.parentNode.parentNode===s,a=r.indexOf(l);h&&(o?a=0:n===38?a=a>1?a-1:0:n===40&&(a=a{o.children.length&&o.children[0].tagName==="A"&&s.menuItems.push(o.children[0]),o.tagName==="A"&&s.menuItems.push(o)}),s.open=!1,ge(s,1)}toggle(e){let t=this,{open:s}=t;s?t.hide(e):t.show(e)}show(e){let t=this,s=E(g.concat("btn-group").map(h=>`.${h}.${m}`).join(",")),r=s&&E(Z,s);r&&r[v].hide();let{element:i,menu:l,open:o}=t,d=i.parentNode;G.relatedTarget=e||null,d.dispatchEvent(G),!G.defaultPrevented&&(ee(t,1),S(l,m),S(d,m),i.setAttribute(_,!0),t.open=!o,setTimeout(()=>{T(l.getElementsByTagName("INPUT")[0]||i),me(t),fe.relatedTarget=e||null,d.dispatchEvent(fe)},1))}hide(e){let t=this,{element:s,menu:r,open:i}=t,l=s.parentNode;X.relatedTarget=e||null,l.dispatchEvent(X),!X.defaultPrevented&&(p(r,m),p(l,m),ee(t),s.setAttribute(_,!1),t.open=!i,T(s),setTimeout(()=>me(t),1),pe.relatedTarget=e||null,l.dispatchEvent(pe))}dispose(){let e=this,{element:t}=e;x(t.parentNode,m)&&e.open&&e.hide(),ge(e),super.dispose(v)}};F.init={component:v,selector:Z,constructor:F};var He="is-active",b=["is-active","bg-primary","text-white"],C="data-value",B=new WeakMap,R=class{#a;#t;#i;#n;#s;#e;#o;#r;constructor(e,t={}){e.style.display="none",e.dataset.tags=!0,this.#t=e;let s=i=>["true","false","1","0",!0,!1].includes(i)&&!!JSON.parse(i),r={...t,...e.dataset};for(this.allowNew=r.allowNew?s(r.allowNew):!1,this.showAllSuggestions=r.showAllSuggestions?s(r.showAllSuggestions):!1,this.badgeStyle=r.badgeStyle||"primary",this.allowClear=r.allowClear?s(r.allowClear):!1,this.server=r.server||!1,this.liveServer=r.liveServer?s(r.liveServer):!1,this.serverParams=r.serverParams||{},typeof this.serverParams=="string"&&(this.serverParams=JSON.parse(this.serverParams)),this.suggestionsThreshold=typeof r.suggestionsThreshold!="undefined"?parseInt(r.suggestionsThreshold):1,this.validationRegex=r.regex||"",this.separator=r.separator?r.separator.split("|"):[],this.max=r.max?parseInt(r.max):null,this.clearLabel=r.clearLabel||"Clear",this.searchLabel=r.searchLabel||"Type a value",this.placeholder=this.#m(),this.#o=!1,this.#r=!0,this.parentForm=e.parentElement;this.parentForm&&(this.parentForm=this.parentForm.parentElement,this.parentForm.nodeName!="FORM"););this.reset=this.reset.bind(this),this.parentForm.addEventListener("reset",this.reset),this.#i=document.createElement("div"),this.#n=document.createElement("div"),this.#s=document.createElement("ul"),this.#e=document.createElement("input"),this.#i.appendChild(this.#n),this.#n.appendChild(this.#e),this.#i.appendChild(this.#s),this.#t.parentNode.insertBefore(this.#i,this.#t.nextSibling),this.#v(),this.#g(),this.#b(),this.#y(),this.resetState(),this.server&&!this.liveServer?this.#u():this.resetSuggestions()}static init(e="select[multiple]",t={}){let s=document.querySelectorAll(e),r;for(let i=0;i!t.disabled).map(t=>({value:t.getAttribute("value"),label:t.innerText}));this.#f(e)}#u(e=!1){this.#a&&this.#a.abort(),this.#a=new AbortController,this.serverParams.query=this.#e.value;let t=new URLSearchParams(this.serverParams).toString();fetch(this.server+"?"+t,{signal:this.#a.signal}).then(s=>s.json()).then(s=>{let r=s.data||s;this.#f(r),this.#a=null,e&&this.#h()}).catch(s=>{s.name!=="AbortError"&&console.error(s)})}#m(){if(this.#t.hasAttribute("placeholder"))return this.#t.getAttribute("placeholder");if(this.#t.dataset.placeholder)return this.#t.dataset.placeholder;let e=this.#t.querySelector("option");return e?(e.hasAttribute("selected")&&e.removeAttribute("selected"),e.value?"":e.innerText):""}#g(){this.#s.classList.add("dropdown-menu","p-0"),this.#s.style.maxHeight="280px",this.#s.style.overflowY="auto",this.#s.addEventListener("mouseenter",e=>{this.#o=!1})}#v(){this.#i.classList.add("form-control","dropdown"),this.#p()===4&&(this.#i.style.height="auto")}#b(){this.#n.addEventListener("click",t=>{this.isDisabled()||this.#e.style.visibility!="hidden"&&this.#e.focus()});let e=this.#t.selectedOptions;for(let t=0;t{if(e.data){let t=e.data.slice(-1);if(this.separator.length&&this.#e.value&&this.separator.includes(t)){let s=this.#e.value.slice(0,-1);if(!this.canAdd(s))return;this.addItem(s,null),this.#c();return}}this.#l(),this.#e.value.length>=this.suggestionsThreshold?this.liveServer?this.#u(!0):this.#h():this.#d()}),this.#e.addEventListener("focus",e=>{this.#e.value.length>=this.suggestionsThreshold&&this.#h()}),this.#e.addEventListener("focusout",e=>{this.#d()}),this.#e.addEventListener("keydown",e=>{switch(e.keyCode||e.key){case 13:case"Enter":e.preventDefault();let s=this.getActiveSelection();if(s)s.click();else if(this.allowNew&&!this.#S(this.#e.value)&&this.#e.value){let i=this.#e.value;if(!this.canAdd(i))return;this.addItem(i,null),this.#c()}break;case 38:case"ArrowUp":e.preventDefault(),this.#o=!0;let r=this.#w();this.#e.value.length==0&&this.#s.classList.contains("show")&&!r&&this.#d();break;case 40:case"ArrowDown":e.preventDefault(),this.#o=!0,this.#E(),this.#e.value.length==0&&!this.#s.classList.contains("show")&&this.#h();break;case 8:case"Backspace":this.#e.value.length==0&&(this.removeLastItem(),this.#l(),this.#d());break}})}#w(){let e=this.getActiveSelection();if(e){let t=e.parentNode;do t=t.previousSibling;while(t&&t.style.display=="none");return t?(e.classList.remove(...b),t.querySelector("a").classList.add(...b),t.parentNode.scrollTop=t.offsetTop-t.parentNode.offsetTop,t):null}return null}#E(){let e=this.getActiveSelection(),t=null;if(e){t=e.parentNode;do t=t.nextSibling;while(t&&t.style.display=="none");return t?(e.classList.remove(...b),t.querySelector("a").classList.add(...b),t.offsetTop>t.parentNode.offsetHeight-t.offsetHeight&&(t.parentNode.scrollTop+=t.offsetHeight),t):null}return t}#l(){this.#e.value?this.#e.size=this.#e.value.length+1:this.getSelectedValues().length?(this.#e.placeholder="",this.#e.size=1):(this.#e.size=this.placeholder.length>0?this.placeholder.length:1,this.#e.placeholder=this.placeholder)}#f(e=null){for(;this.#s.lastChild;)this.#s.removeChild(this.#s.lastChild);for(let t=0;t{this.#o||(this.removeActiveSelection(),r.querySelector("a").classList.add(...b))}),i.addEventListener("mousemove",l=>{this.#o=!1}),i.addEventListener("mousedown",l=>{l.preventDefault()}),i.addEventListener("click",l=>{l.preventDefault();let o=i.innerText;!this.canAdd(o)||(this.addItem(o,i.getAttribute(C),i.dataset),this.#c())})}}reset(){this.removeAll(),this.#r=!1;let e=this.#t.querySelectorAll("option[data-init]");for(let t=0;tt.value)}#h(){if(this.#e.style.visibility=="hidden")return;this.#s.style.left=this.#e.offsetLeft+"px";let e=this.#e.value.toLocaleLowerCase(),t=this.getSelectedValues(),s=this.#s.querySelectorAll("li"),r=!1,i=null,l=!1;for(let o=0;os.textContent==e);return!!(t&&t.getAttribute("selected"))}#x(e){return new RegExp(this.validationRegex.trim()).test(e)}getActiveSelection(){return this.#s.querySelector("a."+He)}removeActiveSelection(){let e=this.getActiveSelection();e&&e.classList.remove(...b)}removeAll(){this.getSelectedValues().forEach(t=>{this.removeItem(t)}),this.#l()}removeLastItem(e){e&&(this.#r=!1);let t=this.#n.querySelectorAll("span");if(!t.length)return;let s=t[t.length-1];this.removeItem(s.getAttribute(C)),this.#r=!0}isDisabled(){return this.#t.hasAttribute("disabled")||this.#t.disabled||this.#t.hasAttribute("readonly")}isInvalid(){return this.#i.classList.contains("is-invalid")}isSingle(){return!this.#t.hasAttribute("multiple")}canAdd(e){return!e||this.max&&this.getSelectedValues().length>=this.max?!1:this.validationRegex&&!this.#x(e)?(this.#i.classList.add("is-invalid"),!1):!0}addItem(e,t=null,s={}){t||(t=e),this.isSingle()&&this.getSelectedValues().length&&this.removeLastItem(!0);let r=this.#p(),i=this.#t.querySelector('option[value="'+t+'"]');i&&(s=i.dataset);let l=e,o=document.createElement("span"),d=["badge"],h=this.badgeStyle;if(s.badgeStyle&&(h=s.badgeStyle),s.badgeClass&&d.push(s.badgeClass),r===5?d=[...d,"me-2","bg-"+h]:d=[...d,"mr-2","badge-"+h],o.classList.add(...d),o.setAttribute(C,t),this.allowClear&&(l=(r===5?'':'')+l),o.innerHTML=l,this.#n.insertBefore(o,this.#e),this.allowClear&&o.querySelector("button").addEventListener("click",a=>{a.preventDefault(),a.stopPropagation(),this.isDisabled()||(this.removeItem(t),document.activeElement.blur(),this.#l())}),!i){i=document.createElement("option"),i.value=t,i.innerText=e;for(let[a,f]of Object.entries(s))i.dataset[a]=f;this.#t.appendChild(i)}i.setAttribute("selected","selected"),i.selected=!0,this.#r&&this.#t.dispatchEvent(new Event("change",{bubbles:!0}))}removeItem(e){let t=this.#n.querySelector("span["+C+'="'+e+'"]');if(!t)return;t.remove();let s=this.#t.querySelector('option[value="'+e+'"]');s&&(s.removeAttribute("selected"),s.selected=!1,this.#r&&this.#t.dispatchEvent(new Event("change",{bubbles:!0}))),this.#e.style.visibility=="hidden"&&this.max&&this.getSelectedValues().length{let n=!1;try{let e=Object.defineProperty({},"passive",{get(){return n=!0,n}});document[N]("DOMContentLoaded",function t(){document[I]("DOMContentLoaded",t,e)},e)}catch{throw Error("Passive events are not supported")}return n})(),de=Ce;var Le=de?{passive:!0}:!1,K=Le;function S(n,e){n.classList.add(e)}function A(n,e){return n.classList.contains(e)}function p(n,e){n.classList.remove(e)}var Ne="aria-expanded",J=Ne;var Ie="show",m=Ie;var De="data-bs-toggle",_=De;var Te=["dropdown","dropup","dropstart","dropend"],g=Te;var ke="dropdown-menu",Q=ke;function L(n,e){let t=new CustomEvent(n,{cancelable:!0});return e instanceof Object&&Object.keys(e).forEach(s=>{Object.defineProperty(t,s,{value:e[s]})}),t}function P(n){let e=n.closest("A");return n&&(n.hasAttribute("href")&&n.href.slice(-1)==="#"||e&&e.hasAttribute("href")&&e.href.slice(-1)==="#")}function D(n){n.focus()}function j(n){return n==="true"?!0:n==="false"?!1:Number.isNaN(+n)?n===""||n==="null"?null:n:+n}var Oe=n=>Object.keys(n),V=Oe;function Y(n,e,t,s){let o={...n.dataset},i={},l={};return V(o).forEach(r=>{let h=s&&r.includes(s)?r.replace(s,"").replace(/[A-Z]/,c=>c.toLowerCase()):r;l[h]=j(o[r])}),V(t).forEach(r=>{t[r]=j(t[r])}),V(e).forEach(r=>{r in t?i[r]=t[r]:r in l?i[r]=l[r]:i[r]=e[r]}),i}var H=class{constructor(e,t,s,o){let i=this,l=E(t);l[e]&&l[e].dispose(),i.element=l,s&&Object.keys(s).length&&(i.options=Y(l,s,o||{},"bs")),l[e]=i}dispose(e){let t=this;t.element[e]=null,Object.keys(t).forEach(s=>{t[s]=null})}};var[u]=g,v="Dropdown",Z=`[${_}="${u}"]`,T=g[1],F=g[2],M=g[3],x=`${Q}-end`,ce=["d-block","invisible"],qe=[u,T],ue=[F,M],Pe={offset:5,display:"dynamic"},G=L(`show.bs.${u}`),fe=L(`shown.bs.${u}`),X=L(`hide.bs.${u}`),pe=L(`hidden.bs.${u}`);function ee(n,e){let{element:t,menu:s,originalClass:o,menuEnd:i,options:l}=n,{offset:r}=l,h=t.parentElement;if(["margin","top","bottom","left","right"].forEach(d=>{s.style[d]=""}),p(h,"position-static"),!e){let d=A(s,x);h.className=o.join(" "),d&&!i?p(s,x):!d&&i&&S(s,x);return}let a=g.find(d=>o.includes(d))||u,f={dropdown:[r,0,0],dropup:[0,0,r],dropstart:[-1,r,0],dropend:[-1,0,0,r]},O={dropdown:{top:"100%"},dropup:{top:"auto",bottom:"100%"},dropstart:{left:"auto",right:"100%"},dropend:{left:"100%",right:"auto"},menuEnd:{right:0,left:"auto"}};ce.forEach(d=>S(s,d));let we=new RegExp(`\\b(${u}|${T}|${F}|${M})+`),z={w:t.offsetWidth,h:t.offsetHeight},y={w:s.offsetWidth,h:s.offsetHeight},se=document.documentElement,ie=document.body,ne=se.clientWidth||ie.clientWidth,oe=se.clientHeight||ie.clientHeight,w=t.getBoundingClientRect(),Ee=w.left+z.w-y.w<0,re=w.left-y.w<0,Se=w.left+y.w>=ne,le=w.left+y.w+z.w>=ne,W=w.top+y.h>=oe,ae=w.top+y.h+z.h>=oe,he=w.top-y.h<0;ue.includes(a)&&re&&le&&(a=u),ue.includes(a)&&W&&(a=T),a===F&&re&&!W&&(a=M),a===M&&le&&!W&&(a=F),a===T&&he&&!ae&&(a=u),a===u&&ae&&!he&&(a=T),f=f[a],s.style.margin=`${f.map(d=>d&&`${d}px`).join(" ")}`,Object.keys(O[a]).forEach(d=>{s.style[d]=O[a][d]}),A(h,a)||(h.className=h.className.replace(we,a)),qe.includes(a)&&(!i&&Se?S(s,x):i&&Ee&&p(s,x),A(s,x)&&Object.keys(O.menuEnd).forEach(d=>{s.style[d]=O.menuEnd[d]})),ce.forEach(d=>p(s,d))}function me(n){let e=n.open?N:I;document[e]("click",ve),document[e]("focus",ve),document[e]("keydown",$e),document[e]("keyup",Ve),n.options.display==="dynamic"&&(window[e]("scroll",be,K),window[e]("resize",be,K))}function ge(n,e){let t=e?N:I;n.element[t]("click",je)}function te(){let n=g.concat("btn-group").map(e=>document.getElementsByClassName(`${e} ${m}`)).find(e=>e.length);return n&&n.length?Array.from(n[0].children).find(e=>e.hasAttribute(_)):null}function ve(n){let{target:e,type:t}=n;if(!e.closest)return;let s=te(),o=s&&s.parentNode,i=s&&s[v],l=i&&i.menu,r=e.closest(Z)!==null,h=o&&o.contains(e)&&(e.tagName==="form"||e.closest("form")!==null);t==="click"&&P(e)&&n.preventDefault(),!(t==="focus"&&(e===s||e===l||l.contains(e)))&&(h||r||i&&i.hide(s))}function je(n){let e=this;e[v].toggle(e),P(n.target)&&n.preventDefault()}function $e(n){(n.which===38||n.which===40)&&n.preventDefault()}function Ve({which:n}){let e=te(),t=e[v],{menu:s,menuItems:o,open:i}=t,l=document.activeElement,r=l===e,h=s.contains(l),c=l.parentNode===s||l.parentNode.parentNode===s,a=o.indexOf(l);c&&(r?a=0:n===38?a=a>1?a-1:0:n===40&&(a=a{r.children.length&&r.children[0].tagName==="A"&&s.menuItems.push(r.children[0]),r.tagName==="A"&&s.menuItems.push(r)}),s.open=!1,ge(s,1)}toggle(e){let t=this,{open:s}=t;s?t.hide(e):t.show(e)}show(e){let t=this,s=E(g.concat("btn-group").map(c=>`.${c}.${m}`).join(",")),o=s&&E(Z,s);o&&o[v].hide();let{element:i,menu:l,open:r}=t,h=i.parentNode;G.relatedTarget=e||null,h.dispatchEvent(G),!G.defaultPrevented&&(ee(t,1),S(l,m),S(h,m),i.setAttribute(J,!0),t.open=!r,setTimeout(()=>{D(l.getElementsByTagName("INPUT")[0]||i),me(t),fe.relatedTarget=e||null,h.dispatchEvent(fe)},1))}hide(e){let t=this,{element:s,menu:o,open:i}=t,l=s.parentNode;X.relatedTarget=e||null,l.dispatchEvent(X),!X.defaultPrevented&&(p(o,m),p(l,m),ee(t),s.setAttribute(J,!1),t.open=!i,D(s),setTimeout(()=>me(t),1),pe.relatedTarget=e||null,l.dispatchEvent(pe))}dispose(){let e=this,{element:t}=e;A(t.parentNode,m)&&e.open&&e.hide(),ge(e),super.dispose(v)}};B.init={component:v,selector:Z,constructor:B};var He="is-active",b=["is-active","bg-primary","text-white"],C="data-value",R=new WeakMap,k=class{#h;#t;#i;#n;#s;#e;#r;#o;constructor(e,t={}){e.style.display="none",R.set(e,this),this.#t=e;let s=i=>["true","false","1","0",!0,!1].includes(i)&&!!JSON.parse(i),o={...t,...e.dataset};for(this.allowNew=o.allowNew?s(o.allowNew):!1,this.showAllSuggestions=o.showAllSuggestions?s(o.showAllSuggestions):!1,this.badgeStyle=o.badgeStyle||"primary",this.allowClear=o.allowClear?s(o.allowClear):!1,this.server=o.server||!1,this.liveServer=o.liveServer?s(o.liveServer):!1,this.serverParams=o.serverParams||{},typeof this.serverParams=="string"&&(this.serverParams=JSON.parse(this.serverParams)),this.suggestionsThreshold=typeof o.suggestionsThreshold!="undefined"?parseInt(o.suggestionsThreshold):1,this.validationRegex=o.regex||"",this.separator=o.separator?o.separator.split("|"):[],this.max=o.max?parseInt(o.max):null,this.clearLabel=o.clearLabel||"Clear",this.searchLabel=o.searchLabel||"Type a value",this.placeholder=this.#m(),this.#r=!1,this.#o=!0,this.parentForm=e.parentElement;this.parentForm&&(this.parentForm=this.parentForm.parentElement,!(this.parentForm&&this.parentForm.nodeName=="FORM")););this.reset=this.reset.bind(this),this.parentForm&&this.parentForm.addEventListener("reset",this.reset),this.#i=document.createElement("div"),this.#n=document.createElement("div"),this.#s=document.createElement("ul"),this.#e=document.createElement("input"),this.#i.appendChild(this.#n),this.#n.appendChild(this.#e),this.#i.appendChild(this.#s),this.#t.parentNode.insertBefore(this.#i,this.#t.nextSibling),this.#v(),this.#g(),this.#b(),this.#y(),this.resetState(),this.server&&!this.liveServer?this.#u():this.resetSuggestions()}static init(e="select[multiple]",t={}){let s=document.querySelectorAll(e);for(let o=0;o!t.disabled).map(t=>({value:t.getAttribute("value"),label:t.textContent}));this.#f(e)}#u(e=!1){this.#h&&this.#h.abort(),this.#h=new AbortController,this.serverParams.query=this.#e.value;let t=new URLSearchParams(this.serverParams).toString();fetch(this.server+"?"+t,{signal:this.#h.signal}).then(s=>s.json()).then(s=>{let o=s.data||s;this.#f(o),this.#h=null,e&&this.#c()}).catch(s=>{s.name!=="AbortError"&&console.error(s)})}#m(){if(this.#t.hasAttribute("placeholder"))return this.#t.getAttribute("placeholder");if(this.#t.dataset.placeholder)return this.#t.dataset.placeholder;let e=this.#t.querySelector("option");return e?(e.hasAttribute("selected")&&e.removeAttribute("selected"),e.value?"":e.textContent):""}#g(){this.#s.classList.add("dropdown-menu","p-0"),this.#s.style.maxHeight="280px",this.#s.style.overflowY="auto",this.#s.addEventListener("mouseenter",e=>{this.#r=!1})}#v(){this.#i.classList.add("form-control","dropdown"),this.#p()===4&&(this.#i.style.height="auto")}#b(){this.#n.addEventListener("click",t=>{this.isDisabled()||this.#e.style.visibility!="hidden"&&this.#e.focus()});let e=this.#t.selectedOptions;for(let t=0;t{if(e.data){let t=e.data.slice(-1);if(this.separator.length&&this.#e.value&&this.separator.includes(t)){this.#e.value=this.#e.value.slice(0,-1);let s=this.#e.value;if(!this.canAdd(s))return;this.addItem(s,null),this.#d();return}}this.#l(),this.#e.value.length>=this.suggestionsThreshold?this.liveServer?this.#u(!0):this.#c():this.#a()}),this.#e.addEventListener("focus",e=>{this.#e.value.length>=this.suggestionsThreshold&&this.#c()}),this.#e.addEventListener("focusout",e=>{this.#a()}),this.#e.addEventListener("keydown",e=>{switch(e.keyCode||e.key){case 13:case"Enter":e.preventDefault();let s=this.getActiveSelection();if(s)s.click();else if(this.allowNew&&this.#e.value){let i=this.#e.value;if(!this.canAdd(i))return;this.addItem(i,null),this.#d()}break;case 38:case"ArrowUp":e.preventDefault(),this.#r=!0;let o=this.#w();this.#e.value.length==0&&this.#s.classList.contains("show")&&!o&&this.#a();break;case 40:case"ArrowDown":e.preventDefault(),this.#r=!0,this.#E(),this.#e.value.length==0&&!this.#s.classList.contains("show")&&this.#c();break;case 8:case"Backspace":this.#e.value.length==0&&(this.removeLastItem(),this.#l(),this.#a());break;case 27:case"Escape":this.#a();break}})}#w(){let e=this.getActiveSelection();if(e){let t=e.parentNode;do t=t.previousSibling;while(t&&t.style.display=="none");return t?(e.classList.remove(...b),t.querySelector("a").classList.add(...b),t.parentNode.scrollTop=t.offsetTop-t.parentNode.offsetTop,t):null}return null}#E(){let e=this.getActiveSelection(),t=null;if(e){t=e.parentNode;do t=t.nextSibling;while(t&&t.style.display=="none");return t?(e.classList.remove(...b),t.querySelector("a").classList.add(...b),t.offsetTop>t.parentNode.offsetHeight-t.offsetHeight&&(t.parentNode.scrollTop+=t.offsetHeight),t):null}return t}#l(){this.#e.value?this.#e.size=this.#e.value.length+1:this.getSelectedValues().length?(this.#e.placeholder="",this.#e.size=1):(this.#e.size=this.placeholder.length>0?this.placeholder.length:1,this.#e.placeholder=this.placeholder)}#f(e=null){for(;this.#s.lastChild;)this.#s.removeChild(this.#s.lastChild);for(let t=0;t{this.#r||(this.removeActiveSelection(),o.querySelector("a").classList.add(...b))}),i.addEventListener("mousemove",l=>{this.#r=!1}),i.addEventListener("mousedown",l=>{l.preventDefault()}),i.addEventListener("click",l=>{l.preventDefault();let r=i.textContent;!this.canAdd(r,i.getAttribute(C))||(this.addItem(r,i.getAttribute(C),i.dataset),this.#d())})}}reset(){this.removeAll(),this.#o=!1;let e=this.#t.querySelectorAll("option[data-init]");for(let t=0;tt.value)}#c(){if(this.#e.style.visibility=="hidden")return;this.#s.style.left=this.#e.offsetLeft+"px";let e=this.#e.value.toLocaleLowerCase(),t=this.getSelectedValues(),s=this.#s.querySelectorAll("li"),o=!1,i=null,l=!1;for(let r=0;rs.textContent==e);return!!(t&&t.getAttribute("selected"))}#A(e){return new RegExp(this.validationRegex.trim()).test(e)}getActiveSelection(){return this.#s.querySelector("a."+He)}removeActiveSelection(){let e=this.getActiveSelection();e&&e.classList.remove(...b)}removeAll(){this.getSelectedValues().forEach(t=>{this.removeItem(t)}),this.#l()}removeLastItem(e){e&&(this.#o=!1);let t=this.#n.querySelectorAll("span");if(!t.length)return;let s=t[t.length-1];this.removeItem(s.getAttribute(C)),this.#o=!0}isDisabled(){return this.#t.hasAttribute("disabled")||this.#t.disabled||this.#t.hasAttribute("readonly")}isInvalid(){return this.#i.classList.contains("is-invalid")}isSingle(){return!this.#t.hasAttribute("multiple")}canAdd(e,t=null){return t||(t=e),!e||this.isDisabled()||!this.isSingle()&&this.#S(t)||this.max&&this.getSelectedValues().length>=this.max?!1:this.validationRegex&&!this.#A(e)?(this.#i.classList.add("is-invalid"),!1):!0}addItem(e,t=null,s={}){t||(t=e),this.isSingle()&&this.getSelectedValues().length&&this.removeLastItem(!0);let o=this.#p(),i=this.#t.querySelector('option[value="'+t+'"]');i&&(s=i.dataset);let l=e,r=document.createElement("span"),h=["badge"],c=this.badgeStyle;if(s.badgeStyle&&(c=s.badgeStyle),s.badgeClass&&h.push(s.badgeClass),o===5?h=[...h,"me-2","bg-"+c]:h=[...h,"mr-2","badge-"+c],r.classList.add(...h),r.setAttribute(C,t),this.allowClear&&(l=(o===5?'':'')+l),r.innerHTML=l,this.#n.insertBefore(r,this.#e),this.allowClear&&r.querySelector("button").addEventListener("click",a=>{a.preventDefault(),a.stopPropagation(),this.isDisabled()||(this.removeItem(t),document.activeElement.blur(),this.#l())}),!i){i=document.createElement("option"),i.value=t,i.textContent=e;for(let[a,f]of Object.entries(s))i.dataset[a]=f;this.#t.appendChild(i)}i.setAttribute("selected","selected"),i.selected=!0,this.#o&&this.#t.dispatchEvent(new Event("change",{bubbles:!0}))}removeItem(e){let t=this.#n.querySelector("span["+C+'="'+e+'"]');if(!t)return;t.remove();let s=this.#t.querySelector('option[value="'+e+'"]');s&&(s.removeAttribute("selected"),s.selected=!1,this.#o&&this.#t.dispatchEvent(new Event("change",{bubbles:!0}))),this.#e.style.visibility=="hidden"&&this.max&&this.getSelectedValues().length {\n let result = false;\n try {\n const opts = Object.defineProperty({}, 'passive', {\n get() {\n result = true;\n return result;\n },\n });\n document[addEventListener]('DOMContentLoaded', function wrap() {\n document[removeEventListener]('DOMContentLoaded', wrap, opts);\n }, opts);\n } catch (e) {\n throw Error('Passive events are not supported');\n }\n\n return result;\n})();\n\nexport default supportPassive;\n", "// general event options\n// not suited for scroll prevention\n// https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md#feature-detection\nimport supportPassive from '../boolean/supportPassive';\n\n/**\n * A global namespace for most scroll event listeners.\n */\nconst passiveHandler = supportPassive ? { passive: true } : false;\n\nexport default passiveHandler;\n", "/**\n * Add class to Element.classList\n *\n * @param {Element} element target\n * @param {string} classNAME to add\n */\nexport default function addClass(element, classNAME) {\n element.classList.add(classNAME);\n}\n", "/**\n * Check class in Element.classList\n *\n * @param {Element} element target\n * @param {string} classNAME to check\n * @return {boolean}\n */\nexport default function hasClass(element, classNAME) {\n return element.classList.contains(classNAME);\n}\n", "/**\n * Remove class from Element.classList\n *\n * @param {Element} element target\n * @param {string} classNAME to remove\n */\nexport default function removeClass(element, classNAME) {\n element.classList.remove(classNAME);\n}\n", "const ariaExpanded = 'aria-expanded';\nexport default ariaExpanded;\n", "const showClass = 'show';\nexport default showClass;\n", "const dataBsToggle = 'data-bs-toggle';\nexport default dataBsToggle;\n", "const dropdownMenuClasses = ['dropdown', 'dropup', 'dropstart', 'dropend'];\nexport default dropdownMenuClasses;\n", "const dropdownMenuClass = 'dropdown-menu';\nexport default dropdownMenuClass;\n", "export default function bootstrapCustomEvent(namespacedEventType, eventProperties) {\n const OriginalCustomEvent = new CustomEvent(namespacedEventType, { cancelable: true });\n\n if (eventProperties instanceof Object) {\n Object.keys(eventProperties).forEach((key) => {\n Object.defineProperty(OriginalCustomEvent, key, {\n value: eventProperties[key],\n });\n });\n }\n return OriginalCustomEvent;\n}\n", "export default function isEmptyAnchor(elem) {\n const parentAnchor = elem.closest('A');\n // anchor href starts with #\n return elem && ((elem.hasAttribute('href') && elem.href.slice(-1) === '#')\n // OR a child of an anchor with href starts with #\n || (parentAnchor && parentAnchor.hasAttribute('href') && parentAnchor.href.slice(-1) === '#'));\n}\n", "export default function setFocus(element) {\n element.focus();\n}\n", "/**\n * The raw value or a given component option.\n *\n * @typedef {string | Element | Function | number | boolean | null} niceValue\n */\n\n/**\n * Utility to normalize component options\n *\n * @param {any} value the input value\n * @return {niceValue} the normalized value\n */\nexport default function normalizeValue(value) {\n if (value === 'true') { // boolean\n return true;\n }\n\n if (value === 'false') { // boolean\n return false;\n }\n\n if (!Number.isNaN(+value)) { // number\n return +value;\n }\n\n if (value === '' || value === 'null') { // null\n return null;\n }\n\n // string / function / Element / object\n return value;\n}\n", "/**\n * Shortcut for `Object.keys()` static method.\n * @param {Record} obj a target object\n * @returns {string[]}\n */\nconst ObjectKeys = (obj) => Object.keys(obj);\nexport default ObjectKeys;\n", "import normalizeValue from './normalizeValue';\nimport ObjectKeys from './ObjectKeys';\n\n/**\n * Utility to normalize component options\n *\n * @param {Element} element target\n * @param {Record} defaultOps component default options\n * @param {Record} inputOps component instance options\n * @param {string=} ns component namespace\n * @return {Record} normalized component options object\n */\nexport default function normalizeOptions(element, defaultOps, inputOps, ns) {\n // @ts-ignore -- usually our `Element` is `HTMLElement` as well\n const data = { ...element.dataset };\n const normalOps = {};\n const dataOps = {};\n\n ObjectKeys(data).forEach((k) => {\n const key = ns && k.includes(ns)\n ? k.replace(ns, '').replace(/[A-Z]/, (match) => match.toLowerCase())\n : k;\n\n dataOps[key] = normalizeValue(data[k]);\n });\n\n ObjectKeys(inputOps).forEach((k) => {\n inputOps[k] = normalizeValue(inputOps[k]);\n });\n\n ObjectKeys(defaultOps).forEach((k) => {\n if (k in inputOps) {\n normalOps[k] = inputOps[k];\n } else if (k in dataOps) {\n normalOps[k] = dataOps[k];\n } else {\n normalOps[k] = defaultOps[k];\n }\n });\n\n return normalOps;\n}\n", "/* Native JavaScript for Bootstrap 5 | Base Component\n----------------------------------------------------- */\n\nimport queryElement from 'shorter-js/src/misc/queryElement.js';\nimport normalizeOptions from 'shorter-js/src/misc/normalizeOptions.js';\n\nexport default class BaseComponent {\n constructor(name, target, defaults, config) {\n const self = this;\n const element = queryElement(target);\n\n if (element[name]) element[name].dispose();\n self.element = element;\n\n if (defaults && Object.keys(defaults).length) {\n self.options = normalizeOptions(element, defaults, (config || {}), 'bs');\n }\n element[name] = self;\n }\n\n dispose(name) {\n const self = this;\n self.element[name] = null;\n Object.keys(self).forEach((prop) => { self[prop] = null; });\n }\n}\n", "/* Native JavaScript for Bootstrap 5 | Dropdown\n----------------------------------------------- */\nimport queryElement from 'shorter-js/src/misc/queryElement.js';\nimport passiveHandler from 'shorter-js/src/misc/passiveHandler.js';\nimport addClass from 'shorter-js/src/class/addClass.js';\nimport hasClass from 'shorter-js/src/class/hasClass.js';\nimport removeClass from 'shorter-js/src/class/removeClass.js';\nimport addEventListener from 'shorter-js/src/strings/addEventListener.js';\nimport removeEventListener from 'shorter-js/src/strings/removeEventListener.js';\n\nimport ariaExpanded from '../strings/ariaExpanded.js';\nimport showClass from '../strings/showClass.js';\nimport dataBsToggle from '../strings/dataBsToggle.js';\nimport dropdownClasses from '../strings/dropdownClasses.js';\nimport dropdownMenuClass from '../strings/dropdownMenuClass.js';\n\nimport bootstrapCustomEvent from '../util/bootstrapCustomEvent.js';\nimport isEmptyAnchor from '../util/isEmptyAnchor.js';\nimport setFocus from '../util/setFocus.js';\nimport BaseComponent from './base-component.js';\n\n// DROPDOWN PRIVATE GC\n// ===================\nconst [dropdownString] = dropdownClasses;\nconst dropdownComponent = 'Dropdown';\nconst dropdownSelector = `[${dataBsToggle}=\"${dropdownString}\"]`;\n\n// DROPDOWN PRIVATE GC\n// ===================\nconst dropupString = dropdownClasses[1];\nconst dropstartString = dropdownClasses[2];\nconst dropendString = dropdownClasses[3];\nconst dropdownMenuEndClass = `${dropdownMenuClass}-end`;\nconst hideMenuClass = ['d-block', 'invisible'];\nconst verticalClass = [dropdownString, dropupString];\nconst horizontalClass = [dropstartString, dropendString];\nconst defaultDropdownOptions = {\n offset: 5, // [number] 5(px)\n display: 'dynamic', // [dynamic|static]\n};\n\n// DROPDOWN CUSTOM EVENTS\n// ========================\nconst showDropdownEvent = bootstrapCustomEvent(`show.bs.${dropdownString}`);\nconst shownDropdownEvent = bootstrapCustomEvent(`shown.bs.${dropdownString}`);\nconst hideDropdownEvent = bootstrapCustomEvent(`hide.bs.${dropdownString}`);\nconst hiddenDropdownEvent = bootstrapCustomEvent(`hidden.bs.${dropdownString}`);\n\n// DROPDOWN PRIVATE METHODS\n// ========================\nfunction styleDropdown(self, show) {\n const {\n element, menu, originalClass, menuEnd, options,\n } = self;\n const { offset } = options;\n const parent = element.parentElement;\n\n // reset menu offset and position\n const resetProps = ['margin', 'top', 'bottom', 'left', 'right'];\n resetProps.forEach((p) => { menu.style[p] = ''; });\n removeClass(parent, 'position-static');\n\n if (!show) {\n const menuEndNow = hasClass(menu, dropdownMenuEndClass);\n parent.className = originalClass.join(' ');\n if (menuEndNow && !menuEnd) removeClass(menu, dropdownMenuEndClass);\n else if (!menuEndNow && menuEnd) addClass(menu, dropdownMenuEndClass);\n return;\n }\n\n // set initial position class\n // take into account .btn-group parent as .dropdown\n let positionClass = dropdownClasses.find((c) => originalClass.includes(c)) || dropdownString;\n\n let dropdownMargin = {\n dropdown: [offset, 0, 0],\n dropup: [0, 0, offset],\n dropstart: [-1, offset, 0],\n dropend: [-1, 0, 0, offset],\n };\n\n const dropdownPosition = {\n dropdown: { top: '100%' },\n dropup: { top: 'auto', bottom: '100%' },\n dropstart: { left: 'auto', right: '100%' },\n dropend: { left: '100%', right: 'auto' },\n menuEnd: { right: 0, left: 'auto' },\n };\n\n // force showing the menu to calculate its size\n hideMenuClass.forEach((c) => addClass(menu, c));\n\n const dropdownRegex = new RegExp(`\\\\b(${dropdownString}|${dropupString}|${dropstartString}|${dropendString})+`);\n const elementDimensions = { w: element.offsetWidth, h: element.offsetHeight };\n const menuDimensions = { w: menu.offsetWidth, h: menu.offsetHeight };\n const HTML = document.documentElement;\n const BD = document.body;\n const windowWidth = (HTML.clientWidth || BD.clientWidth);\n const windowHeight = (HTML.clientHeight || BD.clientHeight);\n const targetBCR = element.getBoundingClientRect();\n // dropdownMenuEnd && [ dropdown | dropup ]\n const leftExceed = targetBCR.left + elementDimensions.w - menuDimensions.w < 0;\n // dropstart\n const leftFullExceed = targetBCR.left - menuDimensions.w < 0;\n // !dropdownMenuEnd && [ dropdown | dropup ]\n const rightExceed = targetBCR.left + menuDimensions.w >= windowWidth;\n // dropend\n const rightFullExceed = targetBCR.left + menuDimensions.w + elementDimensions.w >= windowWidth;\n // dropstart | dropend\n const bottomExceed = targetBCR.top + menuDimensions.h >= windowHeight;\n // dropdown\n const bottomFullExceed = targetBCR.top + menuDimensions.h + elementDimensions.h >= windowHeight;\n // dropup\n const topExceed = targetBCR.top - menuDimensions.h < 0;\n\n // recompute position\n if (horizontalClass.includes(positionClass) && leftFullExceed && rightFullExceed) {\n positionClass = dropdownString;\n }\n if (horizontalClass.includes(positionClass) && bottomExceed) {\n positionClass = dropupString;\n }\n if (positionClass === dropstartString && leftFullExceed && !bottomExceed) {\n positionClass = dropendString;\n }\n if (positionClass === dropendString && rightFullExceed && !bottomExceed) {\n positionClass = dropstartString;\n }\n if (positionClass === dropupString && topExceed && !bottomFullExceed) {\n positionClass = dropdownString;\n }\n if (positionClass === dropdownString && bottomFullExceed && !topExceed) {\n positionClass = dropupString;\n }\n\n // set spacing\n dropdownMargin = dropdownMargin[positionClass];\n menu.style.margin = `${dropdownMargin.map((x) => (x ? `${x}px` : x)).join(' ')}`;\n Object.keys(dropdownPosition[positionClass]).forEach((position) => {\n menu.style[position] = dropdownPosition[positionClass][position];\n });\n\n // update dropdown position class\n if (!hasClass(parent, positionClass)) {\n parent.className = parent.className.replace(dropdownRegex, positionClass);\n }\n\n // update dropdown / dropup to handle parent btn-group element\n // as well as the dropdown-menu-end utility class\n if (verticalClass.includes(positionClass)) {\n if (!menuEnd && rightExceed) addClass(menu, dropdownMenuEndClass);\n else if (menuEnd && leftExceed) removeClass(menu, dropdownMenuEndClass);\n\n if (hasClass(menu, dropdownMenuEndClass)) {\n Object.keys(dropdownPosition.menuEnd).forEach((p) => {\n menu.style[p] = dropdownPosition.menuEnd[p];\n });\n }\n }\n\n // remove util classes from the menu, we have its size\n hideMenuClass.forEach((c) => removeClass(menu, c));\n}\n\nfunction toggleDropdownDismiss(self) {\n const action = self.open ? addEventListener : removeEventListener;\n\n document[action]('click', dropdownDismissHandler);\n document[action]('focus', dropdownDismissHandler);\n document[action]('keydown', dropdownPreventScroll);\n document[action]('keyup', dropdownKeyHandler);\n\n if (self.options.display === 'dynamic') {\n window[action]('scroll', dropdownLayoutHandler, passiveHandler);\n window[action]('resize', dropdownLayoutHandler, passiveHandler);\n }\n}\n\nfunction toggleDropdownHandler(self, add) {\n const action = add ? addEventListener : removeEventListener;\n self.element[action]('click', dropdownClickHandler);\n}\n\nfunction getCurrentOpenDropdown() {\n const currentParent = dropdownClasses.concat('btn-group')\n .map((c) => document.getElementsByClassName(`${c} ${showClass}`))\n .find((x) => x.length);\n\n if (currentParent && currentParent.length) {\n return Array.from(currentParent[0].children).find((x) => x.hasAttribute(dataBsToggle));\n }\n return null;\n}\n\n// DROPDOWN EVENT HANDLERS\n// =======================\nfunction dropdownDismissHandler(e) {\n const { target, type } = e;\n if (!target.closest) return; // some weird FF bug #409\n\n const element = getCurrentOpenDropdown();\n const parent = element && element.parentNode;\n const self = element && element[dropdownComponent];\n const menu = self && self.menu;\n\n const hasData = target.closest(dropdownSelector) !== null;\n const isForm = parent && parent.contains(target)\n && (target.tagName === 'form' || target.closest('form') !== null);\n\n if (type === 'click' && isEmptyAnchor(target)) {\n e.preventDefault();\n }\n if (type === 'focus'\n && (target === element || target === menu || menu.contains(target))) {\n return;\n }\n\n if (isForm || hasData) {\n // smile to ESLint\n } else if (self) {\n self.hide(element);\n }\n}\n\nfunction dropdownClickHandler(e) {\n const element = this;\n const self = element[dropdownComponent];\n self.toggle(element);\n\n if (isEmptyAnchor(e.target)) e.preventDefault();\n}\n\nfunction dropdownPreventScroll(e) {\n if (e.which === 38 || e.which === 40) e.preventDefault();\n}\n\nfunction dropdownKeyHandler({ which }) {\n const element = getCurrentOpenDropdown();\n const self = element[dropdownComponent];\n const { menu, menuItems, open } = self;\n const activeItem = document.activeElement;\n const isSameElement = activeItem === element;\n const isInsideMenu = menu.contains(activeItem);\n const isMenuItem = activeItem.parentNode === menu || activeItem.parentNode.parentNode === menu;\n\n let idx = menuItems.indexOf(activeItem);\n\n if (isMenuItem) { // navigate up | down\n if (isSameElement) {\n idx = 0;\n } else if (which === 38) {\n idx = idx > 1 ? idx - 1 : 0;\n } else if (which === 40) {\n idx = idx < menuItems.length - 1 ? idx + 1 : idx;\n }\n\n if (menuItems[idx]) setFocus(menuItems[idx]);\n }\n\n if (((menuItems.length && isMenuItem) // menu has items\n || (!menuItems.length && (isInsideMenu || isSameElement)) // menu might be a form\n || !isInsideMenu) // or the focused element is not in the menu at all\n && open && which === 27 // menu must be open\n ) {\n self.toggle();\n }\n}\n\nfunction dropdownLayoutHandler() {\n const element = getCurrentOpenDropdown();\n const self = element && element[dropdownComponent];\n\n if (self && self.open) styleDropdown(self, 1);\n}\n\n// DROPDOWN DEFINITION\n// ===================\nexport default class Dropdown extends BaseComponent {\n constructor(target, config) {\n super(dropdownComponent, target, defaultDropdownOptions, config);\n // bind\n const self = this;\n\n // initialization element\n const { element } = self;\n\n // set targets\n const parent = element.parentElement;\n self.menu = queryElement(`.${dropdownMenuClass}`, parent);\n const { menu } = self;\n\n self.originalClass = Array.from(parent.classList);\n\n // set original position\n self.menuEnd = hasClass(menu, dropdownMenuEndClass);\n\n self.menuItems = [];\n\n Array.from(menu.children).forEach((child) => {\n if (child.children.length && (child.children[0].tagName === 'A')) self.menuItems.push(child.children[0]);\n if (child.tagName === 'A') self.menuItems.push(child);\n });\n\n // set initial state to closed\n self.open = false;\n\n // add event listener\n toggleDropdownHandler(self, 1);\n }\n\n // DROPDOWN PUBLIC METHODS\n // =======================\n toggle(related) {\n const self = this;\n const { open } = self;\n\n if (open) self.hide(related);\n else self.show(related);\n }\n\n show(related) {\n const self = this;\n const currentParent = queryElement(dropdownClasses.concat('btn-group').map((c) => `.${c}.${showClass}`).join(','));\n const currentElement = currentParent && queryElement(dropdownSelector, currentParent);\n\n if (currentElement) currentElement[dropdownComponent].hide();\n\n const { element, menu, open } = self;\n const parent = element.parentNode;\n\n // update relatedTarget and dispatch\n showDropdownEvent.relatedTarget = related || null;\n parent.dispatchEvent(showDropdownEvent);\n if (showDropdownEvent.defaultPrevented) return;\n\n // change menu position\n styleDropdown(self, 1);\n\n addClass(menu, showClass);\n addClass(parent, showClass);\n\n element.setAttribute(ariaExpanded, true);\n self.open = !open;\n\n setTimeout(() => {\n setFocus(menu.getElementsByTagName('INPUT')[0] || element); // focus the first input item | element\n toggleDropdownDismiss(self);\n\n shownDropdownEvent.relatedTarget = related || null;\n parent.dispatchEvent(shownDropdownEvent);\n }, 1);\n }\n\n hide(related) {\n const self = this;\n const { element, menu, open } = self;\n const parent = element.parentNode;\n hideDropdownEvent.relatedTarget = related || null;\n parent.dispatchEvent(hideDropdownEvent);\n if (hideDropdownEvent.defaultPrevented) return;\n\n removeClass(menu, showClass);\n removeClass(parent, showClass);\n\n // revert to original position\n styleDropdown(self);\n\n element.setAttribute(ariaExpanded, false);\n self.open = !open;\n\n setFocus(element);\n\n // only re-attach handler if the instance is not disposed\n setTimeout(() => toggleDropdownDismiss(self), 1);\n\n // update relatedTarget and dispatch\n hiddenDropdownEvent.relatedTarget = related || null;\n parent.dispatchEvent(hiddenDropdownEvent);\n }\n\n dispose() {\n const self = this;\n const { element } = self;\n\n if (hasClass(element.parentNode, showClass) && self.open) self.hide();\n\n toggleDropdownHandler(self);\n\n super.dispose(dropdownComponent);\n }\n}\n\nDropdown.init = {\n component: dropdownComponent,\n selector: dropdownSelector,\n constructor: Dropdown,\n};\n", "/**\r\n * Bootstrap 5 (and 4!) tags\r\n *\r\n * Turns your select[multiple] into nice tags lists\r\n *\r\n * Required Bootstrap 5 styles:\r\n * - badge\r\n * - background-color utility\r\n * - margin-end utility\r\n * - float-start utility\r\n * - forms\r\n * - dropdown\r\n */\r\n\r\nconst ACTIVE_CLASS = \"is-active\";\r\nconst ACTIVE_CLASSES = [\"is-active\", \"bg-primary\", \"text-white\"];\r\nconst VALUE_ATTRIBUTE = \"data-value\";\r\n\r\n// Static map will minify very badly as class prop, so we use an external constant\r\nconst INSTANCE_MAP = new WeakMap();\r\n\r\nclass Tags {\r\n #abortController;\r\n #selectElement;\r\n #holderElement;\r\n #containerElement;\r\n #dropElement;\r\n #searchInput;\r\n #keyboardNavigation;\r\n #fireEvents;\r\n\r\n /**\r\n * @param {HTMLSelectElement} el\r\n * @param {Object} globalOpts\r\n */\r\n constructor(el, globalOpts = {}) {\r\n // Hide the select element and register a tags attr\r\n el.style.display = \"none\";\r\n el.dataset.tags = true;\r\n this.#selectElement = el;\r\n\r\n // Allow 1/0, true/false as strings\r\n const parseBool = (value) => [\"true\", \"false\", \"1\", \"0\", true, false].includes(value) && !!JSON.parse(value);\r\n\r\n // Handle options, using global settings first and data attr override\r\n const opts = { ...globalOpts, ...el.dataset };\r\n this.allowNew = opts.allowNew ? parseBool(opts.allowNew) : false;\r\n this.showAllSuggestions = opts.showAllSuggestions ? parseBool(opts.showAllSuggestions) : false;\r\n this.badgeStyle = opts.badgeStyle || \"primary\";\r\n this.allowClear = opts.allowClear ? parseBool(opts.allowClear) : false;\r\n this.server = opts.server || false;\r\n this.liveServer = opts.liveServer ? parseBool(opts.liveServer) : false;\r\n this.serverParams = opts.serverParams || {};\r\n if (typeof this.serverParams == \"string\") {\r\n this.serverParams = JSON.parse(this.serverParams);\r\n }\r\n this.suggestionsThreshold = typeof opts.suggestionsThreshold != \"undefined\" ? parseInt(opts.suggestionsThreshold) : 1;\r\n this.validationRegex = opts.regex || \"\";\r\n this.separator = opts.separator ? opts.separator.split(\"|\") : [];\r\n this.max = opts.max ? parseInt(opts.max) : null;\r\n this.clearLabel = opts.clearLabel || \"Clear\";\r\n this.searchLabel = opts.searchLabel || \"Type a value\";\r\n\r\n this.placeholder = this.#getPlaceholder();\r\n this.#keyboardNavigation = false;\r\n this.#fireEvents = true;\r\n\r\n this.parentForm = el.parentElement;\r\n while (this.parentForm) {\r\n this.parentForm = this.parentForm.parentElement;\r\n if (this.parentForm.nodeName == \"FORM\") {\r\n break;\r\n }\r\n }\r\n\r\n this.reset = this.reset.bind(this);\r\n this.parentForm.addEventListener(\"reset\", this.reset);\r\n\r\n // Create elements\r\n this.#holderElement = document.createElement(\"div\"); // this is the one holding the fake input and the dropmenu\r\n this.#containerElement = document.createElement(\"div\"); // this is the one for the fake input (labels + input)\r\n this.#dropElement = document.createElement(\"ul\");\r\n this.#searchInput = document.createElement(\"input\");\r\n\r\n this.#holderElement.appendChild(this.#containerElement);\r\n this.#containerElement.appendChild(this.#searchInput);\r\n this.#holderElement.appendChild(this.#dropElement);\r\n // insert after\r\n this.#selectElement.parentNode.insertBefore(this.#holderElement, this.#selectElement.nextSibling);\r\n\r\n // Configure them\r\n this.#configureHolderElement();\r\n this.#configureDropElement();\r\n this.#configureContainerElement();\r\n this.#configureSearchInput();\r\n this.resetState();\r\n\r\n if (this.server && !this.liveServer) {\r\n this.#loadFromServer();\r\n } else {\r\n this.resetSuggestions();\r\n }\r\n }\r\n\r\n /**\r\n * Attach to all elements matched by the selector\r\n * @param {string} selector\r\n * @param {Object} opts\r\n */\r\n static init(selector = \"select[multiple]\", opts = {}) {\r\n let list = document.querySelectorAll(selector);\r\n let el;\r\n for (let i = 0; i < list.length; i++) {\r\n if (!list[i].dataset.tags) {\r\n el = new Tags(list[i], opts);\r\n INSTANCE_MAP.set(list[i], el);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @param {HTMLSelectElement} el\r\n */\r\n static getInstance(el) {\r\n if (INSTANCE_MAP.has(el)) {\r\n return INSTANCE_MAP.get(el);\r\n }\r\n }\r\n\r\n dispose() {\r\n INSTANCE_MAP.delete(this.#selectElement);\r\n this.#selectElement.dataset.tags = null;\r\n this.#selectElement.style.display = \"block\";\r\n this.#holderElement.parentNode.removeChild(this.#holderElement);\r\n this.parentForm.removeEventListener(\"reset\", this.reset);\r\n }\r\n\r\n resetState() {\r\n if (this.isDisabled()) {\r\n this.#holderElement.setAttribute(\"readonly\", \"\");\r\n this.#searchInput.setAttribute(\"disabled\", \"\");\r\n } else {\r\n if (this.#holderElement.hasAttribute(\"readonly\")) {\r\n this.#holderElement.removeAttribute(\"readonly\");\r\n }\r\n if (this.#searchInput.hasAttribute(\"disabled\")) {\r\n this.#searchInput.removeAttribute(\"disabled\");\r\n }\r\n }\r\n }\r\n\r\n resetSuggestions() {\r\n let suggestions = Array.from(this.#selectElement.querySelectorAll(\"option\"))\r\n .filter((option) => {\r\n return !option.disabled;\r\n })\r\n .map((option) => {\r\n return {\r\n value: option.getAttribute(\"value\"),\r\n label: option.innerText,\r\n };\r\n });\r\n this.#buildSuggestions(suggestions);\r\n }\r\n\r\n /**\r\n * @param {boolean} show\r\n */\r\n #loadFromServer(show = false) {\r\n if (this.#abortController) {\r\n this.#abortController.abort();\r\n }\r\n this.#abortController = new AbortController();\r\n\r\n this.serverParams.query = this.#searchInput.value;\r\n const params = new URLSearchParams(this.serverParams).toString();\r\n\r\n fetch(this.server + \"?\" + params, { signal: this.#abortController.signal })\r\n .then((r) => r.json())\r\n .then((suggestions) => {\r\n let data = suggestions.data || suggestions;\r\n this.#buildSuggestions(data);\r\n this.#abortController = null;\r\n if (show) {\r\n this.#showSuggestions();\r\n }\r\n })\r\n .catch((e) => {\r\n if (e.name === \"AbortError\") {\r\n return;\r\n }\r\n console.error(e);\r\n });\r\n }\r\n\r\n /**\r\n * @returns {string}\r\n */\r\n #getPlaceholder() {\r\n // Use placeholder and data-placeholder in priority\r\n if (this.#selectElement.hasAttribute(\"placeholder\")) {\r\n return this.#selectElement.getAttribute(\"placeholder\");\r\n }\r\n if (this.#selectElement.dataset.placeholder) {\r\n return this.#selectElement.dataset.placeholder;\r\n }\r\n // Fallback to first option if no value\r\n let firstOption = this.#selectElement.querySelector(\"option\");\r\n if (!firstOption) {\r\n return \"\";\r\n }\r\n if (firstOption.hasAttribute(\"selected\")) {\r\n firstOption.removeAttribute(\"selected\");\r\n }\r\n return !firstOption.value ? firstOption.innerText : \"\";\r\n }\r\n\r\n #configureDropElement() {\r\n this.#dropElement.classList.add(...[\"dropdown-menu\", \"p-0\"]);\r\n this.#dropElement.style.maxHeight = \"280px\";\r\n this.#dropElement.style.overflowY = \"auto\";\r\n\r\n // If the mouse was outside, entering remove keyboard nav mode\r\n this.#dropElement.addEventListener(\"mouseenter\", (event) => {\r\n this.#keyboardNavigation = false;\r\n });\r\n }\r\n\r\n #configureHolderElement() {\r\n this.#holderElement.classList.add(...[\"form-control\", \"dropdown\"]);\r\n if (this.#getBootstrapVersion() === 4) {\r\n // Prevent fixed height due to form-control\r\n this.#holderElement.style.height = \"auto\";\r\n }\r\n }\r\n\r\n #configureContainerElement() {\r\n this.#containerElement.addEventListener(\"click\", (event) => {\r\n if (this.isDisabled()) {\r\n return;\r\n }\r\n if (this.#searchInput.style.visibility != \"hidden\") {\r\n this.#searchInput.focus();\r\n }\r\n });\r\n\r\n // add initial values\r\n // we use selectedOptions because single select can have a selected option\r\n // without a selected attribute if it's the first value\r\n let initialValues = this.#selectElement.selectedOptions;\r\n for (let j = 0; j < initialValues.length; j++) {\r\n let initialValue = initialValues[j];\r\n if (!initialValue.value) {\r\n continue;\r\n }\r\n // track initial values for reset\r\n initialValue.dataset.init = 1;\r\n this.addItem(initialValue.innerText, initialValue.value);\r\n }\r\n }\r\n\r\n #configureSearchInput() {\r\n this.#searchInput.type = \"text\";\r\n this.#searchInput.autocomplete = \"off\";\r\n this.#searchInput.spellcheck = false;\r\n this.#searchInput.style.backgroundColor = \"transparent\";\r\n this.#searchInput.style.border = 0;\r\n this.#searchInput.style.outline = 0;\r\n this.#searchInput.style.maxWidth = \"100%\";\r\n this.#searchInput.ariaLabel = this.searchLabel;\r\n this.#resetSearchInput(true);\r\n\r\n this.#searchInput.addEventListener(\"input\", (event) => {\r\n // Add item if a separator is used\r\n // On mobile or copy paste, it can pass multiple chars (eg: when pressing space and it formats the string)\r\n if (event.data) {\r\n const lastChar = event.data.slice(-1);\r\n if (this.separator.length && this.#searchInput.value && this.separator.includes(lastChar)) {\r\n let text = this.#searchInput.value.slice(0, -1);\r\n if (!this.canAdd(text)) {\r\n return;\r\n }\r\n this.addItem(text, null);\r\n this.#resetSearchInput();\r\n return;\r\n }\r\n }\r\n\r\n // Adjust input width to current content\r\n this.#adjustWidth();\r\n\r\n // Check if we should display suggestions\r\n if (this.#searchInput.value.length >= this.suggestionsThreshold) {\r\n if (this.liveServer) {\r\n this.#loadFromServer(true);\r\n } else {\r\n this.#showSuggestions();\r\n }\r\n } else {\r\n this.#hideSuggestions();\r\n }\r\n });\r\n this.#searchInput.addEventListener(\"focus\", (event) => {\r\n if (this.#searchInput.value.length >= this.suggestionsThreshold) {\r\n this.#showSuggestions();\r\n }\r\n });\r\n this.#searchInput.addEventListener(\"focusout\", (event) => {\r\n this.#hideSuggestions();\r\n });\r\n // keypress doesn't send arrow keys, so we use keydown\r\n this.#searchInput.addEventListener(\"keydown\", (event) => {\r\n // Keycode reference : https://css-tricks.com/snippets/javascript/javascript-keycodes/\r\n let key = event.keyCode || event.key;\r\n\r\n // Keyboard keys\r\n switch (key) {\r\n case 13:\r\n case \"Enter\":\r\n event.preventDefault();\r\n let selection = this.getActiveSelection();\r\n if (selection) {\r\n selection.click();\r\n } else {\r\n // We use what is typed if not selected and not empty\r\n if (this.allowNew && !this.#isSelected(this.#searchInput.value) && this.#searchInput.value) {\r\n let text = this.#searchInput.value;\r\n if (!this.canAdd(text)) {\r\n return;\r\n }\r\n this.addItem(text, null);\r\n this.#resetSearchInput();\r\n }\r\n }\r\n break;\r\n case 38:\r\n case \"ArrowUp\":\r\n event.preventDefault();\r\n this.#keyboardNavigation = true;\r\n let newSelection = this.#moveSelectionUp();\r\n // If we use arrow up without input and there is no new selection, hide suggestions\r\n if (this.#searchInput.value.length == 0 && this.#dropElement.classList.contains(\"show\") && !newSelection) {\r\n this.#hideSuggestions();\r\n }\r\n break;\r\n case 40:\r\n case \"ArrowDown\":\r\n event.preventDefault();\r\n this.#keyboardNavigation = true;\r\n this.#moveSelectionDown();\r\n // If we use arrow down without input, show suggestions\r\n if (this.#searchInput.value.length == 0 && !this.#dropElement.classList.contains(\"show\")) {\r\n this.#showSuggestions();\r\n }\r\n break;\r\n case 8:\r\n case \"Backspace\":\r\n if (this.#searchInput.value.length == 0) {\r\n this.removeLastItem();\r\n this.#adjustWidth();\r\n this.#hideSuggestions();\r\n }\r\n break;\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * @returns {HTMLElement}\r\n */\r\n #moveSelectionUp() {\r\n let active = this.getActiveSelection();\r\n if (active) {\r\n let prev = active.parentNode;\r\n do {\r\n prev = prev.previousSibling;\r\n } while (prev && prev.style.display == \"none\");\r\n if (!prev) {\r\n return null;\r\n }\r\n active.classList.remove(...ACTIVE_CLASSES);\r\n prev.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n // Don't use scrollIntoView as it scrolls the whole window\r\n prev.parentNode.scrollTop = prev.offsetTop - prev.parentNode.offsetTop;\r\n return prev;\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * @returns {HTMLElement}\r\n */\r\n #moveSelectionDown() {\r\n let active = this.getActiveSelection();\r\n let next = null;\r\n if (active) {\r\n next = active.parentNode;\r\n do {\r\n next = next.nextSibling;\r\n } while (next && next.style.display == \"none\");\r\n if (!next) {\r\n return null;\r\n }\r\n active.classList.remove(...ACTIVE_CLASSES);\r\n next.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n // This is the equivalent of scrollIntoView(false) but only for parent node\r\n if (next.offsetTop > next.parentNode.offsetHeight - next.offsetHeight) {\r\n next.parentNode.scrollTop += next.offsetHeight;\r\n }\r\n return next;\r\n }\r\n return next;\r\n }\r\n\r\n /**\r\n * Adjust the field to fit its content and show/hide placeholder if needed\r\n */\r\n #adjustWidth() {\r\n if (this.#searchInput.value) {\r\n this.#searchInput.size = this.#searchInput.value.length + 1;\r\n } else {\r\n // Show the placeholder only if empty\r\n if (this.getSelectedValues().length) {\r\n this.#searchInput.placeholder = \"\";\r\n this.#searchInput.size = 1;\r\n } else {\r\n this.#searchInput.size = this.placeholder.length > 0 ? this.placeholder.length : 1;\r\n this.#searchInput.placeholder = this.placeholder;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Add suggestions to the drop element\r\n * @param {array}\r\n */\r\n #buildSuggestions(suggestions = null) {\r\n while (this.#dropElement.lastChild) {\r\n this.#dropElement.removeChild(this.#dropElement.lastChild);\r\n }\r\n for (let i = 0; i < suggestions.length; i++) {\r\n let suggestion = suggestions[i];\r\n if (!suggestion.value) {\r\n continue;\r\n }\r\n let newChild = document.createElement(\"li\");\r\n let newChildLink = document.createElement(\"a\");\r\n newChild.append(newChildLink);\r\n newChildLink.classList.add(\"dropdown-item\");\r\n newChildLink.setAttribute(VALUE_ATTRIBUTE, suggestion.value);\r\n newChildLink.setAttribute(\"href\", \"#\");\r\n newChildLink.innerText = suggestion.label;\r\n if (suggestion.data) {\r\n for (const [key, value] of Object.entries(suggestion.data)) {\r\n newChildLink.dataset[key] = value;\r\n }\r\n }\r\n this.#dropElement.appendChild(newChild);\r\n\r\n // Hover sets active item\r\n newChildLink.addEventListener(\"mouseenter\", (event) => {\r\n // Don't trigger enter if using arrows\r\n if (this.#keyboardNavigation) {\r\n return;\r\n }\r\n this.removeActiveSelection();\r\n newChild.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n });\r\n // Moving the mouse means no longer using keyboard\r\n newChildLink.addEventListener(\"mousemove\", (event) => {\r\n this.#keyboardNavigation = false;\r\n });\r\n\r\n newChildLink.addEventListener(\"mousedown\", (event) => {\r\n // Otherwise searchInput would lose focus and close the menu\r\n event.preventDefault();\r\n });\r\n newChildLink.addEventListener(\"click\", (event) => {\r\n event.preventDefault();\r\n let text = newChildLink.innerText;\r\n if (!this.canAdd(text)) {\r\n return;\r\n }\r\n this.addItem(text, newChildLink.getAttribute(VALUE_ATTRIBUTE), newChildLink.dataset);\r\n this.#resetSearchInput();\r\n });\r\n }\r\n }\r\n\r\n reset() {\r\n this.removeAll();\r\n\r\n // Reset doesn't fire change event\r\n this.#fireEvents = false;\r\n let initialValues = this.#selectElement.querySelectorAll(\"option[data-init]\");\r\n for (let j = 0; j < initialValues.length; j++) {\r\n let initialValue = initialValues[j];\r\n this.addItem(initialValue.innerText, initialValue.value);\r\n }\r\n this.#adjustWidth();\r\n this.#fireEvents = true;\r\n }\r\n\r\n #resetSearchInput(init = false) {\r\n this.#searchInput.value = \"\";\r\n this.#adjustWidth();\r\n\r\n if (!init) {\r\n this.#hideSuggestions();\r\n // Trigger input even to show suggestions if needed\r\n this.#searchInput.dispatchEvent(new Event(\"input\"));\r\n }\r\n\r\n // We use visibility instead of display to keep layout intact\r\n if (this.max && this.getSelectedValues().length === this.max) {\r\n this.#searchInput.style.visibility = \"hidden\";\r\n } else if (this.#searchInput.style.visibility == \"hidden\") {\r\n this.#searchInput.style.visibility = \"visible\";\r\n }\r\n\r\n if (this.isSingle() && !init) {\r\n document.activeElement.blur();\r\n }\r\n }\r\n\r\n /**\r\n * @returns {array}\r\n */\r\n getSelectedValues() {\r\n // option[selected] is used rather that selectedOptions as it works more consistently\r\n let selected = this.#selectElement.querySelectorAll(\"option[selected]\");\r\n return Array.from(selected).map((el) => el.value);\r\n }\r\n\r\n /**\r\n * The element create with buildSuggestions\r\n */\r\n #showSuggestions() {\r\n if (this.#searchInput.style.visibility == \"hidden\") {\r\n return;\r\n }\r\n\r\n // Position next to search input\r\n this.#dropElement.style.left = this.#searchInput.offsetLeft + \"px\";\r\n\r\n // Get search value\r\n let search = this.#searchInput.value.toLocaleLowerCase();\r\n\r\n // Get current values\r\n let values = this.getSelectedValues();\r\n\r\n // Filter the list according to search string\r\n let list = this.#dropElement.querySelectorAll(\"li\");\r\n let found = false;\r\n let firstItem = null;\r\n let hasPossibleValues = false;\r\n for (let i = 0; i < list.length; i++) {\r\n let item = list[i];\r\n let text = item.innerText.toLocaleLowerCase();\r\n let link = item.querySelector(\"a\");\r\n\r\n // Remove previous selection\r\n link.classList.remove(...ACTIVE_CLASSES);\r\n\r\n // Hide selected values\r\n if (values.indexOf(link.getAttribute(VALUE_ATTRIBUTE)) != -1) {\r\n item.style.display = \"none\";\r\n continue;\r\n }\r\n\r\n hasPossibleValues = true;\r\n\r\n // Check search length since we can trigger dropdown with arrow\r\n let isMatched = search.length === 0 || text.indexOf(search) !== -1;\r\n if (this.showAllSuggestions || this.suggestionsThreshold === 0 || isMatched) {\r\n item.style.display = \"list-item\";\r\n found = true;\r\n if (!firstItem && isMatched) {\r\n firstItem = item;\r\n }\r\n } else {\r\n item.style.display = \"none\";\r\n }\r\n }\r\n\r\n // Always select first item\r\n if (firstItem) {\r\n this.#holderElement.classList.remove(\"is-invalid\");\r\n firstItem.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n firstItem.parentNode.scrollTop = firstItem.offsetTop - firstItem.parentNode.offsetTop;\r\n } else {\r\n // No item and we don't allow new items => error\r\n if (!this.allowNew && !(search.length === 0 && !hasPossibleValues)) {\r\n this.#holderElement.classList.add(\"is-invalid\");\r\n } else if (this.validationRegex && this.isInvalid()) {\r\n this.#holderElement.classList.remove(\"is-invalid\");\r\n }\r\n }\r\n\r\n // Remove dropdown if not found or to show validation message\r\n if (!found || this.isInvalid()) {\r\n this.#dropElement.classList.remove(\"show\");\r\n } else {\r\n // Or show it if necessary\r\n this.#dropElement.classList.add(\"show\");\r\n }\r\n }\r\n\r\n /**\r\n * The element create with buildSuggestions\r\n */\r\n #hideSuggestions() {\r\n this.#dropElement.classList.remove(\"show\");\r\n this.#holderElement.classList.remove(\"is-invalid\");\r\n this.removeActiveSelection();\r\n }\r\n\r\n /**\r\n * @returns {Number}\r\n */\r\n #getBootstrapVersion() {\r\n let ver = 5;\r\n // If we have jQuery and the tooltip plugin for BS4\r\n if (window.jQuery && $.fn.tooltip != undefined && $.fn.tooltip.Constructor != undefined) {\r\n ver = parseInt($.fn.tooltip.Constructor.VERSION.charAt(0));\r\n }\r\n return ver;\r\n }\r\n\r\n /**\r\n * Find if label is already selected (based on attribute)\r\n * @param {string} text\r\n * @returns {boolean}\r\n */\r\n #isSelected(text) {\r\n const opt = Array.from(this.#selectElement.querySelectorAll(\"option\")).find((el) => el.textContent == text);\r\n if (opt && opt.getAttribute(\"selected\")) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Checks if value matches a configured regex\r\n * @param {string} value\r\n * @returns {boolean}\r\n */\r\n #validateRegex(value) {\r\n const regex = new RegExp(this.validationRegex.trim());\r\n return regex.test(value);\r\n }\r\n\r\n /**\r\n * @returns {HTMLElement}\r\n */\r\n getActiveSelection() {\r\n return this.#dropElement.querySelector(\"a.\" + ACTIVE_CLASS);\r\n }\r\n\r\n removeActiveSelection() {\r\n let selection = this.getActiveSelection();\r\n if (selection) {\r\n selection.classList.remove(...ACTIVE_CLASSES);\r\n }\r\n }\r\n\r\n removeAll() {\r\n let items = this.getSelectedValues();\r\n items.forEach((item) => {\r\n this.removeItem(item);\r\n });\r\n this.#adjustWidth();\r\n }\r\n\r\n /**\r\n * @param {boolean} noEvents\r\n */\r\n removeLastItem(noEvents) {\r\n if (noEvents) {\r\n this.#fireEvents = false;\r\n }\r\n let items = this.#containerElement.querySelectorAll(\"span\");\r\n if (!items.length) {\r\n return;\r\n }\r\n let lastItem = items[items.length - 1];\r\n this.removeItem(lastItem.getAttribute(VALUE_ATTRIBUTE));\r\n this.#fireEvents = true;\r\n }\r\n\r\n /**\r\n * @returns {boolean}\r\n */\r\n isDisabled() {\r\n return this.#selectElement.hasAttribute(\"disabled\") || this.#selectElement.disabled || this.#selectElement.hasAttribute(\"readonly\");\r\n }\r\n\r\n /**\r\n * @returns {boolean}\r\n */\r\n isInvalid() {\r\n return this.#holderElement.classList.contains(\"is-invalid\");\r\n }\r\n\r\n /**\r\n * @returns {boolean}\r\n */\r\n isSingle() {\r\n return !this.#selectElement.hasAttribute(\"multiple\");\r\n }\r\n\r\n /**\r\n * @param {string} text\r\n * @returns {boolean}\r\n */\r\n canAdd(text) {\r\n if (!text) {\r\n return false;\r\n }\r\n // Check for max\r\n if (this.max && this.getSelectedValues().length >= this.max) {\r\n return false;\r\n }\r\n // Check for regex\r\n if (this.validationRegex && !this.#validateRegex(text)) {\r\n this.#holderElement.classList.add(\"is-invalid\");\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * You might want to use canAdd before to ensure the item is valid\r\n * @param {string} text\r\n * @param {string} value\r\n * @param {object} data\r\n */\r\n addItem(text, value = null, data = {}) {\r\n if (!value) {\r\n value = text;\r\n }\r\n\r\n // Single items remove first\r\n if (this.isSingle() && this.getSelectedValues().length) {\r\n this.removeLastItem(true);\r\n }\r\n\r\n const bver = this.#getBootstrapVersion();\r\n let opt = this.#selectElement.querySelector('option[value=\"' + value + '\"]');\r\n if (opt) {\r\n data = opt.dataset;\r\n }\r\n\r\n // create span\r\n let html = text;\r\n let span = document.createElement(\"span\");\r\n let classes = [\"badge\"];\r\n let badgeStyle = this.badgeStyle;\r\n if (data.badgeStyle) {\r\n badgeStyle = data.badgeStyle;\r\n }\r\n if (data.badgeClass) {\r\n classes.push(data.badgeClass);\r\n }\r\n if (bver === 5) {\r\n //https://getbootstrap.com/docs/5.1/components/badge/\r\n classes = [...classes, ...[\"me-2\", \"bg-\" + badgeStyle]];\r\n } else {\r\n // https://getbootstrap.com/docs/4.6/components/badge/\r\n classes = [...classes, ...[\"mr-2\", \"badge-\" + badgeStyle]];\r\n }\r\n span.classList.add(...classes);\r\n span.setAttribute(VALUE_ATTRIBUTE, value);\r\n\r\n if (this.allowClear) {\r\n const btn =\r\n bver === 5\r\n ? ''\r\n : '';\r\n html = btn + html;\r\n }\r\n\r\n span.innerHTML = html;\r\n this.#containerElement.insertBefore(span, this.#searchInput);\r\n\r\n if (this.allowClear) {\r\n span.querySelector(\"button\").addEventListener(\"click\", (event) => {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n if (!this.isDisabled()) {\r\n this.removeItem(value);\r\n document.activeElement.blur();\r\n this.#adjustWidth();\r\n }\r\n });\r\n }\r\n\r\n // we need to create a new option\r\n if (!opt) {\r\n opt = document.createElement(\"option\");\r\n opt.value = value;\r\n opt.innerText = text;\r\n // Pass along data provided\r\n for (const [key, value] of Object.entries(data)) {\r\n opt.dataset[key] = value;\r\n }\r\n this.#selectElement.appendChild(opt);\r\n }\r\n\r\n // update select, we need to set attribute for option[selected]\r\n opt.setAttribute(\"selected\", \"selected\");\r\n opt.selected = true;\r\n\r\n // Fire change event\r\n if (this.#fireEvents) {\r\n this.#selectElement.dispatchEvent(new Event(\"change\", { bubbles: true }));\r\n }\r\n }\r\n\r\n /**\r\n * @param {string} value\r\n */\r\n removeItem(value) {\r\n let item = this.#containerElement.querySelector(\"span[\" + VALUE_ATTRIBUTE + '=\"' + value + '\"]');\r\n if (!item) {\r\n return;\r\n }\r\n item.remove();\r\n\r\n // update select\r\n let opt = this.#selectElement.querySelector('option[value=\"' + value + '\"]');\r\n if (opt) {\r\n opt.removeAttribute(\"selected\");\r\n opt.selected = false;\r\n\r\n // Fire change event\r\n if (this.#fireEvents) {\r\n this.#selectElement.dispatchEvent(new Event(\"change\", { bubbles: true }));\r\n }\r\n }\r\n\r\n // Make input visible\r\n if (this.#searchInput.style.visibility == \"hidden\" && this.max && this.getSelectedValues().length < this.max) {\r\n this.#searchInput.style.visibility = \"visible\";\r\n }\r\n }\r\n}\r\n\r\nexport default Tags;\r\n", "import { Dropdown } from \"./node_modules/bootstrap.native/src/components/dropdown-native.js\";\r\nimport Tags from \"./tags.js\";\r\n\r\nexport default Tags;"], - "mappings": "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", + "sourcesContent": ["/**\n * Checks if an object is an `Element`.\n *\n * @param {any} element the target object\n * @returns {boolean} the query result\n */\nexport default function isElement(element) {\n return element instanceof Element;\n}\n", "import isElement from './isElement';\n\n/**\n * Utility to check if target is typeof `Element`\n * or find one that matches a selector.\n *\n * @param {Element | string} selector the input selector or target element\n * @param {Element=} parent optional Element to look into\n * @return {Element?} the Element or `querySelector` result\n */\nexport default function querySelector(selector, parent) {\n const lookUp = parent && isElement(parent) ? parent : document;\n // @ts-ignore -- `isElement` is just as good\n return isElement(selector) ? selector : lookUp.querySelector(selector);\n}\n", "import querySelector from './querySelector';\n\n/**\n * Utility to check if target is typeof `Element`\n * or find one that matches a selector.\n *\n * @deprecated\n *\n * @param {Element | string} selector the input selector or target element\n * @param {Element=} parent optional Element to look into\n * @return {Element?} the Element or `querySelector` result\n */\nexport default function queryElement(selector, parent) {\n return querySelector(selector, parent);\n}\n", "/**\n * A global namespace for 'addEventListener' string.\n * @type {string}\n */\nconst addEventListener = 'addEventListener';\nexport default addEventListener;\n", "/**\n * A global namespace for 'removeEventListener' string.\n * @type {string}\n */\nconst removeEventListener = 'removeEventListener';\nexport default removeEventListener;\n", "import addEventListener from '../strings/addEventListener.js';\nimport removeEventListener from '../strings/removeEventListener.js';\n\n/**\n * A global namespace for passive events support.\n * @type {boolean}\n */\nconst supportPassive = (() => {\n let result = false;\n try {\n const opts = Object.defineProperty({}, 'passive', {\n get() {\n result = true;\n return result;\n },\n });\n document[addEventListener]('DOMContentLoaded', function wrap() {\n document[removeEventListener]('DOMContentLoaded', wrap, opts);\n }, opts);\n } catch (e) {\n throw Error('Passive events are not supported');\n }\n\n return result;\n})();\n\nexport default supportPassive;\n", "// general event options\n// not suited for scroll prevention\n// https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md#feature-detection\nimport supportPassive from '../boolean/supportPassive';\n\n/**\n * A global namespace for most scroll event listeners.\n */\nconst passiveHandler = supportPassive ? { passive: true } : false;\n\nexport default passiveHandler;\n", "/**\n * Add class to Element.classList\n *\n * @param {Element} element target\n * @param {string} classNAME to add\n */\nexport default function addClass(element, classNAME) {\n element.classList.add(classNAME);\n}\n", "/**\n * Check class in Element.classList\n *\n * @param {Element} element target\n * @param {string} classNAME to check\n * @return {boolean}\n */\nexport default function hasClass(element, classNAME) {\n return element.classList.contains(classNAME);\n}\n", "/**\n * Remove class from Element.classList\n *\n * @param {Element} element target\n * @param {string} classNAME to remove\n */\nexport default function removeClass(element, classNAME) {\n element.classList.remove(classNAME);\n}\n", "const ariaExpanded = 'aria-expanded';\nexport default ariaExpanded;\n", "const showClass = 'show';\nexport default showClass;\n", "const dataBsToggle = 'data-bs-toggle';\nexport default dataBsToggle;\n", "const dropdownMenuClasses = ['dropdown', 'dropup', 'dropstart', 'dropend'];\nexport default dropdownMenuClasses;\n", "const dropdownMenuClass = 'dropdown-menu';\nexport default dropdownMenuClass;\n", "export default function bootstrapCustomEvent(namespacedEventType, eventProperties) {\n const OriginalCustomEvent = new CustomEvent(namespacedEventType, { cancelable: true });\n\n if (eventProperties instanceof Object) {\n Object.keys(eventProperties).forEach((key) => {\n Object.defineProperty(OriginalCustomEvent, key, {\n value: eventProperties[key],\n });\n });\n }\n return OriginalCustomEvent;\n}\n", "export default function isEmptyAnchor(elem) {\n const parentAnchor = elem.closest('A');\n // anchor href starts with #\n return elem && ((elem.hasAttribute('href') && elem.href.slice(-1) === '#')\n // OR a child of an anchor with href starts with #\n || (parentAnchor && parentAnchor.hasAttribute('href') && parentAnchor.href.slice(-1) === '#'));\n}\n", "export default function setFocus(element) {\n element.focus();\n}\n", "/**\n * The raw value or a given component option.\n *\n * @typedef {string | Element | Function | number | boolean | null} niceValue\n */\n\n/**\n * Utility to normalize component options\n *\n * @param {any} value the input value\n * @return {niceValue} the normalized value\n */\nexport default function normalizeValue(value) {\n if (value === 'true') { // boolean\n return true;\n }\n\n if (value === 'false') { // boolean\n return false;\n }\n\n if (!Number.isNaN(+value)) { // number\n return +value;\n }\n\n if (value === '' || value === 'null') { // null\n return null;\n }\n\n // string / function / Element / object\n return value;\n}\n", "/**\n * Shortcut for `Object.keys()` static method.\n * @param {Record} obj a target object\n * @returns {string[]}\n */\nconst ObjectKeys = (obj) => Object.keys(obj);\nexport default ObjectKeys;\n", "import normalizeValue from './normalizeValue';\nimport ObjectKeys from './ObjectKeys';\n\n/**\n * Utility to normalize component options\n *\n * @param {Element} element target\n * @param {Record} defaultOps component default options\n * @param {Record} inputOps component instance options\n * @param {string=} ns component namespace\n * @return {Record} normalized component options object\n */\nexport default function normalizeOptions(element, defaultOps, inputOps, ns) {\n // @ts-ignore -- usually our `Element` is `HTMLElement` as well\n const data = { ...element.dataset };\n const normalOps = {};\n const dataOps = {};\n\n ObjectKeys(data).forEach((k) => {\n const key = ns && k.includes(ns)\n ? k.replace(ns, '').replace(/[A-Z]/, (match) => match.toLowerCase())\n : k;\n\n dataOps[key] = normalizeValue(data[k]);\n });\n\n ObjectKeys(inputOps).forEach((k) => {\n inputOps[k] = normalizeValue(inputOps[k]);\n });\n\n ObjectKeys(defaultOps).forEach((k) => {\n if (k in inputOps) {\n normalOps[k] = inputOps[k];\n } else if (k in dataOps) {\n normalOps[k] = dataOps[k];\n } else {\n normalOps[k] = defaultOps[k];\n }\n });\n\n return normalOps;\n}\n", "/* Native JavaScript for Bootstrap 5 | Base Component\n----------------------------------------------------- */\n\nimport queryElement from 'shorter-js/src/misc/queryElement.js';\nimport normalizeOptions from 'shorter-js/src/misc/normalizeOptions.js';\n\nexport default class BaseComponent {\n constructor(name, target, defaults, config) {\n const self = this;\n const element = queryElement(target);\n\n if (element[name]) element[name].dispose();\n self.element = element;\n\n if (defaults && Object.keys(defaults).length) {\n self.options = normalizeOptions(element, defaults, (config || {}), 'bs');\n }\n element[name] = self;\n }\n\n dispose(name) {\n const self = this;\n self.element[name] = null;\n Object.keys(self).forEach((prop) => { self[prop] = null; });\n }\n}\n", "/* Native JavaScript for Bootstrap 5 | Dropdown\n----------------------------------------------- */\nimport queryElement from 'shorter-js/src/misc/queryElement.js';\nimport passiveHandler from 'shorter-js/src/misc/passiveHandler.js';\nimport addClass from 'shorter-js/src/class/addClass.js';\nimport hasClass from 'shorter-js/src/class/hasClass.js';\nimport removeClass from 'shorter-js/src/class/removeClass.js';\nimport addEventListener from 'shorter-js/src/strings/addEventListener.js';\nimport removeEventListener from 'shorter-js/src/strings/removeEventListener.js';\n\nimport ariaExpanded from '../strings/ariaExpanded.js';\nimport showClass from '../strings/showClass.js';\nimport dataBsToggle from '../strings/dataBsToggle.js';\nimport dropdownClasses from '../strings/dropdownClasses.js';\nimport dropdownMenuClass from '../strings/dropdownMenuClass.js';\n\nimport bootstrapCustomEvent from '../util/bootstrapCustomEvent.js';\nimport isEmptyAnchor from '../util/isEmptyAnchor.js';\nimport setFocus from '../util/setFocus.js';\nimport BaseComponent from './base-component.js';\n\n// DROPDOWN PRIVATE GC\n// ===================\nconst [dropdownString] = dropdownClasses;\nconst dropdownComponent = 'Dropdown';\nconst dropdownSelector = `[${dataBsToggle}=\"${dropdownString}\"]`;\n\n// DROPDOWN PRIVATE GC\n// ===================\nconst dropupString = dropdownClasses[1];\nconst dropstartString = dropdownClasses[2];\nconst dropendString = dropdownClasses[3];\nconst dropdownMenuEndClass = `${dropdownMenuClass}-end`;\nconst hideMenuClass = ['d-block', 'invisible'];\nconst verticalClass = [dropdownString, dropupString];\nconst horizontalClass = [dropstartString, dropendString];\nconst defaultDropdownOptions = {\n offset: 5, // [number] 5(px)\n display: 'dynamic', // [dynamic|static]\n};\n\n// DROPDOWN CUSTOM EVENTS\n// ========================\nconst showDropdownEvent = bootstrapCustomEvent(`show.bs.${dropdownString}`);\nconst shownDropdownEvent = bootstrapCustomEvent(`shown.bs.${dropdownString}`);\nconst hideDropdownEvent = bootstrapCustomEvent(`hide.bs.${dropdownString}`);\nconst hiddenDropdownEvent = bootstrapCustomEvent(`hidden.bs.${dropdownString}`);\n\n// DROPDOWN PRIVATE METHODS\n// ========================\nfunction styleDropdown(self, show) {\n const {\n element, menu, originalClass, menuEnd, options,\n } = self;\n const { offset } = options;\n const parent = element.parentElement;\n\n // reset menu offset and position\n const resetProps = ['margin', 'top', 'bottom', 'left', 'right'];\n resetProps.forEach((p) => { menu.style[p] = ''; });\n removeClass(parent, 'position-static');\n\n if (!show) {\n const menuEndNow = hasClass(menu, dropdownMenuEndClass);\n parent.className = originalClass.join(' ');\n if (menuEndNow && !menuEnd) removeClass(menu, dropdownMenuEndClass);\n else if (!menuEndNow && menuEnd) addClass(menu, dropdownMenuEndClass);\n return;\n }\n\n // set initial position class\n // take into account .btn-group parent as .dropdown\n let positionClass = dropdownClasses.find((c) => originalClass.includes(c)) || dropdownString;\n\n let dropdownMargin = {\n dropdown: [offset, 0, 0],\n dropup: [0, 0, offset],\n dropstart: [-1, offset, 0],\n dropend: [-1, 0, 0, offset],\n };\n\n const dropdownPosition = {\n dropdown: { top: '100%' },\n dropup: { top: 'auto', bottom: '100%' },\n dropstart: { left: 'auto', right: '100%' },\n dropend: { left: '100%', right: 'auto' },\n menuEnd: { right: 0, left: 'auto' },\n };\n\n // force showing the menu to calculate its size\n hideMenuClass.forEach((c) => addClass(menu, c));\n\n const dropdownRegex = new RegExp(`\\\\b(${dropdownString}|${dropupString}|${dropstartString}|${dropendString})+`);\n const elementDimensions = { w: element.offsetWidth, h: element.offsetHeight };\n const menuDimensions = { w: menu.offsetWidth, h: menu.offsetHeight };\n const HTML = document.documentElement;\n const BD = document.body;\n const windowWidth = (HTML.clientWidth || BD.clientWidth);\n const windowHeight = (HTML.clientHeight || BD.clientHeight);\n const targetBCR = element.getBoundingClientRect();\n // dropdownMenuEnd && [ dropdown | dropup ]\n const leftExceed = targetBCR.left + elementDimensions.w - menuDimensions.w < 0;\n // dropstart\n const leftFullExceed = targetBCR.left - menuDimensions.w < 0;\n // !dropdownMenuEnd && [ dropdown | dropup ]\n const rightExceed = targetBCR.left + menuDimensions.w >= windowWidth;\n // dropend\n const rightFullExceed = targetBCR.left + menuDimensions.w + elementDimensions.w >= windowWidth;\n // dropstart | dropend\n const bottomExceed = targetBCR.top + menuDimensions.h >= windowHeight;\n // dropdown\n const bottomFullExceed = targetBCR.top + menuDimensions.h + elementDimensions.h >= windowHeight;\n // dropup\n const topExceed = targetBCR.top - menuDimensions.h < 0;\n\n // recompute position\n if (horizontalClass.includes(positionClass) && leftFullExceed && rightFullExceed) {\n positionClass = dropdownString;\n }\n if (horizontalClass.includes(positionClass) && bottomExceed) {\n positionClass = dropupString;\n }\n if (positionClass === dropstartString && leftFullExceed && !bottomExceed) {\n positionClass = dropendString;\n }\n if (positionClass === dropendString && rightFullExceed && !bottomExceed) {\n positionClass = dropstartString;\n }\n if (positionClass === dropupString && topExceed && !bottomFullExceed) {\n positionClass = dropdownString;\n }\n if (positionClass === dropdownString && bottomFullExceed && !topExceed) {\n positionClass = dropupString;\n }\n\n // set spacing\n dropdownMargin = dropdownMargin[positionClass];\n menu.style.margin = `${dropdownMargin.map((x) => (x ? `${x}px` : x)).join(' ')}`;\n Object.keys(dropdownPosition[positionClass]).forEach((position) => {\n menu.style[position] = dropdownPosition[positionClass][position];\n });\n\n // update dropdown position class\n if (!hasClass(parent, positionClass)) {\n parent.className = parent.className.replace(dropdownRegex, positionClass);\n }\n\n // update dropdown / dropup to handle parent btn-group element\n // as well as the dropdown-menu-end utility class\n if (verticalClass.includes(positionClass)) {\n if (!menuEnd && rightExceed) addClass(menu, dropdownMenuEndClass);\n else if (menuEnd && leftExceed) removeClass(menu, dropdownMenuEndClass);\n\n if (hasClass(menu, dropdownMenuEndClass)) {\n Object.keys(dropdownPosition.menuEnd).forEach((p) => {\n menu.style[p] = dropdownPosition.menuEnd[p];\n });\n }\n }\n\n // remove util classes from the menu, we have its size\n hideMenuClass.forEach((c) => removeClass(menu, c));\n}\n\nfunction toggleDropdownDismiss(self) {\n const action = self.open ? addEventListener : removeEventListener;\n\n document[action]('click', dropdownDismissHandler);\n document[action]('focus', dropdownDismissHandler);\n document[action]('keydown', dropdownPreventScroll);\n document[action]('keyup', dropdownKeyHandler);\n\n if (self.options.display === 'dynamic') {\n window[action]('scroll', dropdownLayoutHandler, passiveHandler);\n window[action]('resize', dropdownLayoutHandler, passiveHandler);\n }\n}\n\nfunction toggleDropdownHandler(self, add) {\n const action = add ? addEventListener : removeEventListener;\n self.element[action]('click', dropdownClickHandler);\n}\n\nfunction getCurrentOpenDropdown() {\n const currentParent = dropdownClasses.concat('btn-group')\n .map((c) => document.getElementsByClassName(`${c} ${showClass}`))\n .find((x) => x.length);\n\n if (currentParent && currentParent.length) {\n return Array.from(currentParent[0].children).find((x) => x.hasAttribute(dataBsToggle));\n }\n return null;\n}\n\n// DROPDOWN EVENT HANDLERS\n// =======================\nfunction dropdownDismissHandler(e) {\n const { target, type } = e;\n if (!target.closest) return; // some weird FF bug #409\n\n const element = getCurrentOpenDropdown();\n const parent = element && element.parentNode;\n const self = element && element[dropdownComponent];\n const menu = self && self.menu;\n\n const hasData = target.closest(dropdownSelector) !== null;\n const isForm = parent && parent.contains(target)\n && (target.tagName === 'form' || target.closest('form') !== null);\n\n if (type === 'click' && isEmptyAnchor(target)) {\n e.preventDefault();\n }\n if (type === 'focus'\n && (target === element || target === menu || menu.contains(target))) {\n return;\n }\n\n if (isForm || hasData) {\n // smile to ESLint\n } else if (self) {\n self.hide(element);\n }\n}\n\nfunction dropdownClickHandler(e) {\n const element = this;\n const self = element[dropdownComponent];\n self.toggle(element);\n\n if (isEmptyAnchor(e.target)) e.preventDefault();\n}\n\nfunction dropdownPreventScroll(e) {\n if (e.which === 38 || e.which === 40) e.preventDefault();\n}\n\nfunction dropdownKeyHandler({ which }) {\n const element = getCurrentOpenDropdown();\n const self = element[dropdownComponent];\n const { menu, menuItems, open } = self;\n const activeItem = document.activeElement;\n const isSameElement = activeItem === element;\n const isInsideMenu = menu.contains(activeItem);\n const isMenuItem = activeItem.parentNode === menu || activeItem.parentNode.parentNode === menu;\n\n let idx = menuItems.indexOf(activeItem);\n\n if (isMenuItem) { // navigate up | down\n if (isSameElement) {\n idx = 0;\n } else if (which === 38) {\n idx = idx > 1 ? idx - 1 : 0;\n } else if (which === 40) {\n idx = idx < menuItems.length - 1 ? idx + 1 : idx;\n }\n\n if (menuItems[idx]) setFocus(menuItems[idx]);\n }\n\n if (((menuItems.length && isMenuItem) // menu has items\n || (!menuItems.length && (isInsideMenu || isSameElement)) // menu might be a form\n || !isInsideMenu) // or the focused element is not in the menu at all\n && open && which === 27 // menu must be open\n ) {\n self.toggle();\n }\n}\n\nfunction dropdownLayoutHandler() {\n const element = getCurrentOpenDropdown();\n const self = element && element[dropdownComponent];\n\n if (self && self.open) styleDropdown(self, 1);\n}\n\n// DROPDOWN DEFINITION\n// ===================\nexport default class Dropdown extends BaseComponent {\n constructor(target, config) {\n super(dropdownComponent, target, defaultDropdownOptions, config);\n // bind\n const self = this;\n\n // initialization element\n const { element } = self;\n\n // set targets\n const parent = element.parentElement;\n self.menu = queryElement(`.${dropdownMenuClass}`, parent);\n const { menu } = self;\n\n self.originalClass = Array.from(parent.classList);\n\n // set original position\n self.menuEnd = hasClass(menu, dropdownMenuEndClass);\n\n self.menuItems = [];\n\n Array.from(menu.children).forEach((child) => {\n if (child.children.length && (child.children[0].tagName === 'A')) self.menuItems.push(child.children[0]);\n if (child.tagName === 'A') self.menuItems.push(child);\n });\n\n // set initial state to closed\n self.open = false;\n\n // add event listener\n toggleDropdownHandler(self, 1);\n }\n\n // DROPDOWN PUBLIC METHODS\n // =======================\n toggle(related) {\n const self = this;\n const { open } = self;\n\n if (open) self.hide(related);\n else self.show(related);\n }\n\n show(related) {\n const self = this;\n const currentParent = queryElement(dropdownClasses.concat('btn-group').map((c) => `.${c}.${showClass}`).join(','));\n const currentElement = currentParent && queryElement(dropdownSelector, currentParent);\n\n if (currentElement) currentElement[dropdownComponent].hide();\n\n const { element, menu, open } = self;\n const parent = element.parentNode;\n\n // update relatedTarget and dispatch\n showDropdownEvent.relatedTarget = related || null;\n parent.dispatchEvent(showDropdownEvent);\n if (showDropdownEvent.defaultPrevented) return;\n\n // change menu position\n styleDropdown(self, 1);\n\n addClass(menu, showClass);\n addClass(parent, showClass);\n\n element.setAttribute(ariaExpanded, true);\n self.open = !open;\n\n setTimeout(() => {\n setFocus(menu.getElementsByTagName('INPUT')[0] || element); // focus the first input item | element\n toggleDropdownDismiss(self);\n\n shownDropdownEvent.relatedTarget = related || null;\n parent.dispatchEvent(shownDropdownEvent);\n }, 1);\n }\n\n hide(related) {\n const self = this;\n const { element, menu, open } = self;\n const parent = element.parentNode;\n hideDropdownEvent.relatedTarget = related || null;\n parent.dispatchEvent(hideDropdownEvent);\n if (hideDropdownEvent.defaultPrevented) return;\n\n removeClass(menu, showClass);\n removeClass(parent, showClass);\n\n // revert to original position\n styleDropdown(self);\n\n element.setAttribute(ariaExpanded, false);\n self.open = !open;\n\n setFocus(element);\n\n // only re-attach handler if the instance is not disposed\n setTimeout(() => toggleDropdownDismiss(self), 1);\n\n // update relatedTarget and dispatch\n hiddenDropdownEvent.relatedTarget = related || null;\n parent.dispatchEvent(hiddenDropdownEvent);\n }\n\n dispose() {\n const self = this;\n const { element } = self;\n\n if (hasClass(element.parentNode, showClass) && self.open) self.hide();\n\n toggleDropdownHandler(self);\n\n super.dispose(dropdownComponent);\n }\n}\n\nDropdown.init = {\n component: dropdownComponent,\n selector: dropdownSelector,\n constructor: Dropdown,\n};\n", "/**\r\n * Bootstrap 5 (and 4!) tags\r\n *\r\n * Turns your select[multiple] into nice tags lists\r\n *\r\n * Required Bootstrap 5 styles:\r\n * - badge\r\n * - background-color utility\r\n * - margin-end utility\r\n * - float-start utility\r\n * - forms\r\n * - dropdown\r\n */\r\n\r\nconst ACTIVE_CLASS = \"is-active\";\r\nconst ACTIVE_CLASSES = [\"is-active\", \"bg-primary\", \"text-white\"];\r\nconst VALUE_ATTRIBUTE = \"data-value\";\r\n\r\n// Static map will minify very badly as class prop, so we use an external constant\r\nconst INSTANCE_MAP = new WeakMap();\r\n\r\nclass Tags {\r\n #abortController;\r\n #selectElement;\r\n #holderElement;\r\n #containerElement;\r\n #dropElement;\r\n #searchInput;\r\n #keyboardNavigation;\r\n #fireEvents;\r\n\r\n /**\r\n * @param {HTMLSelectElement} el\r\n * @param {Object} globalOpts\r\n */\r\n constructor(el, globalOpts = {}) {\r\n // Hide the select element and register a tags attr\r\n el.style.display = \"none\";\r\n INSTANCE_MAP.set(el, this);\r\n this.#selectElement = el;\r\n\r\n // Allow 1/0, true/false as strings\r\n const parseBool = (value) => [\"true\", \"false\", \"1\", \"0\", true, false].includes(value) && !!JSON.parse(value);\r\n\r\n // Handle options, using global settings first and data attr override\r\n const opts = { ...globalOpts, ...el.dataset };\r\n this.allowNew = opts.allowNew ? parseBool(opts.allowNew) : false;\r\n this.showAllSuggestions = opts.showAllSuggestions ? parseBool(opts.showAllSuggestions) : false;\r\n this.badgeStyle = opts.badgeStyle || \"primary\";\r\n this.allowClear = opts.allowClear ? parseBool(opts.allowClear) : false;\r\n this.server = opts.server || false;\r\n this.liveServer = opts.liveServer ? parseBool(opts.liveServer) : false;\r\n this.serverParams = opts.serverParams || {};\r\n if (typeof this.serverParams == \"string\") {\r\n this.serverParams = JSON.parse(this.serverParams);\r\n }\r\n this.suggestionsThreshold = typeof opts.suggestionsThreshold != \"undefined\" ? parseInt(opts.suggestionsThreshold) : 1;\r\n this.validationRegex = opts.regex || \"\";\r\n this.separator = opts.separator ? opts.separator.split(\"|\") : [];\r\n this.max = opts.max ? parseInt(opts.max) : null;\r\n this.clearLabel = opts.clearLabel || \"Clear\";\r\n this.searchLabel = opts.searchLabel || \"Type a value\";\r\n\r\n this.placeholder = this.#getPlaceholder();\r\n this.#keyboardNavigation = false;\r\n this.#fireEvents = true;\r\n\r\n this.parentForm = el.parentElement;\r\n while (this.parentForm) {\r\n this.parentForm = this.parentForm.parentElement;\r\n if (this.parentForm && this.parentForm.nodeName == \"FORM\") {\r\n break;\r\n }\r\n }\r\n this.reset = this.reset.bind(this);\r\n if (this.parentForm) {\r\n this.parentForm.addEventListener(\"reset\", this.reset);\r\n }\r\n\r\n // Create elements\r\n this.#holderElement = document.createElement(\"div\"); // this is the one holding the fake input and the dropmenu\r\n this.#containerElement = document.createElement(\"div\"); // this is the one for the fake input (labels + input)\r\n this.#dropElement = document.createElement(\"ul\");\r\n this.#searchInput = document.createElement(\"input\");\r\n\r\n this.#holderElement.appendChild(this.#containerElement);\r\n this.#containerElement.appendChild(this.#searchInput);\r\n this.#holderElement.appendChild(this.#dropElement);\r\n // insert after\r\n this.#selectElement.parentNode.insertBefore(this.#holderElement, this.#selectElement.nextSibling);\r\n\r\n // Configure them\r\n this.#configureHolderElement();\r\n this.#configureDropElement();\r\n this.#configureContainerElement();\r\n this.#configureSearchInput();\r\n this.resetState();\r\n\r\n if (this.server && !this.liveServer) {\r\n this.#loadFromServer();\r\n } else {\r\n this.resetSuggestions();\r\n }\r\n }\r\n\r\n /**\r\n * Attach to all elements matched by the selector\r\n * @param {string} selector\r\n * @param {Object} opts\r\n */\r\n static init(selector = \"select[multiple]\", opts = {}) {\r\n let list = document.querySelectorAll(selector);\r\n for (let i = 0; i < list.length; i++) {\r\n if (Tags.getInstance(list[i])) {\r\n continue;\r\n }\r\n new Tags(list[i], opts);\r\n }\r\n }\r\n\r\n /**\r\n * @param {HTMLSelectElement} el\r\n */\r\n static getInstance(el) {\r\n if (INSTANCE_MAP.has(el)) {\r\n return INSTANCE_MAP.get(el);\r\n }\r\n }\r\n\r\n dispose() {\r\n INSTANCE_MAP.delete(this.#selectElement);\r\n this.#selectElement.style.display = \"block\";\r\n this.#holderElement.parentNode.removeChild(this.#holderElement);\r\n if (this.parentForm) {\r\n this.parentForm.removeEventListener(\"reset\", this.reset);\r\n }\r\n }\r\n\r\n resetState() {\r\n if (this.isDisabled()) {\r\n this.#holderElement.setAttribute(\"readonly\", \"\");\r\n this.#searchInput.setAttribute(\"disabled\", \"\");\r\n } else {\r\n if (this.#holderElement.hasAttribute(\"readonly\")) {\r\n this.#holderElement.removeAttribute(\"readonly\");\r\n }\r\n if (this.#searchInput.hasAttribute(\"disabled\")) {\r\n this.#searchInput.removeAttribute(\"disabled\");\r\n }\r\n }\r\n }\r\n\r\n resetSuggestions() {\r\n let suggestions = Array.from(this.#selectElement.querySelectorAll(\"option\"))\r\n .filter((option) => {\r\n return !option.disabled;\r\n })\r\n .map((option) => {\r\n return {\r\n value: option.getAttribute(\"value\"),\r\n label: option.textContent,\r\n };\r\n });\r\n this.#buildSuggestions(suggestions);\r\n }\r\n\r\n /**\r\n * @param {boolean} show\r\n */\r\n #loadFromServer(show = false) {\r\n if (this.#abortController) {\r\n this.#abortController.abort();\r\n }\r\n this.#abortController = new AbortController();\r\n\r\n this.serverParams.query = this.#searchInput.value;\r\n const params = new URLSearchParams(this.serverParams).toString();\r\n\r\n fetch(this.server + \"?\" + params, { signal: this.#abortController.signal })\r\n .then((r) => r.json())\r\n .then((suggestions) => {\r\n let data = suggestions.data || suggestions;\r\n this.#buildSuggestions(data);\r\n this.#abortController = null;\r\n if (show) {\r\n this.#showSuggestions();\r\n }\r\n })\r\n .catch((e) => {\r\n if (e.name === \"AbortError\") {\r\n return;\r\n }\r\n console.error(e);\r\n });\r\n }\r\n\r\n /**\r\n * @returns {string}\r\n */\r\n #getPlaceholder() {\r\n // Use placeholder and data-placeholder in priority\r\n if (this.#selectElement.hasAttribute(\"placeholder\")) {\r\n return this.#selectElement.getAttribute(\"placeholder\");\r\n }\r\n if (this.#selectElement.dataset.placeholder) {\r\n return this.#selectElement.dataset.placeholder;\r\n }\r\n // Fallback to first option if no value\r\n let firstOption = this.#selectElement.querySelector(\"option\");\r\n if (!firstOption) {\r\n return \"\";\r\n }\r\n if (firstOption.hasAttribute(\"selected\")) {\r\n firstOption.removeAttribute(\"selected\");\r\n }\r\n return !firstOption.value ? firstOption.textContent : \"\";\r\n }\r\n\r\n #configureDropElement() {\r\n this.#dropElement.classList.add(...[\"dropdown-menu\", \"p-0\"]);\r\n this.#dropElement.style.maxHeight = \"280px\";\r\n this.#dropElement.style.overflowY = \"auto\";\r\n\r\n // If the mouse was outside, entering remove keyboard nav mode\r\n this.#dropElement.addEventListener(\"mouseenter\", (event) => {\r\n this.#keyboardNavigation = false;\r\n });\r\n }\r\n\r\n #configureHolderElement() {\r\n this.#holderElement.classList.add(...[\"form-control\", \"dropdown\"]);\r\n if (this.#getBootstrapVersion() === 4) {\r\n // Prevent fixed height due to form-control\r\n this.#holderElement.style.height = \"auto\";\r\n }\r\n }\r\n\r\n #configureContainerElement() {\r\n this.#containerElement.addEventListener(\"click\", (event) => {\r\n if (this.isDisabled()) {\r\n return;\r\n }\r\n if (this.#searchInput.style.visibility != \"hidden\") {\r\n this.#searchInput.focus();\r\n }\r\n });\r\n\r\n // add initial values\r\n // we use selectedOptions because single select can have a selected option\r\n // without a selected attribute if it's the first value\r\n let initialValues = this.#selectElement.selectedOptions;\r\n for (let j = 0; j < initialValues.length; j++) {\r\n let initialValue = initialValues[j];\r\n if (!initialValue.value) {\r\n continue;\r\n }\r\n // track initial values for reset\r\n initialValue.dataset.init = 1;\r\n this.addItem(initialValue.textContent, initialValue.value);\r\n }\r\n }\r\n\r\n #configureSearchInput() {\r\n this.#searchInput.type = \"text\";\r\n this.#searchInput.autocomplete = \"off\";\r\n this.#searchInput.spellcheck = false;\r\n this.#searchInput.style.backgroundColor = \"transparent\";\r\n this.#searchInput.style.border = 0;\r\n this.#searchInput.style.outline = 0;\r\n this.#searchInput.style.maxWidth = \"100%\";\r\n this.#searchInput.ariaLabel = this.searchLabel;\r\n this.#resetSearchInput(true);\r\n\r\n this.#searchInput.addEventListener(\"input\", (event) => {\r\n // Add item if a separator is used\r\n // On mobile or copy paste, it can pass multiple chars (eg: when pressing space and it formats the string)\r\n if (event.data) {\r\n const lastChar = event.data.slice(-1);\r\n if (this.separator.length && this.#searchInput.value && this.separator.includes(lastChar)) {\r\n // Remove separator even if adding is prevented\r\n this.#searchInput.value = this.#searchInput.value.slice(0, -1);\r\n let text = this.#searchInput.value;\r\n if (!this.canAdd(text)) {\r\n return;\r\n }\r\n this.addItem(text, null);\r\n this.#resetSearchInput();\r\n return;\r\n }\r\n }\r\n\r\n // Adjust input width to current content\r\n this.#adjustWidth();\r\n\r\n // Check if we should display suggestions\r\n if (this.#searchInput.value.length >= this.suggestionsThreshold) {\r\n if (this.liveServer) {\r\n this.#loadFromServer(true);\r\n } else {\r\n this.#showSuggestions();\r\n }\r\n } else {\r\n this.#hideSuggestions();\r\n }\r\n });\r\n this.#searchInput.addEventListener(\"focus\", (event) => {\r\n if (this.#searchInput.value.length >= this.suggestionsThreshold) {\r\n this.#showSuggestions();\r\n }\r\n });\r\n this.#searchInput.addEventListener(\"focusout\", (event) => {\r\n this.#hideSuggestions();\r\n });\r\n // keypress doesn't send arrow keys, so we use keydown\r\n this.#searchInput.addEventListener(\"keydown\", (event) => {\r\n // Keycode reference : https://css-tricks.com/snippets/javascript/javascript-keycodes/\r\n let key = event.keyCode || event.key;\r\n\r\n // Keyboard keys\r\n switch (key) {\r\n case 13:\r\n case \"Enter\":\r\n event.preventDefault();\r\n let selection = this.getActiveSelection();\r\n if (selection) {\r\n selection.click();\r\n } else {\r\n // We use what is typed if not selected and not empty\r\n if (this.allowNew && this.#searchInput.value) {\r\n let text = this.#searchInput.value;\r\n if (!this.canAdd(text)) {\r\n return;\r\n }\r\n this.addItem(text, null);\r\n this.#resetSearchInput();\r\n }\r\n }\r\n break;\r\n case 38:\r\n case \"ArrowUp\":\r\n event.preventDefault();\r\n this.#keyboardNavigation = true;\r\n let newSelection = this.#moveSelectionUp();\r\n // If we use arrow up without input and there is no new selection, hide suggestions\r\n if (this.#searchInput.value.length == 0 && this.#dropElement.classList.contains(\"show\") && !newSelection) {\r\n this.#hideSuggestions();\r\n }\r\n break;\r\n case 40:\r\n case \"ArrowDown\":\r\n event.preventDefault();\r\n this.#keyboardNavigation = true;\r\n this.#moveSelectionDown();\r\n // If we use arrow down without input, show suggestions\r\n if (this.#searchInput.value.length == 0 && !this.#dropElement.classList.contains(\"show\")) {\r\n this.#showSuggestions();\r\n }\r\n break;\r\n case 8:\r\n case \"Backspace\":\r\n if (this.#searchInput.value.length == 0) {\r\n this.removeLastItem();\r\n this.#adjustWidth();\r\n this.#hideSuggestions();\r\n }\r\n break;\r\n case 27:\r\n case \"Escape\":\r\n // We may wish to not use the suggestions\r\n this.#hideSuggestions();\r\n break;\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * @returns {HTMLElement}\r\n */\r\n #moveSelectionUp() {\r\n let active = this.getActiveSelection();\r\n if (active) {\r\n let prev = active.parentNode;\r\n do {\r\n prev = prev.previousSibling;\r\n } while (prev && prev.style.display == \"none\");\r\n if (!prev) {\r\n return null;\r\n }\r\n active.classList.remove(...ACTIVE_CLASSES);\r\n prev.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n // Don't use scrollIntoView as it scrolls the whole window\r\n prev.parentNode.scrollTop = prev.offsetTop - prev.parentNode.offsetTop;\r\n return prev;\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * @returns {HTMLElement}\r\n */\r\n #moveSelectionDown() {\r\n let active = this.getActiveSelection();\r\n let next = null;\r\n if (active) {\r\n next = active.parentNode;\r\n do {\r\n next = next.nextSibling;\r\n } while (next && next.style.display == \"none\");\r\n if (!next) {\r\n return null;\r\n }\r\n active.classList.remove(...ACTIVE_CLASSES);\r\n next.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n // This is the equivalent of scrollIntoView(false) but only for parent node\r\n if (next.offsetTop > next.parentNode.offsetHeight - next.offsetHeight) {\r\n next.parentNode.scrollTop += next.offsetHeight;\r\n }\r\n return next;\r\n }\r\n return next;\r\n }\r\n\r\n /**\r\n * Adjust the field to fit its content and show/hide placeholder if needed\r\n */\r\n #adjustWidth() {\r\n if (this.#searchInput.value) {\r\n this.#searchInput.size = this.#searchInput.value.length + 1;\r\n } else {\r\n // Show the placeholder only if empty\r\n if (this.getSelectedValues().length) {\r\n this.#searchInput.placeholder = \"\";\r\n this.#searchInput.size = 1;\r\n } else {\r\n this.#searchInput.size = this.placeholder.length > 0 ? this.placeholder.length : 1;\r\n this.#searchInput.placeholder = this.placeholder;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Add suggestions to the drop element\r\n * @param {array}\r\n */\r\n #buildSuggestions(suggestions = null) {\r\n while (this.#dropElement.lastChild) {\r\n this.#dropElement.removeChild(this.#dropElement.lastChild);\r\n }\r\n for (let i = 0; i < suggestions.length; i++) {\r\n let suggestion = suggestions[i];\r\n if (!suggestion.value) {\r\n continue;\r\n }\r\n let newChild = document.createElement(\"li\");\r\n let newChildLink = document.createElement(\"a\");\r\n newChild.append(newChildLink);\r\n newChildLink.classList.add(\"dropdown-item\");\r\n newChildLink.setAttribute(VALUE_ATTRIBUTE, suggestion.value);\r\n newChildLink.setAttribute(\"href\", \"#\");\r\n newChildLink.textContent = suggestion.label;\r\n if (suggestion.data) {\r\n for (const [key, value] of Object.entries(suggestion.data)) {\r\n newChildLink.dataset[key] = value;\r\n }\r\n }\r\n this.#dropElement.appendChild(newChild);\r\n\r\n // Hover sets active item\r\n newChildLink.addEventListener(\"mouseenter\", (event) => {\r\n // Don't trigger enter if using arrows\r\n if (this.#keyboardNavigation) {\r\n return;\r\n }\r\n this.removeActiveSelection();\r\n newChild.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n });\r\n // Moving the mouse means no longer using keyboard\r\n newChildLink.addEventListener(\"mousemove\", (event) => {\r\n this.#keyboardNavigation = false;\r\n });\r\n\r\n newChildLink.addEventListener(\"mousedown\", (event) => {\r\n // Otherwise searchInput would lose focus and close the menu\r\n event.preventDefault();\r\n });\r\n newChildLink.addEventListener(\"click\", (event) => {\r\n event.preventDefault();\r\n let text = newChildLink.textContent;\r\n if (!this.canAdd(text, newChildLink.getAttribute(VALUE_ATTRIBUTE))) {\r\n return;\r\n }\r\n this.addItem(text, newChildLink.getAttribute(VALUE_ATTRIBUTE), newChildLink.dataset);\r\n this.#resetSearchInput();\r\n });\r\n }\r\n }\r\n\r\n reset() {\r\n this.removeAll();\r\n\r\n // Reset doesn't fire change event\r\n this.#fireEvents = false;\r\n let initialValues = this.#selectElement.querySelectorAll(\"option[data-init]\");\r\n for (let j = 0; j < initialValues.length; j++) {\r\n let initialValue = initialValues[j];\r\n this.addItem(initialValue.textContent, initialValue.value);\r\n }\r\n this.#adjustWidth();\r\n this.#fireEvents = true;\r\n }\r\n\r\n #resetSearchInput(init = false) {\r\n this.#searchInput.value = \"\";\r\n this.#adjustWidth();\r\n\r\n if (!init) {\r\n this.#hideSuggestions();\r\n // Trigger input even to show suggestions if needed\r\n this.#searchInput.dispatchEvent(new Event(\"input\"));\r\n }\r\n\r\n // We use visibility instead of display to keep layout intact\r\n if (this.max && this.getSelectedValues().length === this.max) {\r\n this.#searchInput.style.visibility = \"hidden\";\r\n } else if (this.#searchInput.style.visibility == \"hidden\") {\r\n this.#searchInput.style.visibility = \"visible\";\r\n }\r\n\r\n if (this.isSingle() && !init) {\r\n document.activeElement.blur();\r\n }\r\n }\r\n\r\n /**\r\n * @returns {array}\r\n */\r\n getSelectedValues() {\r\n // option[selected] is used rather that selectedOptions as it works more consistently\r\n let selected = this.#selectElement.querySelectorAll(\"option[selected]\");\r\n return Array.from(selected).map((el) => el.value);\r\n }\r\n\r\n /**\r\n * The element create with buildSuggestions\r\n */\r\n #showSuggestions() {\r\n if (this.#searchInput.style.visibility == \"hidden\") {\r\n return;\r\n }\r\n\r\n // Position next to search input\r\n this.#dropElement.style.left = this.#searchInput.offsetLeft + \"px\";\r\n\r\n // Get search value\r\n let search = this.#searchInput.value.toLocaleLowerCase();\r\n\r\n // Get current values\r\n let values = this.getSelectedValues();\r\n\r\n // Filter the list according to search string\r\n let list = this.#dropElement.querySelectorAll(\"li\");\r\n let found = false;\r\n let firstItem = null;\r\n let hasPossibleValues = false;\r\n for (let i = 0; i < list.length; i++) {\r\n let item = list[i];\r\n let text = item.textContent.toLocaleLowerCase();\r\n let link = item.querySelector(\"a\");\r\n\r\n // Remove previous selection\r\n link.classList.remove(...ACTIVE_CLASSES);\r\n\r\n // Hide selected values\r\n if (values.indexOf(link.getAttribute(VALUE_ATTRIBUTE)) != -1) {\r\n item.style.display = \"none\";\r\n continue;\r\n }\r\n\r\n hasPossibleValues = true;\r\n\r\n // Check search length since we can trigger dropdown with arrow\r\n let isMatched = search.length === 0 || text.indexOf(search) !== -1;\r\n if (this.showAllSuggestions || this.suggestionsThreshold === 0 || isMatched) {\r\n item.style.display = \"list-item\";\r\n found = true;\r\n if (!firstItem && isMatched) {\r\n firstItem = item;\r\n }\r\n } else {\r\n item.style.display = \"none\";\r\n }\r\n }\r\n\r\n // Always select first item\r\n if (firstItem) {\r\n this.#holderElement.classList.remove(\"is-invalid\");\r\n firstItem.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n firstItem.parentNode.scrollTop = firstItem.offsetTop - firstItem.parentNode.offsetTop;\r\n } else {\r\n // No item and we don't allow new items => error\r\n if (!this.allowNew && !(search.length === 0 && !hasPossibleValues)) {\r\n this.#holderElement.classList.add(\"is-invalid\");\r\n } else if (this.validationRegex && this.isInvalid()) {\r\n this.#holderElement.classList.remove(\"is-invalid\");\r\n }\r\n }\r\n\r\n // Remove dropdown if not found or to show validation message\r\n if (!found || this.isInvalid()) {\r\n this.#dropElement.classList.remove(\"show\");\r\n } else {\r\n // Or show it if necessary\r\n this.#dropElement.classList.add(\"show\");\r\n }\r\n }\r\n\r\n /**\r\n * The element create with buildSuggestions\r\n */\r\n #hideSuggestions() {\r\n this.#dropElement.classList.remove(\"show\");\r\n this.#holderElement.classList.remove(\"is-invalid\");\r\n this.removeActiveSelection();\r\n }\r\n\r\n /**\r\n * @returns {Number}\r\n */\r\n #getBootstrapVersion() {\r\n let ver = 5;\r\n // If we have jQuery and the tooltip plugin for BS4\r\n if (window.jQuery && $.fn.tooltip != undefined && $.fn.tooltip.Constructor != undefined) {\r\n ver = parseInt($.fn.tooltip.Constructor.VERSION.charAt(0));\r\n }\r\n return ver;\r\n }\r\n\r\n /**\r\n * Find if label is already selected (based on attribute)\r\n * @param {string} text\r\n * @returns {boolean}\r\n */\r\n #isSelected(text) {\r\n const opt = Array.from(this.#selectElement.querySelectorAll(\"option\")).find((el) => el.textContent == text);\r\n if (opt && opt.getAttribute(\"selected\")) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Checks if value matches a configured regex\r\n * @param {string} value\r\n * @returns {boolean}\r\n */\r\n #validateRegex(value) {\r\n const regex = new RegExp(this.validationRegex.trim());\r\n return regex.test(value);\r\n }\r\n\r\n /**\r\n * @returns {HTMLElement}\r\n */\r\n getActiveSelection() {\r\n return this.#dropElement.querySelector(\"a.\" + ACTIVE_CLASS);\r\n }\r\n\r\n removeActiveSelection() {\r\n let selection = this.getActiveSelection();\r\n if (selection) {\r\n selection.classList.remove(...ACTIVE_CLASSES);\r\n }\r\n }\r\n\r\n removeAll() {\r\n let items = this.getSelectedValues();\r\n items.forEach((item) => {\r\n this.removeItem(item);\r\n });\r\n this.#adjustWidth();\r\n }\r\n\r\n /**\r\n * @param {boolean} noEvents\r\n */\r\n removeLastItem(noEvents) {\r\n if (noEvents) {\r\n this.#fireEvents = false;\r\n }\r\n let items = this.#containerElement.querySelectorAll(\"span\");\r\n if (!items.length) {\r\n return;\r\n }\r\n let lastItem = items[items.length - 1];\r\n this.removeItem(lastItem.getAttribute(VALUE_ATTRIBUTE));\r\n this.#fireEvents = true;\r\n }\r\n\r\n /**\r\n * @returns {boolean}\r\n */\r\n isDisabled() {\r\n return this.#selectElement.hasAttribute(\"disabled\") || this.#selectElement.disabled || this.#selectElement.hasAttribute(\"readonly\");\r\n }\r\n\r\n /**\r\n * @returns {boolean}\r\n */\r\n isInvalid() {\r\n return this.#holderElement.classList.contains(\"is-invalid\");\r\n }\r\n\r\n /**\r\n * @returns {boolean}\r\n */\r\n isSingle() {\r\n return !this.#selectElement.hasAttribute(\"multiple\");\r\n }\r\n\r\n /**\r\n * @param {string} text\r\n * @param {string} value\r\n * @returns {boolean}\r\n */\r\n canAdd(text, value = null) {\r\n if (!value) {\r\n value = text;\r\n }\r\n\r\n // Check invalid input\r\n if (!text) {\r\n return false;\r\n }\r\n // Check disabled\r\n if (this.isDisabled()) {\r\n return false;\r\n }\r\n // Check already selected input (single will replace)\r\n if (!this.isSingle() && this.#isSelected(value)) {\r\n return false;\r\n }\r\n // Check for max\r\n if (this.max && this.getSelectedValues().length >= this.max) {\r\n return false;\r\n }\r\n // Check for regex\r\n if (this.validationRegex && !this.#validateRegex(text)) {\r\n this.#holderElement.classList.add(\"is-invalid\");\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * You might want to use canAdd before to ensure the item is valid\r\n * @param {string} text\r\n * @param {string} value\r\n * @param {object} data\r\n */\r\n addItem(text, value = null, data = {}) {\r\n if (!value) {\r\n value = text;\r\n }\r\n\r\n // Single items remove first\r\n if (this.isSingle() && this.getSelectedValues().length) {\r\n this.removeLastItem(true);\r\n }\r\n\r\n const bver = this.#getBootstrapVersion();\r\n let opt = this.#selectElement.querySelector('option[value=\"' + value + '\"]');\r\n if (opt) {\r\n data = opt.dataset;\r\n }\r\n\r\n // create span\r\n let html = text;\r\n let span = document.createElement(\"span\");\r\n let classes = [\"badge\"];\r\n let badgeStyle = this.badgeStyle;\r\n if (data.badgeStyle) {\r\n badgeStyle = data.badgeStyle;\r\n }\r\n if (data.badgeClass) {\r\n classes.push(data.badgeClass);\r\n }\r\n if (bver === 5) {\r\n //https://getbootstrap.com/docs/5.1/components/badge/\r\n classes = [...classes, ...[\"me-2\", \"bg-\" + badgeStyle]];\r\n } else {\r\n // https://getbootstrap.com/docs/4.6/components/badge/\r\n classes = [...classes, ...[\"mr-2\", \"badge-\" + badgeStyle]];\r\n }\r\n span.classList.add(...classes);\r\n span.setAttribute(VALUE_ATTRIBUTE, value);\r\n\r\n if (this.allowClear) {\r\n const btn =\r\n bver === 5\r\n ? ''\r\n : '';\r\n html = btn + html;\r\n }\r\n\r\n span.innerHTML = html;\r\n this.#containerElement.insertBefore(span, this.#searchInput);\r\n\r\n if (this.allowClear) {\r\n span.querySelector(\"button\").addEventListener(\"click\", (event) => {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n if (!this.isDisabled()) {\r\n this.removeItem(value);\r\n document.activeElement.blur();\r\n this.#adjustWidth();\r\n }\r\n });\r\n }\r\n\r\n // we need to create a new option\r\n if (!opt) {\r\n opt = document.createElement(\"option\");\r\n opt.value = value;\r\n opt.textContent = text; // innerText is not well supported by jsdom\r\n // Pass along data provided\r\n for (const [key, value] of Object.entries(data)) {\r\n opt.dataset[key] = value;\r\n }\r\n this.#selectElement.appendChild(opt);\r\n }\r\n\r\n // update select, we need to set attribute for option[selected]\r\n opt.setAttribute(\"selected\", \"selected\");\r\n opt.selected = true;\r\n\r\n // Fire change event\r\n if (this.#fireEvents) {\r\n this.#selectElement.dispatchEvent(new Event(\"change\", { bubbles: true }));\r\n }\r\n }\r\n\r\n /**\r\n * @param {string} value\r\n */\r\n removeItem(value) {\r\n let item = this.#containerElement.querySelector(\"span[\" + VALUE_ATTRIBUTE + '=\"' + value + '\"]');\r\n if (!item) {\r\n return;\r\n }\r\n item.remove();\r\n\r\n // update select\r\n let opt = this.#selectElement.querySelector('option[value=\"' + value + '\"]');\r\n if (opt) {\r\n opt.removeAttribute(\"selected\");\r\n opt.selected = false;\r\n\r\n // Fire change event\r\n if (this.#fireEvents) {\r\n this.#selectElement.dispatchEvent(new Event(\"change\", { bubbles: true }));\r\n }\r\n }\r\n\r\n // Make input visible\r\n if (this.#searchInput.style.visibility == \"hidden\" && this.max && this.getSelectedValues().length < this.max) {\r\n this.#searchInput.style.visibility = \"visible\";\r\n }\r\n }\r\n}\r\n\r\nexport default Tags;\r\n", "import { Dropdown } from \"./node_modules/bootstrap.native/src/components/dropdown-native.js\";\r\nimport Tags from \"./tags.js\";\r\n\r\nexport default Tags;"], + "mappings": "AAMe,WAAmB,EAAS,CACzC,MAAO,aAAmB,SCGb,WAAuB,EAAU,EAAQ,CACtD,GAAM,GAAS,GAAU,EAAU,GAAU,EAAS,SAEtD,MAAO,GAAU,GAAY,EAAW,EAAO,cAAc,GCDhD,WAAsB,EAAU,EAAQ,CACrD,MAAO,GAAc,EAAU,GCTjC,GAAM,IAAmB,mBAClB,EAAQ,GCDf,GAAM,IAAsB,sBACrB,EAAQ,GCEf,GAAM,IAAkB,KAAM,CAC5B,GAAI,GAAS,GACb,GAAI,CACF,GAAM,GAAO,OAAO,eAAe,GAAI,UAAW,CAChD,KAAM,CACJ,SAAS,GACF,KAGX,SAAS,GAAkB,mBAAoB,YAAgB,CAC7D,SAAS,GAAqB,mBAAoB,EAAM,IACvD,QACH,CACA,KAAM,OAAM,oCAGd,MAAO,OAGF,GAAQ,GClBf,GAAM,IAAiB,GAAiB,CAAE,QAAS,IAAS,GAErD,EAAQ,GCJA,WAAkB,EAAS,EAAW,CACnD,EAAQ,UAAU,IAAI,GCAT,WAAkB,EAAS,EAAW,CACnD,MAAO,GAAQ,UAAU,SAAS,GCFrB,WAAqB,EAAS,EAAW,CACtD,EAAQ,UAAU,OAAO,GCP3B,GAAM,IAAe,gBACd,EAAQ,GCDf,GAAM,IAAY,OACX,EAAQ,GCDf,GAAM,IAAe,iBACd,EAAQ,GCDf,GAAM,IAAsB,CAAC,WAAY,SAAU,YAAa,WACzD,EAAQ,GCDf,GAAM,IAAoB,gBACnB,EAAQ,GCDA,WAA8B,EAAqB,EAAiB,CACjF,GAAM,GAAsB,GAAI,aAAY,EAAqB,CAAE,WAAY,KAE/E,MAAI,aAA2B,SAC7B,OAAO,KAAK,GAAiB,QAAQ,AAAC,GAAQ,CAC5C,OAAO,eAAe,EAAqB,EAAK,CAC9C,MAAO,EAAgB,OAItB,ECVM,WAAuB,EAAM,CAC1C,GAAM,GAAe,EAAK,QAAQ,KAElC,MAAO,IAAU,GAAK,aAAa,SAAW,EAAK,KAAK,MAAM,MAAQ,KAEhE,GAAgB,EAAa,aAAa,SAAW,EAAa,KAAK,MAAM,MAAQ,KCL9E,WAAkB,EAAS,CACxC,EAAQ,QCWK,WAAwB,EAAO,CAC5C,MAAI,KAAU,OACL,GAGL,IAAU,QACL,GAGJ,OAAO,MAAM,CAAC,GAIf,IAAU,IAAM,IAAU,OACrB,KAIF,EARE,CAAC,ECjBZ,GAAM,IAAa,AAAC,GAAQ,OAAO,KAAK,GACjC,EAAQ,GCMA,WAA0B,EAAS,EAAY,EAAU,EAAI,CAE1E,GAAM,GAAO,IAAK,EAAQ,SACpB,EAAY,GACZ,EAAU,GAEhB,SAAW,GAAM,QAAQ,AAAC,GAAM,CAC9B,GAAM,GAAM,GAAM,EAAE,SAAS,GACzB,EAAE,QAAQ,EAAI,IAAI,QAAQ,QAAS,AAAC,GAAU,EAAM,eACpD,EAEJ,EAAQ,GAAO,EAAe,EAAK,MAGrC,EAAW,GAAU,QAAQ,AAAC,GAAM,CAClC,EAAS,GAAK,EAAe,EAAS,MAGxC,EAAW,GAAY,QAAQ,AAAC,GAAM,CACpC,AAAI,IAAK,GACP,EAAU,GAAK,EAAS,GACnB,AAAI,IAAK,GACd,EAAU,GAAK,EAAQ,GAEvB,EAAU,GAAK,EAAW,KAIvB,EClCT,WAAmC,CACjC,YAAY,EAAM,EAAQ,EAAU,EAAQ,CAC1C,GAAM,GAAO,KACP,EAAU,EAAa,GAE7B,AAAI,EAAQ,IAAO,EAAQ,GAAM,UACjC,EAAK,QAAU,EAEX,GAAY,OAAO,KAAK,GAAU,QACpC,GAAK,QAAU,EAAiB,EAAS,EAAW,GAAU,GAAK,OAErE,EAAQ,GAAQ,EAGlB,QAAQ,EAAM,CACZ,GAAM,GAAO,KACb,EAAK,QAAQ,GAAQ,KACrB,OAAO,KAAK,GAAM,QAAQ,AAAC,GAAS,CAAE,EAAK,GAAQ,SCAvD,GAAM,CAAC,GAAkB,EACnB,EAAoB,WACpB,EAAmB,IAAI,MAAiB,MAIxC,EAAe,EAAgB,GAC/B,EAAkB,EAAgB,GAClC,EAAgB,EAAgB,GAChC,EAAuB,GAAG,QAC1B,GAAgB,CAAC,UAAW,aAC5B,GAAgB,CAAC,EAAgB,GACjC,GAAkB,CAAC,EAAiB,GACpC,GAAyB,CAC7B,OAAQ,EACR,QAAS,WAKL,EAAoB,EAAqB,WAAW,KACpD,GAAqB,EAAqB,YAAY,KACtD,EAAoB,EAAqB,WAAW,KACpD,GAAsB,EAAqB,aAAa,KAI9D,YAAuB,EAAM,EAAM,CACjC,GAAM,CACJ,UAAS,OAAM,gBAAe,UAAS,WACrC,EACE,CAAE,UAAW,EACb,EAAS,EAAQ,cAOvB,GAHA,AADmB,CAAC,SAAU,MAAO,SAAU,OAAQ,SAC5C,QAAQ,AAAC,GAAM,CAAE,EAAK,MAAM,GAAK,KAC5C,EAAY,EAAQ,mBAEhB,CAAC,EAAM,CACT,GAAM,GAAa,EAAS,EAAM,GAClC,EAAO,UAAY,EAAc,KAAK,KACtC,AAAI,GAAc,CAAC,EAAS,EAAY,EAAM,GACrC,CAAC,GAAc,GAAS,EAAS,EAAM,GAChD,OAKF,GAAI,GAAgB,EAAgB,KAAK,AAAC,GAAM,EAAc,SAAS,KAAO,EAE1E,EAAiB,CACnB,SAAU,CAAC,EAAQ,EAAG,GACtB,OAAQ,CAAC,EAAG,EAAG,GACf,UAAW,CAAC,GAAI,EAAQ,GACxB,QAAS,CAAC,GAAI,EAAG,EAAG,IAGhB,EAAmB,CACvB,SAAU,CAAE,IAAK,QACjB,OAAQ,CAAE,IAAK,OAAQ,OAAQ,QAC/B,UAAW,CAAE,KAAM,OAAQ,MAAO,QAClC,QAAS,CAAE,KAAM,OAAQ,MAAO,QAChC,QAAS,CAAE,MAAO,EAAG,KAAM,SAI7B,GAAc,QAAQ,AAAC,GAAM,EAAS,EAAM,IAE5C,GAAM,IAAgB,GAAI,QAAO,OAAO,KAAkB,KAAgB,KAAmB,OACvF,EAAoB,CAAE,EAAG,EAAQ,YAAa,EAAG,EAAQ,cACzD,EAAiB,CAAE,EAAG,EAAK,YAAa,EAAG,EAAK,cAChD,GAAO,SAAS,gBAChB,GAAK,SAAS,KACd,GAAe,GAAK,aAAe,GAAG,YACtC,GAAgB,GAAK,cAAgB,GAAG,aACxC,EAAY,EAAQ,wBAEpB,GAAa,EAAU,KAAO,EAAkB,EAAI,EAAe,EAAI,EAEvE,GAAiB,EAAU,KAAO,EAAe,EAAI,EAErD,GAAc,EAAU,KAAO,EAAe,GAAK,GAEnD,GAAkB,EAAU,KAAO,EAAe,EAAI,EAAkB,GAAK,GAE7E,EAAe,EAAU,IAAM,EAAe,GAAK,GAEnD,GAAmB,EAAU,IAAM,EAAe,EAAI,EAAkB,GAAK,GAE7E,GAAY,EAAU,IAAM,EAAe,EAAI,EAGrD,AAAI,GAAgB,SAAS,IAAkB,IAAkB,IAC/D,GAAgB,GAEd,GAAgB,SAAS,IAAkB,GAC7C,GAAgB,GAEd,IAAkB,GAAmB,IAAkB,CAAC,GAC1D,GAAgB,GAEd,IAAkB,GAAiB,IAAmB,CAAC,GACzD,GAAgB,GAEd,IAAkB,GAAgB,IAAa,CAAC,IAClD,GAAgB,GAEd,IAAkB,GAAkB,IAAoB,CAAC,IAC3D,GAAgB,GAIlB,EAAiB,EAAe,GAChC,EAAK,MAAM,OAAS,GAAG,EAAe,IAAI,AAAC,GAAO,GAAI,GAAG,OAAY,KAAK,OAC1E,OAAO,KAAK,EAAiB,IAAgB,QAAQ,AAAC,GAAa,CACjE,EAAK,MAAM,GAAY,EAAiB,GAAe,KAIpD,EAAS,EAAQ,IACpB,GAAO,UAAY,EAAO,UAAU,QAAQ,GAAe,IAKzD,GAAc,SAAS,IACzB,CAAI,CAAC,GAAW,GAAa,EAAS,EAAM,GACnC,GAAW,IAAY,EAAY,EAAM,GAE9C,EAAS,EAAM,IACjB,OAAO,KAAK,EAAiB,SAAS,QAAQ,AAAC,GAAM,CACnD,EAAK,MAAM,GAAK,EAAiB,QAAQ,MAM/C,GAAc,QAAQ,AAAC,GAAM,EAAY,EAAM,IAGjD,YAA+B,EAAM,CACnC,GAAM,GAAS,EAAK,KAAO,EAAmB,EAE9C,SAAS,GAAQ,QAAS,IAC1B,SAAS,GAAQ,QAAS,IAC1B,SAAS,GAAQ,UAAW,IAC5B,SAAS,GAAQ,QAAS,IAEtB,EAAK,QAAQ,UAAY,WAC3B,QAAO,GAAQ,SAAU,GAAuB,GAChD,OAAO,GAAQ,SAAU,GAAuB,IAIpD,YAA+B,EAAM,EAAK,CACxC,GAAM,GAAS,EAAM,EAAmB,EACxC,EAAK,QAAQ,GAAQ,QAAS,IAGhC,aAAkC,CAChC,GAAM,GAAgB,EAAgB,OAAO,aAC1C,IAAI,AAAC,GAAM,SAAS,uBAAuB,GAAG,KAAK,MACnD,KAAK,AAAC,GAAM,EAAE,QAEjB,MAAI,IAAiB,EAAc,OAC1B,MAAM,KAAK,EAAc,GAAG,UAAU,KAAK,AAAC,GAAM,EAAE,aAAa,IAEnE,KAKT,YAAgC,EAAG,CACjC,GAAM,CAAE,SAAQ,QAAS,EACzB,GAAI,CAAC,EAAO,QAAS,OAErB,GAAM,GAAU,KACV,EAAS,GAAW,EAAQ,WAC5B,EAAO,GAAW,EAAQ,GAC1B,EAAO,GAAQ,EAAK,KAEpB,EAAU,EAAO,QAAQ,KAAsB,KAC/C,EAAS,GAAU,EAAO,SAAS,IACnC,GAAO,UAAY,QAAU,EAAO,QAAQ,UAAY,MAK9D,AAHI,IAAS,SAAW,EAAc,IACpC,EAAE,iBAEA,MAAS,SACP,KAAW,GAAW,IAAW,GAAQ,EAAK,SAAS,MAIzD,IAAU,GAEH,GACT,EAAK,KAAK,IAId,YAA8B,EAAG,CAC/B,GAAM,GAAU,KAEhB,AADa,EAAQ,GAChB,OAAO,GAER,EAAc,EAAE,SAAS,EAAE,iBAGjC,YAA+B,EAAG,CAChC,AAAI,GAAE,QAAU,IAAM,EAAE,QAAU,KAAI,EAAE,iBAG1C,YAA4B,CAAE,SAAS,CACrC,GAAM,GAAU,KACV,EAAO,EAAQ,GACf,CAAE,OAAM,YAAW,QAAS,EAC5B,EAAa,SAAS,cACtB,EAAgB,IAAe,EAC/B,EAAe,EAAK,SAAS,GAC7B,EAAa,EAAW,aAAe,GAAQ,EAAW,WAAW,aAAe,EAEtF,EAAM,EAAU,QAAQ,GAE5B,AAAI,GACF,CAAI,EACF,EAAM,EACD,AAAI,IAAU,GACnB,EAAM,EAAM,EAAI,EAAM,EAAI,EACjB,IAAU,IACnB,GAAM,EAAM,EAAU,OAAS,EAAI,EAAM,EAAI,GAG3C,EAAU,IAAM,EAAS,EAAU,KAGnC,GAAU,QAAU,GAClB,CAAC,EAAU,QAAW,IAAgB,IACvC,CAAC,IACD,GAAQ,IAAU,IAEvB,EAAK,SAIT,aAAiC,CAC/B,GAAM,GAAU,KACV,EAAO,GAAW,EAAQ,GAEhC,AAAI,GAAQ,EAAK,MAAM,GAAc,EAAM,GAK7C,mBAAsC,EAAc,CAClD,YAAY,EAAQ,EAAQ,CAC1B,MAAM,EAAmB,EAAQ,GAAwB,GAEzD,GAAM,GAAO,KAGP,CAAE,WAAY,EAGd,EAAS,EAAQ,cACvB,EAAK,KAAO,EAAa,IAAI,IAAqB,GAClD,GAAM,CAAE,QAAS,EAEjB,EAAK,cAAgB,MAAM,KAAK,EAAO,WAGvC,EAAK,QAAU,EAAS,EAAM,GAE9B,EAAK,UAAY,GAEjB,MAAM,KAAK,EAAK,UAAU,QAAQ,AAAC,GAAU,CAC3C,AAAI,EAAM,SAAS,QAAW,EAAM,SAAS,GAAG,UAAY,KAAM,EAAK,UAAU,KAAK,EAAM,SAAS,IACjG,EAAM,UAAY,KAAK,EAAK,UAAU,KAAK,KAIjD,EAAK,KAAO,GAGZ,GAAsB,EAAM,GAK9B,OAAO,EAAS,CACd,GAAM,GAAO,KACP,CAAE,QAAS,EAEjB,AAAI,EAAM,EAAK,KAAK,GACf,EAAK,KAAK,GAGjB,KAAK,EAAS,CACZ,GAAM,GAAO,KACP,EAAgB,EAAa,EAAgB,OAAO,aAAa,IAAI,AAAC,GAAM,IAAI,KAAK,KAAa,KAAK,MACvG,EAAiB,GAAiB,EAAa,EAAkB,GAEvE,AAAI,GAAgB,EAAe,GAAmB,OAEtD,GAAM,CAAE,UAAS,OAAM,QAAS,EAC1B,EAAS,EAAQ,WAKvB,AAFA,EAAkB,cAAgB,GAAW,KAC7C,EAAO,cAAc,GACjB,GAAkB,kBAGtB,IAAc,EAAM,GAEpB,EAAS,EAAM,GACf,EAAS,EAAQ,GAEjB,EAAQ,aAAa,EAAc,IACnC,EAAK,KAAO,CAAC,EAEb,WAAW,IAAM,CACf,EAAS,EAAK,qBAAqB,SAAS,IAAM,GAClD,GAAsB,GAEtB,GAAmB,cAAgB,GAAW,KAC9C,EAAO,cAAc,KACpB,IAGL,KAAK,EAAS,CACZ,GAAM,GAAO,KACP,CAAE,UAAS,OAAM,QAAS,EAC1B,EAAS,EAAQ,WAGvB,AAFA,EAAkB,cAAgB,GAAW,KAC7C,EAAO,cAAc,GACjB,GAAkB,kBAEtB,GAAY,EAAM,GAClB,EAAY,EAAQ,GAGpB,GAAc,GAEd,EAAQ,aAAa,EAAc,IACnC,EAAK,KAAO,CAAC,EAEb,EAAS,GAGT,WAAW,IAAM,GAAsB,GAAO,GAG9C,GAAoB,cAAgB,GAAW,KAC/C,EAAO,cAAc,KAGvB,SAAU,CACR,GAAM,GAAO,KACP,CAAE,WAAY,EAEpB,AAAI,EAAS,EAAQ,WAAY,IAAc,EAAK,MAAM,EAAK,OAE/D,GAAsB,GAEtB,MAAM,QAAQ,KAIlB,EAAS,KAAO,CACd,UAAW,EACX,SAAU,EACV,YAAa,GC7Xf,GAAM,IAAe,YACf,EAAiB,CAAC,YAAa,aAAc,cAC7C,EAAkB,aAGlB,EAAe,GAAI,SAEzB,OAAW,yBAcT,YAAY,EAAI,EAAa,GAAI,CAE/B,EAAG,MAAM,QAAU,OACnB,EAAa,IAAI,EAAI,MACrB,QAAsB,EAGtB,GAAM,GAAY,AAAC,GAAU,CAAC,OAAQ,QAAS,IAAK,IAAK,GAAM,IAAO,SAAS,IAAU,CAAC,CAAC,KAAK,MAAM,GAGhG,EAAO,IAAK,KAAe,EAAG,SAuBpC,IAtBA,KAAK,SAAW,EAAK,SAAW,EAAU,EAAK,UAAY,GAC3D,KAAK,mBAAqB,EAAK,mBAAqB,EAAU,EAAK,oBAAsB,GACzF,KAAK,WAAa,EAAK,YAAc,UACrC,KAAK,WAAa,EAAK,WAAa,EAAU,EAAK,YAAc,GACjE,KAAK,OAAS,EAAK,QAAU,GAC7B,KAAK,WAAa,EAAK,WAAa,EAAU,EAAK,YAAc,GACjE,KAAK,aAAe,EAAK,cAAgB,GACrC,MAAO,MAAK,cAAgB,UAC9B,MAAK,aAAe,KAAK,MAAM,KAAK,eAEtC,KAAK,qBAAuB,MAAO,GAAK,sBAAwB,YAAc,SAAS,EAAK,sBAAwB,EACpH,KAAK,gBAAkB,EAAK,OAAS,GACrC,KAAK,UAAY,EAAK,UAAY,EAAK,UAAU,MAAM,KAAO,GAC9D,KAAK,IAAM,EAAK,IAAM,SAAS,EAAK,KAAO,KAC3C,KAAK,WAAa,EAAK,YAAc,QACrC,KAAK,YAAc,EAAK,aAAe,eAEvC,KAAK,YAAc,UACnB,QAA2B,GAC3B,QAAmB,GAEnB,KAAK,WAAa,EAAG,cACd,KAAK,YACV,MAAK,WAAa,KAAK,WAAW,cAC9B,OAAK,YAAc,KAAK,WAAW,UAAY,UAAnD,CAIF,KAAK,MAAQ,KAAK,MAAM,KAAK,MACzB,KAAK,YACP,KAAK,WAAW,iBAAiB,QAAS,KAAK,OAIjD,QAAsB,SAAS,cAAc,OAC7C,QAAyB,SAAS,cAAc,OAChD,QAAoB,SAAS,cAAc,MAC3C,QAAoB,SAAS,cAAc,SAE3C,QAAoB,YAAY,SAChC,QAAuB,YAAY,SACnC,QAAoB,YAAY,SAEhC,QAAoB,WAAW,aAAa,QAAqB,QAAoB,aAGrF,UACA,UACA,UACA,UACA,KAAK,aAEL,AAAI,KAAK,QAAU,CAAC,KAAK,WACvB,UAEA,KAAK,yBASF,MAAK,EAAW,mBAAoB,EAAO,GAAI,CACpD,GAAI,GAAO,SAAS,iBAAiB,GACrC,OAAS,GAAI,EAAG,EAAI,EAAK,OAAQ,IAC/B,AAAI,EAAK,YAAY,EAAK,KAG1B,GAAI,GAAK,EAAK,GAAI,SAOf,aAAY,EAAI,CACrB,GAAI,EAAa,IAAI,GACnB,MAAO,GAAa,IAAI,GAI5B,SAAU,CACR,EAAa,OAAO,SACpB,QAAoB,MAAM,QAAU,QACpC,QAAoB,WAAW,YAAY,SACvC,KAAK,YACP,KAAK,WAAW,oBAAoB,QAAS,KAAK,OAItD,YAAa,CACX,AAAI,KAAK,aACP,SAAoB,aAAa,WAAY,IAC7C,QAAkB,aAAa,WAAY,KAEvC,SAAoB,aAAa,aACnC,QAAoB,gBAAgB,YAElC,QAAkB,aAAa,aACjC,QAAkB,gBAAgB,aAKxC,kBAAmB,CACjB,GAAI,GAAc,MAAM,KAAK,QAAoB,iBAAiB,WAC/D,OAAO,AAAC,GACA,CAAC,EAAO,UAEhB,IAAI,AAAC,GACG,EACL,MAAO,EAAO,aAAa,SAC3B,MAAO,EAAO,eAGpB,QAAuB,MAMT,EAAO,GAAO,CAC5B,AAAI,SACF,QAAsB,QAExB,QAAwB,GAAI,iBAE5B,KAAK,aAAa,MAAQ,QAAkB,MAC5C,GAAM,GAAS,GAAI,iBAAgB,KAAK,cAAc,WAEtD,MAAM,KAAK,OAAS,IAAM,EAAQ,CAAE,OAAQ,QAAsB,SAC/D,KAAK,AAAC,GAAM,EAAE,QACd,KAAK,AAAC,GAAgB,CACrB,GAAI,GAAO,EAAY,MAAQ,EAC/B,QAAuB,GACvB,QAAwB,KACpB,GACF,YAGH,MAAM,AAAC,GAAM,CACZ,AAAI,EAAE,OAAS,cAGf,QAAQ,MAAM,SAOF,CAEhB,GAAI,QAAoB,aAAa,eACnC,MAAO,SAAoB,aAAa,eAE1C,GAAI,QAAoB,QAAQ,YAC9B,MAAO,SAAoB,QAAQ,YAGrC,GAAI,GAAc,QAAoB,cAAc,UACpD,MAAK,GAGD,GAAY,aAAa,aAC3B,EAAY,gBAAgB,YAEvB,AAAC,EAAY,MAAkC,GAA1B,EAAY,aAL/B,OAQa,CACtB,QAAkB,UAAU,IAAQ,gBAAiB,OACrD,QAAkB,MAAM,UAAY,QACpC,QAAkB,MAAM,UAAY,OAGpC,QAAkB,iBAAiB,aAAc,AAAC,GAAU,CAC1D,QAA2B,SAIL,CACxB,QAAoB,UAAU,IAAQ,eAAgB,YAClD,YAAgC,GAElC,SAAoB,MAAM,OAAS,YAIV,CAC3B,QAAuB,iBAAiB,QAAS,AAAC,GAAU,CAC1D,AAAI,KAAK,cAGL,QAAkB,MAAM,YAAc,UACxC,QAAkB,UAOtB,GAAI,GAAgB,QAAoB,gBACxC,OAAS,GAAI,EAAG,EAAI,EAAc,OAAQ,IAAK,CAC7C,GAAI,GAAe,EAAc,GACjC,AAAI,CAAC,EAAa,OAIlB,GAAa,QAAQ,KAAO,EAC5B,KAAK,QAAQ,EAAa,YAAa,EAAa,aAIhC,CACtB,QAAkB,KAAO,OACzB,QAAkB,aAAe,MACjC,QAAkB,WAAa,GAC/B,QAAkB,MAAM,gBAAkB,cAC1C,QAAkB,MAAM,OAAS,EACjC,QAAkB,MAAM,QAAU,EAClC,QAAkB,MAAM,SAAW,OACnC,QAAkB,UAAY,KAAK,YACnC,QAAuB,IAEvB,QAAkB,iBAAiB,QAAS,AAAC,GAAU,CAGrD,GAAI,EAAM,KAAM,CACd,GAAM,GAAW,EAAM,KAAK,MAAM,IAClC,GAAI,KAAK,UAAU,QAAU,QAAkB,OAAS,KAAK,UAAU,SAAS,GAAW,CAEzF,QAAkB,MAAQ,QAAkB,MAAM,MAAM,EAAG,IAC3D,GAAI,GAAO,QAAkB,MAC7B,GAAI,CAAC,KAAK,OAAO,GACf,OAEF,KAAK,QAAQ,EAAM,MACnB,UACA,QAKJ,UAGA,AAAI,QAAkB,MAAM,QAAU,KAAK,qBACzC,AAAI,KAAK,WACP,QAAqB,IAErB,UAGF,YAGJ,QAAkB,iBAAiB,QAAS,AAAC,GAAU,CACrD,AAAI,QAAkB,MAAM,QAAU,KAAK,sBACzC,YAGJ,QAAkB,iBAAiB,WAAY,AAAC,GAAU,CACxD,YAGF,QAAkB,iBAAiB,UAAW,AAAC,GAAU,CAKvD,OAHU,EAAM,SAAW,EAAM,SAI1B,QACA,QACH,EAAM,iBACN,GAAI,GAAY,KAAK,qBACrB,GAAI,EACF,EAAU,gBAGN,KAAK,UAAY,QAAkB,MAAO,CAC5C,GAAI,GAAO,QAAkB,MAC7B,GAAI,CAAC,KAAK,OAAO,GACf,OAEF,KAAK,QAAQ,EAAM,MACnB,UAGJ,UACG,QACA,UACH,EAAM,iBACN,QAA2B,GAC3B,GAAI,GAAe,UAEnB,AAAI,QAAkB,MAAM,QAAU,GAAK,QAAkB,UAAU,SAAS,SAAW,CAAC,GAC1F,UAEF,UACG,QACA,YACH,EAAM,iBACN,QAA2B,GAC3B,UAEI,QAAkB,MAAM,QAAU,GAAK,CAAC,QAAkB,UAAU,SAAS,SAC/E,UAEF,UACG,OACA,YACH,AAAI,QAAkB,MAAM,QAAU,GACpC,MAAK,iBACL,UACA,WAEF,UACG,QACA,SAEH,UACA,aAQW,CACjB,GAAI,GAAS,KAAK,qBAClB,GAAI,EAAQ,CACV,GAAI,GAAO,EAAO,WAClB,EACE,GAAO,EAAK,sBACL,GAAQ,EAAK,MAAM,SAAW,QACvC,MAAK,GAGL,GAAO,UAAU,OAAO,GAAG,GAC3B,EAAK,cAAc,KAAK,UAAU,IAAI,GAAG,GAEzC,EAAK,WAAW,UAAY,EAAK,UAAY,EAAK,WAAW,UACtD,GANE,KAQX,MAAO,UAMY,CACnB,GAAI,GAAS,KAAK,qBACd,EAAO,KACX,GAAI,EAAQ,CACV,EAAO,EAAO,WACd,EACE,GAAO,EAAK,kBACL,GAAQ,EAAK,MAAM,SAAW,QACvC,MAAK,GAGL,GAAO,UAAU,OAAO,GAAG,GAC3B,EAAK,cAAc,KAAK,UAAU,IAAI,GAAG,GAErC,EAAK,UAAY,EAAK,WAAW,aAAe,EAAK,cACvD,GAAK,WAAW,WAAa,EAAK,cAE7B,GARE,KAUX,MAAO,OAMM,CACb,AAAI,QAAkB,MACpB,QAAkB,KAAO,QAAkB,MAAM,OAAS,EAG1D,AAAI,KAAK,oBAAoB,OAC3B,SAAkB,YAAc,GAChC,QAAkB,KAAO,GAEzB,SAAkB,KAAO,KAAK,YAAY,OAAS,EAAI,KAAK,YAAY,OAAS,EACjF,QAAkB,YAAc,KAAK,gBASzB,EAAc,KAAM,CACpC,KAAO,QAAkB,WACvB,QAAkB,YAAY,QAAkB,WAElD,OAAS,GAAI,EAAG,EAAI,EAAY,OAAQ,IAAK,CAC3C,GAAI,GAAa,EAAY,GAC7B,GAAI,CAAC,EAAW,MACd,SAEF,GAAI,GAAW,SAAS,cAAc,MAClC,EAAe,SAAS,cAAc,KAM1C,GALA,EAAS,OAAO,GAChB,EAAa,UAAU,IAAI,iBAC3B,EAAa,aAAa,EAAiB,EAAW,OACtD,EAAa,aAAa,OAAQ,KAClC,EAAa,YAAc,EAAW,MAClC,EAAW,KACb,OAAW,CAAC,EAAK,IAAU,QAAO,QAAQ,EAAW,MACnD,EAAa,QAAQ,GAAO,EAGhC,QAAkB,YAAY,GAG9B,EAAa,iBAAiB,aAAc,AAAC,GAAU,CAErD,AAAI,SAGJ,MAAK,wBACL,EAAS,cAAc,KAAK,UAAU,IAAI,GAAG,MAG/C,EAAa,iBAAiB,YAAa,AAAC,GAAU,CACpD,QAA2B,KAG7B,EAAa,iBAAiB,YAAa,AAAC,GAAU,CAEpD,EAAM,mBAER,EAAa,iBAAiB,QAAS,AAAC,GAAU,CAChD,EAAM,iBACN,GAAI,GAAO,EAAa,YACxB,AAAI,CAAC,KAAK,OAAO,EAAM,EAAa,aAAa,KAGjD,MAAK,QAAQ,EAAM,EAAa,aAAa,GAAkB,EAAa,SAC5E,cAKN,OAAQ,CACN,KAAK,YAGL,QAAmB,GACnB,GAAI,GAAgB,QAAoB,iBAAiB,qBACzD,OAAS,GAAI,EAAG,EAAI,EAAc,OAAQ,IAAK,CAC7C,GAAI,GAAe,EAAc,GACjC,KAAK,QAAQ,EAAa,YAAa,EAAa,OAEtD,UACA,QAAmB,MAGH,EAAO,GAAO,CAC9B,QAAkB,MAAQ,GAC1B,UAEK,GACH,WAEA,QAAkB,cAAc,GAAI,OAAM,WAI5C,AAAI,KAAK,KAAO,KAAK,oBAAoB,SAAW,KAAK,IACvD,QAAkB,MAAM,WAAa,SAC5B,QAAkB,MAAM,YAAc,UAC/C,SAAkB,MAAM,WAAa,WAGnC,KAAK,YAAc,CAAC,GACtB,SAAS,cAAc,OAO3B,mBAAoB,CAElB,GAAI,GAAW,QAAoB,iBAAiB,oBACpD,MAAO,OAAM,KAAK,GAAU,IAAI,AAAC,GAAO,EAAG,WAM1B,CACjB,GAAI,QAAkB,MAAM,YAAc,SACxC,OAIF,QAAkB,MAAM,KAAO,QAAkB,WAAa,KAG9D,GAAI,GAAS,QAAkB,MAAM,oBAGjC,EAAS,KAAK,oBAGd,EAAO,QAAkB,iBAAiB,MAC1C,EAAQ,GACR,EAAY,KACZ,EAAoB,GACxB,OAAS,GAAI,EAAG,EAAI,EAAK,OAAQ,IAAK,CACpC,GAAI,GAAO,EAAK,GACZ,EAAO,EAAK,YAAY,oBACxB,EAAO,EAAK,cAAc,KAM9B,GAHA,EAAK,UAAU,OAAO,GAAG,GAGrB,EAAO,QAAQ,EAAK,aAAa,KAAqB,GAAI,CAC5D,EAAK,MAAM,QAAU,OACrB,SAGF,EAAoB,GAGpB,GAAI,GAAY,EAAO,SAAW,GAAK,EAAK,QAAQ,KAAY,GAChE,AAAI,KAAK,oBAAsB,KAAK,uBAAyB,GAAK,EAChE,GAAK,MAAM,QAAU,YACrB,EAAQ,GACJ,CAAC,GAAa,GAChB,GAAY,IAGd,EAAK,MAAM,QAAU,OAKzB,AAAI,EACF,SAAoB,UAAU,OAAO,cACrC,EAAU,cAAc,KAAK,UAAU,IAAI,GAAG,GAC9C,EAAU,WAAW,UAAY,EAAU,UAAY,EAAU,WAAW,WAG5E,AAAI,CAAC,KAAK,UAAY,CAAE,GAAO,SAAW,GAAK,CAAC,GAC9C,QAAoB,UAAU,IAAI,cACzB,KAAK,iBAAmB,KAAK,aACtC,QAAoB,UAAU,OAAO,cAKzC,AAAI,CAAC,GAAS,KAAK,YACjB,QAAkB,UAAU,OAAO,QAGnC,QAAkB,UAAU,IAAI,YAOjB,CACjB,QAAkB,UAAU,OAAO,QACnC,QAAoB,UAAU,OAAO,cACrC,KAAK,4BAMgB,CACrB,GAAI,GAAM,EAEV,MAAI,QAAO,QAAU,EAAE,GAAG,SAAW,MAAa,EAAE,GAAG,QAAQ,aAAe,MAC5E,GAAM,SAAS,EAAE,GAAG,QAAQ,YAAY,QAAQ,OAAO,KAElD,KAQG,EAAM,CAChB,GAAM,GAAM,MAAM,KAAK,QAAoB,iBAAiB,WAAW,KAAK,AAAC,GAAO,EAAG,aAAe,GACtG,MAAI,MAAO,EAAI,aAAa,gBAWf,EAAO,CAEpB,MAAO,AADO,IAAI,QAAO,KAAK,gBAAgB,QACjC,KAAK,GAMpB,oBAAqB,CACnB,MAAO,SAAkB,cAAc,KAAO,IAGhD,uBAAwB,CACtB,GAAI,GAAY,KAAK,qBACrB,AAAI,GACF,EAAU,UAAU,OAAO,GAAG,GAIlC,WAAY,CAEV,AADY,KAAK,oBACX,QAAQ,AAAC,GAAS,CACtB,KAAK,WAAW,KAElB,UAMF,eAAe,EAAU,CACvB,AAAI,GACF,SAAmB,IAErB,GAAI,GAAQ,QAAuB,iBAAiB,QACpD,GAAI,CAAC,EAAM,OACT,OAEF,GAAI,GAAW,EAAM,EAAM,OAAS,GACpC,KAAK,WAAW,EAAS,aAAa,IACtC,QAAmB,GAMrB,YAAa,CACX,MAAO,SAAoB,aAAa,aAAe,QAAoB,UAAY,QAAoB,aAAa,YAM1H,WAAY,CACV,MAAO,SAAoB,UAAU,SAAS,cAMhD,UAAW,CACT,MAAO,CAAC,QAAoB,aAAa,YAQ3C,OAAO,EAAM,EAAQ,KAAM,CAkBzB,MAjBK,IACH,GAAQ,GAIN,CAAC,GAID,KAAK,cAIL,CAAC,KAAK,YAAc,QAAiB,IAIrC,KAAK,KAAO,KAAK,oBAAoB,QAAU,KAAK,IAC/C,GAGL,KAAK,iBAAmB,CAAC,QAAoB,GAC/C,SAAoB,UAAU,IAAI,cAC3B,IAEF,GAST,QAAQ,EAAM,EAAQ,KAAM,EAAO,GAAI,CACrC,AAAK,GACH,GAAQ,GAIN,KAAK,YAAc,KAAK,oBAAoB,QAC9C,KAAK,eAAe,IAGtB,GAAM,GAAO,UACT,EAAM,QAAoB,cAAc,iBAAmB,EAAQ,MACvE,AAAI,GACF,GAAO,EAAI,SAIb,GAAI,GAAO,EACP,EAAO,SAAS,cAAc,QAC9B,EAAU,CAAC,SACX,EAAa,KAAK,WAyCtB,GAxCI,EAAK,YACP,GAAa,EAAK,YAEhB,EAAK,YACP,EAAQ,KAAK,EAAK,YAEpB,AAAI,IAAS,EAEX,EAAU,CAAC,GAAG,EAAa,OAAQ,MAAQ,GAG3C,EAAU,CAAC,GAAG,EAAa,OAAQ,SAAW,GAEhD,EAAK,UAAU,IAAI,GAAG,GACtB,EAAK,aAAa,EAAiB,GAE/B,KAAK,YAKP,GAAO,AAHL,KAAS,EACL,iHAAmH,KAAK,WAAa,cACrI,kJAAoJ,KAAK,WAAa,sDAC/J,GAGf,EAAK,UAAY,EACjB,QAAuB,aAAa,EAAM,SAEtC,KAAK,YACP,EAAK,cAAc,UAAU,iBAAiB,QAAS,AAAC,GAAU,CAChE,EAAM,iBACN,EAAM,kBACD,KAAK,cACR,MAAK,WAAW,GAChB,SAAS,cAAc,OACvB,aAMF,CAAC,EAAK,CACR,EAAM,SAAS,cAAc,UAC7B,EAAI,MAAQ,EACZ,EAAI,YAAc,EAElB,OAAW,CAAC,EAAK,IAAU,QAAO,QAAQ,GACxC,EAAI,QAAQ,GAAO,EAErB,QAAoB,YAAY,GAIlC,EAAI,aAAa,WAAY,YAC7B,EAAI,SAAW,GAGX,SACF,QAAoB,cAAc,GAAI,OAAM,SAAU,CAAE,QAAS,MAOrE,WAAW,EAAO,CAChB,GAAI,GAAO,QAAuB,cAAc,QAAU,EAAkB,KAAO,EAAQ,MAC3F,GAAI,CAAC,EACH,OAEF,EAAK,SAGL,GAAI,GAAM,QAAoB,cAAc,iBAAmB,EAAQ,MACvE,AAAI,GACF,GAAI,gBAAgB,YACpB,EAAI,SAAW,GAGX,SACF,QAAoB,cAAc,GAAI,OAAM,SAAU,CAAE,QAAS,OAKjE,QAAkB,MAAM,YAAc,UAAY,KAAK,KAAO,KAAK,oBAAoB,OAAS,KAAK,KACvG,SAAkB,MAAM,WAAa,aAKpC,GAAQ,ECn2Bf,GAAO,IAAQ", "names": [] } diff --git a/tags.min.js b/tags.min.js index 9ebdb75..31bcee2 100644 --- a/tags.min.js +++ b/tags.min.js @@ -1,2 +1,2 @@ -var p="is-active",o=["is-active","bg-primary","text-white"],d="data-value",f=new WeakMap,v=class{#h;#t;#i;#l;#s;#e;#a;#r;constructor(e,t={}){e.style.display="none",e.dataset.tags=!0,this.#t=e;let s=i=>["true","false","1","0",!0,!1].includes(i)&&!!JSON.parse(i),l={...t,...e.dataset};for(this.allowNew=l.allowNew?s(l.allowNew):!1,this.showAllSuggestions=l.showAllSuggestions?s(l.showAllSuggestions):!1,this.badgeStyle=l.badgeStyle||"primary",this.allowClear=l.allowClear?s(l.allowClear):!1,this.server=l.server||!1,this.liveServer=l.liveServer?s(l.liveServer):!1,this.serverParams=l.serverParams||{},typeof this.serverParams=="string"&&(this.serverParams=JSON.parse(this.serverParams)),this.suggestionsThreshold=typeof l.suggestionsThreshold!="undefined"?parseInt(l.suggestionsThreshold):1,this.validationRegex=l.regex||"",this.separator=l.separator?l.separator.split("|"):[],this.max=l.max?parseInt(l.max):null,this.clearLabel=l.clearLabel||"Clear",this.searchLabel=l.searchLabel||"Type a value",this.placeholder=this.#p(),this.#a=!1,this.#r=!0,this.parentForm=e.parentElement;this.parentForm&&(this.parentForm=this.parentForm.parentElement,this.parentForm.nodeName!="FORM"););this.reset=this.reset.bind(this),this.parentForm.addEventListener("reset",this.reset),this.#i=document.createElement("div"),this.#l=document.createElement("div"),this.#s=document.createElement("ul"),this.#e=document.createElement("input"),this.#i.appendChild(this.#l),this.#l.appendChild(this.#e),this.#i.appendChild(this.#s),this.#t.parentNode.insertBefore(this.#i,this.#t.nextSibling),this.#g(),this.#m(),this.#b(),this.#y(),this.resetState(),this.server&&!this.liveServer?this.#c():this.resetSuggestions()}static init(e="select[multiple]",t={}){let s=document.querySelectorAll(e),l;for(let i=0;i!t.disabled).map(t=>({value:t.getAttribute("value"),label:t.innerText}));this.#f(e)}#c(e=!1){this.#h&&this.#h.abort(),this.#h=new AbortController,this.serverParams.query=this.#e.value;let t=new URLSearchParams(this.serverParams).toString();fetch(this.server+"?"+t,{signal:this.#h.signal}).then(s=>s.json()).then(s=>{let l=s.data||s;this.#f(l),this.#h=null,e&&this.#u()}).catch(s=>{s.name!=="AbortError"&&console.error(s)})}#p(){if(this.#t.hasAttribute("placeholder"))return this.#t.getAttribute("placeholder");if(this.#t.dataset.placeholder)return this.#t.dataset.placeholder;let e=this.#t.querySelector("option");return e?(e.hasAttribute("selected")&&e.removeAttribute("selected"),e.value?"":e.innerText):""}#m(){this.#s.classList.add("dropdown-menu","p-0"),this.#s.style.maxHeight="280px",this.#s.style.overflowY="auto",this.#s.addEventListener("mouseenter",e=>{this.#a=!1})}#g(){this.#i.classList.add("form-control","dropdown"),this.#v()===4&&(this.#i.style.height="auto")}#b(){this.#l.addEventListener("click",t=>{this.isDisabled()||this.#e.style.visibility!="hidden"&&this.#e.focus()});let e=this.#t.selectedOptions;for(let t=0;t{if(e.data){let t=e.data.slice(-1);if(this.separator.length&&this.#e.value&&this.separator.includes(t)){let s=this.#e.value.slice(0,-1);if(!this.canAdd(s))return;this.addItem(s,null),this.#d();return}}this.#n(),this.#e.value.length>=this.suggestionsThreshold?this.liveServer?this.#c(!0):this.#u():this.#o()}),this.#e.addEventListener("focus",e=>{this.#e.value.length>=this.suggestionsThreshold&&this.#u()}),this.#e.addEventListener("focusout",e=>{this.#o()}),this.#e.addEventListener("keydown",e=>{switch(e.keyCode||e.key){case 13:case"Enter":e.preventDefault();let s=this.getActiveSelection();if(s)s.click();else if(this.allowNew&&!this.#w(this.#e.value)&&this.#e.value){let i=this.#e.value;if(!this.canAdd(i))return;this.addItem(i,null),this.#d()}break;case 38:case"ArrowUp":e.preventDefault(),this.#a=!0;let l=this.#S();this.#e.value.length==0&&this.#s.classList.contains("show")&&!l&&this.#o();break;case 40:case"ArrowDown":e.preventDefault(),this.#a=!0,this.#A(),this.#e.value.length==0&&!this.#s.classList.contains("show")&&this.#u();break;case 8:case"Backspace":this.#e.value.length==0&&(this.removeLastItem(),this.#n(),this.#o());break}})}#S(){let e=this.getActiveSelection();if(e){let t=e.parentNode;do t=t.previousSibling;while(t&&t.style.display=="none");return t?(e.classList.remove(...o),t.querySelector("a").classList.add(...o),t.parentNode.scrollTop=t.offsetTop-t.parentNode.offsetTop,t):null}return null}#A(){let e=this.getActiveSelection(),t=null;if(e){t=e.parentNode;do t=t.nextSibling;while(t&&t.style.display=="none");return t?(e.classList.remove(...o),t.querySelector("a").classList.add(...o),t.offsetTop>t.parentNode.offsetHeight-t.offsetHeight&&(t.parentNode.scrollTop+=t.offsetHeight),t):null}return t}#n(){this.#e.value?this.#e.size=this.#e.value.length+1:this.getSelectedValues().length?(this.#e.placeholder="",this.#e.size=1):(this.#e.size=this.placeholder.length>0?this.placeholder.length:1,this.#e.placeholder=this.placeholder)}#f(e=null){for(;this.#s.lastChild;)this.#s.removeChild(this.#s.lastChild);for(let t=0;t{this.#a||(this.removeActiveSelection(),l.querySelector("a").classList.add(...o))}),i.addEventListener("mousemove",r=>{this.#a=!1}),i.addEventListener("mousedown",r=>{r.preventDefault()}),i.addEventListener("click",r=>{r.preventDefault();let a=i.innerText;!this.canAdd(a)||(this.addItem(a,i.getAttribute(d),i.dataset),this.#d())})}}reset(){this.removeAll(),this.#r=!1;let e=this.#t.querySelectorAll("option[data-init]");for(let t=0;tt.value)}#u(){if(this.#e.style.visibility=="hidden")return;this.#s.style.left=this.#e.offsetLeft+"px";let e=this.#e.value.toLocaleLowerCase(),t=this.getSelectedValues(),s=this.#s.querySelectorAll("li"),l=!1,i=null,r=!1;for(let a=0;as.textContent==e);return!!(t&&t.getAttribute("selected"))}#L(e){return new RegExp(this.validationRegex.trim()).test(e)}getActiveSelection(){return this.#s.querySelector("a."+p)}removeActiveSelection(){let e=this.getActiveSelection();e&&e.classList.remove(...o)}removeAll(){this.getSelectedValues().forEach(t=>{this.removeItem(t)}),this.#n()}removeLastItem(e){e&&(this.#r=!1);let t=this.#l.querySelectorAll("span");if(!t.length)return;let s=t[t.length-1];this.removeItem(s.getAttribute(d)),this.#r=!0}isDisabled(){return this.#t.hasAttribute("disabled")||this.#t.disabled||this.#t.hasAttribute("readonly")}isInvalid(){return this.#i.classList.contains("is-invalid")}isSingle(){return!this.#t.hasAttribute("multiple")}canAdd(e){return!e||this.max&&this.getSelectedValues().length>=this.max?!1:this.validationRegex&&!this.#L(e)?(this.#i.classList.add("is-invalid"),!1):!0}addItem(e,t=null,s={}){t||(t=e),this.isSingle()&&this.getSelectedValues().length&&this.removeLastItem(!0);let l=this.#v(),i=this.#t.querySelector('option[value="'+t+'"]');i&&(s=i.dataset);let r=e,a=document.createElement("span"),n=["badge"],u=this.badgeStyle;if(s.badgeStyle&&(u=s.badgeStyle),s.badgeClass&&n.push(s.badgeClass),l===5?n=[...n,"me-2","bg-"+u]:n=[...n,"mr-2","badge-"+u],a.classList.add(...n),a.setAttribute(d,t),this.allowClear&&(r=(l===5?'':'')+r),a.innerHTML=r,this.#l.insertBefore(a,this.#e),this.allowClear&&a.querySelector("button").addEventListener("click",h=>{h.preventDefault(),h.stopPropagation(),this.isDisabled()||(this.removeItem(t),document.activeElement.blur(),this.#n())}),!i){i=document.createElement("option"),i.value=t,i.innerText=e;for(let[h,c]of Object.entries(s))i.dataset[h]=c;this.#t.appendChild(i)}i.setAttribute("selected","selected"),i.selected=!0,this.#r&&this.#t.dispatchEvent(new Event("change",{bubbles:!0}))}removeItem(e){let t=this.#l.querySelector("span["+d+'="'+e+'"]');if(!t)return;t.remove();let s=this.#t.querySelector('option[value="'+e+'"]');s&&(s.removeAttribute("selected"),s.selected=!1,this.#r&&this.#t.dispatchEvent(new Event("change",{bubbles:!0}))),this.#e.style.visibility=="hidden"&&this.max&&this.getSelectedValues().length["true","false","1","0",!0,!1].includes(l)&&!!JSON.parse(l),i={...t,...e.dataset};for(this.allowNew=i.allowNew?s(i.allowNew):!1,this.showAllSuggestions=i.showAllSuggestions?s(i.showAllSuggestions):!1,this.badgeStyle=i.badgeStyle||"primary",this.allowClear=i.allowClear?s(i.allowClear):!1,this.server=i.server||!1,this.liveServer=i.liveServer?s(i.liveServer):!1,this.serverParams=i.serverParams||{},typeof this.serverParams=="string"&&(this.serverParams=JSON.parse(this.serverParams)),this.suggestionsThreshold=typeof i.suggestionsThreshold!="undefined"?parseInt(i.suggestionsThreshold):1,this.validationRegex=i.regex||"",this.separator=i.separator?i.separator.split("|"):[],this.max=i.max?parseInt(i.max):null,this.clearLabel=i.clearLabel||"Clear",this.searchLabel=i.searchLabel||"Type a value",this.placeholder=this.#p(),this.#a=!1,this.#r=!0,this.parentForm=e.parentElement;this.parentForm&&(this.parentForm=this.parentForm.parentElement,!(this.parentForm&&this.parentForm.nodeName=="FORM")););this.reset=this.reset.bind(this),this.parentForm&&this.parentForm.addEventListener("reset",this.reset),this.#i=document.createElement("div"),this.#l=document.createElement("div"),this.#s=document.createElement("ul"),this.#e=document.createElement("input"),this.#i.appendChild(this.#l),this.#l.appendChild(this.#e),this.#i.appendChild(this.#s),this.#t.parentNode.insertBefore(this.#i,this.#t.nextSibling),this.#g(),this.#m(),this.#b(),this.#y(),this.resetState(),this.server&&!this.liveServer?this.#c():this.resetSuggestions()}static init(e="select[multiple]",t={}){let s=document.querySelectorAll(e);for(let i=0;i!t.disabled).map(t=>({value:t.getAttribute("value"),label:t.textContent}));this.#f(e)}#c(e=!1){this.#o&&this.#o.abort(),this.#o=new AbortController,this.serverParams.query=this.#e.value;let t=new URLSearchParams(this.serverParams).toString();fetch(this.server+"?"+t,{signal:this.#o.signal}).then(s=>s.json()).then(s=>{let i=s.data||s;this.#f(i),this.#o=null,e&&this.#u()}).catch(s=>{s.name!=="AbortError"&&console.error(s)})}#p(){if(this.#t.hasAttribute("placeholder"))return this.#t.getAttribute("placeholder");if(this.#t.dataset.placeholder)return this.#t.dataset.placeholder;let e=this.#t.querySelector("option");return e?(e.hasAttribute("selected")&&e.removeAttribute("selected"),e.value?"":e.textContent):""}#m(){this.#s.classList.add("dropdown-menu","p-0"),this.#s.style.maxHeight="280px",this.#s.style.overflowY="auto",this.#s.addEventListener("mouseenter",e=>{this.#a=!1})}#g(){this.#i.classList.add("form-control","dropdown"),this.#v()===4&&(this.#i.style.height="auto")}#b(){this.#l.addEventListener("click",t=>{this.isDisabled()||this.#e.style.visibility!="hidden"&&this.#e.focus()});let e=this.#t.selectedOptions;for(let t=0;t{if(e.data){let t=e.data.slice(-1);if(this.separator.length&&this.#e.value&&this.separator.includes(t)){this.#e.value=this.#e.value.slice(0,-1);let s=this.#e.value;if(!this.canAdd(s))return;this.addItem(s,null),this.#d();return}}this.#n(),this.#e.value.length>=this.suggestionsThreshold?this.liveServer?this.#c(!0):this.#u():this.#h()}),this.#e.addEventListener("focus",e=>{this.#e.value.length>=this.suggestionsThreshold&&this.#u()}),this.#e.addEventListener("focusout",e=>{this.#h()}),this.#e.addEventListener("keydown",e=>{switch(e.keyCode||e.key){case 13:case"Enter":e.preventDefault();let s=this.getActiveSelection();if(s)s.click();else if(this.allowNew&&this.#e.value){let l=this.#e.value;if(!this.canAdd(l))return;this.addItem(l,null),this.#d()}break;case 38:case"ArrowUp":e.preventDefault(),this.#a=!0;let i=this.#S();this.#e.value.length==0&&this.#s.classList.contains("show")&&!i&&this.#h();break;case 40:case"ArrowDown":e.preventDefault(),this.#a=!0,this.#A(),this.#e.value.length==0&&!this.#s.classList.contains("show")&&this.#u();break;case 8:case"Backspace":this.#e.value.length==0&&(this.removeLastItem(),this.#n(),this.#h());break;case 27:case"Escape":this.#h();break}})}#S(){let e=this.getActiveSelection();if(e){let t=e.parentNode;do t=t.previousSibling;while(t&&t.style.display=="none");return t?(e.classList.remove(...o),t.querySelector("a").classList.add(...o),t.parentNode.scrollTop=t.offsetTop-t.parentNode.offsetTop,t):null}return null}#A(){let e=this.getActiveSelection(),t=null;if(e){t=e.parentNode;do t=t.nextSibling;while(t&&t.style.display=="none");return t?(e.classList.remove(...o),t.querySelector("a").classList.add(...o),t.offsetTop>t.parentNode.offsetHeight-t.offsetHeight&&(t.parentNode.scrollTop+=t.offsetHeight),t):null}return t}#n(){this.#e.value?this.#e.size=this.#e.value.length+1:this.getSelectedValues().length?(this.#e.placeholder="",this.#e.size=1):(this.#e.size=this.placeholder.length>0?this.placeholder.length:1,this.#e.placeholder=this.placeholder)}#f(e=null){for(;this.#s.lastChild;)this.#s.removeChild(this.#s.lastChild);for(let t=0;t{this.#a||(this.removeActiveSelection(),i.querySelector("a").classList.add(...o))}),l.addEventListener("mousemove",r=>{this.#a=!1}),l.addEventListener("mousedown",r=>{r.preventDefault()}),l.addEventListener("click",r=>{r.preventDefault();let a=l.textContent;!this.canAdd(a,l.getAttribute(d))||(this.addItem(a,l.getAttribute(d),l.dataset),this.#d())})}}reset(){this.removeAll(),this.#r=!1;let e=this.#t.querySelectorAll("option[data-init]");for(let t=0;tt.value)}#u(){if(this.#e.style.visibility=="hidden")return;this.#s.style.left=this.#e.offsetLeft+"px";let e=this.#e.value.toLocaleLowerCase(),t=this.getSelectedValues(),s=this.#s.querySelectorAll("li"),i=!1,l=null,r=!1;for(let a=0;as.textContent==e);return!!(t&&t.getAttribute("selected"))}#L(e){return new RegExp(this.validationRegex.trim()).test(e)}getActiveSelection(){return this.#s.querySelector("a."+p)}removeActiveSelection(){let e=this.getActiveSelection();e&&e.classList.remove(...o)}removeAll(){this.getSelectedValues().forEach(t=>{this.removeItem(t)}),this.#n()}removeLastItem(e){e&&(this.#r=!1);let t=this.#l.querySelectorAll("span");if(!t.length)return;let s=t[t.length-1];this.removeItem(s.getAttribute(d)),this.#r=!0}isDisabled(){return this.#t.hasAttribute("disabled")||this.#t.disabled||this.#t.hasAttribute("readonly")}isInvalid(){return this.#i.classList.contains("is-invalid")}isSingle(){return!this.#t.hasAttribute("multiple")}canAdd(e,t=null){return t||(t=e),!e||this.isDisabled()||!this.isSingle()&&this.#w(t)||this.max&&this.getSelectedValues().length>=this.max?!1:this.validationRegex&&!this.#L(e)?(this.#i.classList.add("is-invalid"),!1):!0}addItem(e,t=null,s={}){t||(t=e),this.isSingle()&&this.getSelectedValues().length&&this.removeLastItem(!0);let i=this.#v(),l=this.#t.querySelector('option[value="'+t+'"]');l&&(s=l.dataset);let r=e,a=document.createElement("span"),n=["badge"],u=this.badgeStyle;if(s.badgeStyle&&(u=s.badgeStyle),s.badgeClass&&n.push(s.badgeClass),i===5?n=[...n,"me-2","bg-"+u]:n=[...n,"mr-2","badge-"+u],a.classList.add(...n),a.setAttribute(d,t),this.allowClear&&(r=(i===5?'':'')+r),a.innerHTML=r,this.#l.insertBefore(a,this.#e),this.allowClear&&a.querySelector("button").addEventListener("click",h=>{h.preventDefault(),h.stopPropagation(),this.isDisabled()||(this.removeItem(t),document.activeElement.blur(),this.#n())}),!l){l=document.createElement("option"),l.value=t,l.textContent=e;for(let[h,f]of Object.entries(s))l.dataset[h]=f;this.#t.appendChild(l)}l.setAttribute("selected","selected"),l.selected=!0,this.#r&&this.#t.dispatchEvent(new Event("change",{bubbles:!0}))}removeItem(e){let t=this.#l.querySelector("span["+d+'="'+e+'"]');if(!t)return;t.remove();let s=this.#t.querySelector('option[value="'+e+'"]');s&&(s.removeAttribute("selected"),s.selected=!1,this.#r&&this.#t.dispatchEvent(new Event("change",{bubbles:!0}))),this.#e.style.visibility=="hidden"&&this.max&&this.getSelectedValues().length [\"true\", \"false\", \"1\", \"0\", true, false].includes(value) && !!JSON.parse(value);\r\n\r\n // Handle options, using global settings first and data attr override\r\n const opts = { ...globalOpts, ...el.dataset };\r\n this.allowNew = opts.allowNew ? parseBool(opts.allowNew) : false;\r\n this.showAllSuggestions = opts.showAllSuggestions ? parseBool(opts.showAllSuggestions) : false;\r\n this.badgeStyle = opts.badgeStyle || \"primary\";\r\n this.allowClear = opts.allowClear ? parseBool(opts.allowClear) : false;\r\n this.server = opts.server || false;\r\n this.liveServer = opts.liveServer ? parseBool(opts.liveServer) : false;\r\n this.serverParams = opts.serverParams || {};\r\n if (typeof this.serverParams == \"string\") {\r\n this.serverParams = JSON.parse(this.serverParams);\r\n }\r\n this.suggestionsThreshold = typeof opts.suggestionsThreshold != \"undefined\" ? parseInt(opts.suggestionsThreshold) : 1;\r\n this.validationRegex = opts.regex || \"\";\r\n this.separator = opts.separator ? opts.separator.split(\"|\") : [];\r\n this.max = opts.max ? parseInt(opts.max) : null;\r\n this.clearLabel = opts.clearLabel || \"Clear\";\r\n this.searchLabel = opts.searchLabel || \"Type a value\";\r\n\r\n this.placeholder = this.#getPlaceholder();\r\n this.#keyboardNavigation = false;\r\n this.#fireEvents = true;\r\n\r\n this.parentForm = el.parentElement;\r\n while (this.parentForm) {\r\n this.parentForm = this.parentForm.parentElement;\r\n if (this.parentForm.nodeName == \"FORM\") {\r\n break;\r\n }\r\n }\r\n\r\n this.reset = this.reset.bind(this);\r\n this.parentForm.addEventListener(\"reset\", this.reset);\r\n\r\n // Create elements\r\n this.#holderElement = document.createElement(\"div\"); // this is the one holding the fake input and the dropmenu\r\n this.#containerElement = document.createElement(\"div\"); // this is the one for the fake input (labels + input)\r\n this.#dropElement = document.createElement(\"ul\");\r\n this.#searchInput = document.createElement(\"input\");\r\n\r\n this.#holderElement.appendChild(this.#containerElement);\r\n this.#containerElement.appendChild(this.#searchInput);\r\n this.#holderElement.appendChild(this.#dropElement);\r\n // insert after\r\n this.#selectElement.parentNode.insertBefore(this.#holderElement, this.#selectElement.nextSibling);\r\n\r\n // Configure them\r\n this.#configureHolderElement();\r\n this.#configureDropElement();\r\n this.#configureContainerElement();\r\n this.#configureSearchInput();\r\n this.resetState();\r\n\r\n if (this.server && !this.liveServer) {\r\n this.#loadFromServer();\r\n } else {\r\n this.resetSuggestions();\r\n }\r\n }\r\n\r\n /**\r\n * Attach to all elements matched by the selector\r\n * @param {string} selector\r\n * @param {Object} opts\r\n */\r\n static init(selector = \"select[multiple]\", opts = {}) {\r\n let list = document.querySelectorAll(selector);\r\n let el;\r\n for (let i = 0; i < list.length; i++) {\r\n if (!list[i].dataset.tags) {\r\n el = new Tags(list[i], opts);\r\n INSTANCE_MAP.set(list[i], el);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @param {HTMLSelectElement} el\r\n */\r\n static getInstance(el) {\r\n if (INSTANCE_MAP.has(el)) {\r\n return INSTANCE_MAP.get(el);\r\n }\r\n }\r\n\r\n dispose() {\r\n INSTANCE_MAP.delete(this.#selectElement);\r\n this.#selectElement.dataset.tags = null;\r\n this.#selectElement.style.display = \"block\";\r\n this.#holderElement.parentNode.removeChild(this.#holderElement);\r\n this.parentForm.removeEventListener(\"reset\", this.reset);\r\n }\r\n\r\n resetState() {\r\n if (this.isDisabled()) {\r\n this.#holderElement.setAttribute(\"readonly\", \"\");\r\n this.#searchInput.setAttribute(\"disabled\", \"\");\r\n } else {\r\n if (this.#holderElement.hasAttribute(\"readonly\")) {\r\n this.#holderElement.removeAttribute(\"readonly\");\r\n }\r\n if (this.#searchInput.hasAttribute(\"disabled\")) {\r\n this.#searchInput.removeAttribute(\"disabled\");\r\n }\r\n }\r\n }\r\n\r\n resetSuggestions() {\r\n let suggestions = Array.from(this.#selectElement.querySelectorAll(\"option\"))\r\n .filter((option) => {\r\n return !option.disabled;\r\n })\r\n .map((option) => {\r\n return {\r\n value: option.getAttribute(\"value\"),\r\n label: option.innerText,\r\n };\r\n });\r\n this.#buildSuggestions(suggestions);\r\n }\r\n\r\n /**\r\n * @param {boolean} show\r\n */\r\n #loadFromServer(show = false) {\r\n if (this.#abortController) {\r\n this.#abortController.abort();\r\n }\r\n this.#abortController = new AbortController();\r\n\r\n this.serverParams.query = this.#searchInput.value;\r\n const params = new URLSearchParams(this.serverParams).toString();\r\n\r\n fetch(this.server + \"?\" + params, { signal: this.#abortController.signal })\r\n .then((r) => r.json())\r\n .then((suggestions) => {\r\n let data = suggestions.data || suggestions;\r\n this.#buildSuggestions(data);\r\n this.#abortController = null;\r\n if (show) {\r\n this.#showSuggestions();\r\n }\r\n })\r\n .catch((e) => {\r\n if (e.name === \"AbortError\") {\r\n return;\r\n }\r\n console.error(e);\r\n });\r\n }\r\n\r\n /**\r\n * @returns {string}\r\n */\r\n #getPlaceholder() {\r\n // Use placeholder and data-placeholder in priority\r\n if (this.#selectElement.hasAttribute(\"placeholder\")) {\r\n return this.#selectElement.getAttribute(\"placeholder\");\r\n }\r\n if (this.#selectElement.dataset.placeholder) {\r\n return this.#selectElement.dataset.placeholder;\r\n }\r\n // Fallback to first option if no value\r\n let firstOption = this.#selectElement.querySelector(\"option\");\r\n if (!firstOption) {\r\n return \"\";\r\n }\r\n if (firstOption.hasAttribute(\"selected\")) {\r\n firstOption.removeAttribute(\"selected\");\r\n }\r\n return !firstOption.value ? firstOption.innerText : \"\";\r\n }\r\n\r\n #configureDropElement() {\r\n this.#dropElement.classList.add(...[\"dropdown-menu\", \"p-0\"]);\r\n this.#dropElement.style.maxHeight = \"280px\";\r\n this.#dropElement.style.overflowY = \"auto\";\r\n\r\n // If the mouse was outside, entering remove keyboard nav mode\r\n this.#dropElement.addEventListener(\"mouseenter\", (event) => {\r\n this.#keyboardNavigation = false;\r\n });\r\n }\r\n\r\n #configureHolderElement() {\r\n this.#holderElement.classList.add(...[\"form-control\", \"dropdown\"]);\r\n if (this.#getBootstrapVersion() === 4) {\r\n // Prevent fixed height due to form-control\r\n this.#holderElement.style.height = \"auto\";\r\n }\r\n }\r\n\r\n #configureContainerElement() {\r\n this.#containerElement.addEventListener(\"click\", (event) => {\r\n if (this.isDisabled()) {\r\n return;\r\n }\r\n if (this.#searchInput.style.visibility != \"hidden\") {\r\n this.#searchInput.focus();\r\n }\r\n });\r\n\r\n // add initial values\r\n // we use selectedOptions because single select can have a selected option\r\n // without a selected attribute if it's the first value\r\n let initialValues = this.#selectElement.selectedOptions;\r\n for (let j = 0; j < initialValues.length; j++) {\r\n let initialValue = initialValues[j];\r\n if (!initialValue.value) {\r\n continue;\r\n }\r\n // track initial values for reset\r\n initialValue.dataset.init = 1;\r\n this.addItem(initialValue.innerText, initialValue.value);\r\n }\r\n }\r\n\r\n #configureSearchInput() {\r\n this.#searchInput.type = \"text\";\r\n this.#searchInput.autocomplete = \"off\";\r\n this.#searchInput.spellcheck = false;\r\n this.#searchInput.style.backgroundColor = \"transparent\";\r\n this.#searchInput.style.border = 0;\r\n this.#searchInput.style.outline = 0;\r\n this.#searchInput.style.maxWidth = \"100%\";\r\n this.#searchInput.ariaLabel = this.searchLabel;\r\n this.#resetSearchInput(true);\r\n\r\n this.#searchInput.addEventListener(\"input\", (event) => {\r\n // Add item if a separator is used\r\n // On mobile or copy paste, it can pass multiple chars (eg: when pressing space and it formats the string)\r\n if (event.data) {\r\n const lastChar = event.data.slice(-1);\r\n if (this.separator.length && this.#searchInput.value && this.separator.includes(lastChar)) {\r\n let text = this.#searchInput.value.slice(0, -1);\r\n if (!this.canAdd(text)) {\r\n return;\r\n }\r\n this.addItem(text, null);\r\n this.#resetSearchInput();\r\n return;\r\n }\r\n }\r\n\r\n // Adjust input width to current content\r\n this.#adjustWidth();\r\n\r\n // Check if we should display suggestions\r\n if (this.#searchInput.value.length >= this.suggestionsThreshold) {\r\n if (this.liveServer) {\r\n this.#loadFromServer(true);\r\n } else {\r\n this.#showSuggestions();\r\n }\r\n } else {\r\n this.#hideSuggestions();\r\n }\r\n });\r\n this.#searchInput.addEventListener(\"focus\", (event) => {\r\n if (this.#searchInput.value.length >= this.suggestionsThreshold) {\r\n this.#showSuggestions();\r\n }\r\n });\r\n this.#searchInput.addEventListener(\"focusout\", (event) => {\r\n this.#hideSuggestions();\r\n });\r\n // keypress doesn't send arrow keys, so we use keydown\r\n this.#searchInput.addEventListener(\"keydown\", (event) => {\r\n // Keycode reference : https://css-tricks.com/snippets/javascript/javascript-keycodes/\r\n let key = event.keyCode || event.key;\r\n\r\n // Keyboard keys\r\n switch (key) {\r\n case 13:\r\n case \"Enter\":\r\n event.preventDefault();\r\n let selection = this.getActiveSelection();\r\n if (selection) {\r\n selection.click();\r\n } else {\r\n // We use what is typed if not selected and not empty\r\n if (this.allowNew && !this.#isSelected(this.#searchInput.value) && this.#searchInput.value) {\r\n let text = this.#searchInput.value;\r\n if (!this.canAdd(text)) {\r\n return;\r\n }\r\n this.addItem(text, null);\r\n this.#resetSearchInput();\r\n }\r\n }\r\n break;\r\n case 38:\r\n case \"ArrowUp\":\r\n event.preventDefault();\r\n this.#keyboardNavigation = true;\r\n let newSelection = this.#moveSelectionUp();\r\n // If we use arrow up without input and there is no new selection, hide suggestions\r\n if (this.#searchInput.value.length == 0 && this.#dropElement.classList.contains(\"show\") && !newSelection) {\r\n this.#hideSuggestions();\r\n }\r\n break;\r\n case 40:\r\n case \"ArrowDown\":\r\n event.preventDefault();\r\n this.#keyboardNavigation = true;\r\n this.#moveSelectionDown();\r\n // If we use arrow down without input, show suggestions\r\n if (this.#searchInput.value.length == 0 && !this.#dropElement.classList.contains(\"show\")) {\r\n this.#showSuggestions();\r\n }\r\n break;\r\n case 8:\r\n case \"Backspace\":\r\n if (this.#searchInput.value.length == 0) {\r\n this.removeLastItem();\r\n this.#adjustWidth();\r\n this.#hideSuggestions();\r\n }\r\n break;\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * @returns {HTMLElement}\r\n */\r\n #moveSelectionUp() {\r\n let active = this.getActiveSelection();\r\n if (active) {\r\n let prev = active.parentNode;\r\n do {\r\n prev = prev.previousSibling;\r\n } while (prev && prev.style.display == \"none\");\r\n if (!prev) {\r\n return null;\r\n }\r\n active.classList.remove(...ACTIVE_CLASSES);\r\n prev.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n // Don't use scrollIntoView as it scrolls the whole window\r\n prev.parentNode.scrollTop = prev.offsetTop - prev.parentNode.offsetTop;\r\n return prev;\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * @returns {HTMLElement}\r\n */\r\n #moveSelectionDown() {\r\n let active = this.getActiveSelection();\r\n let next = null;\r\n if (active) {\r\n next = active.parentNode;\r\n do {\r\n next = next.nextSibling;\r\n } while (next && next.style.display == \"none\");\r\n if (!next) {\r\n return null;\r\n }\r\n active.classList.remove(...ACTIVE_CLASSES);\r\n next.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n // This is the equivalent of scrollIntoView(false) but only for parent node\r\n if (next.offsetTop > next.parentNode.offsetHeight - next.offsetHeight) {\r\n next.parentNode.scrollTop += next.offsetHeight;\r\n }\r\n return next;\r\n }\r\n return next;\r\n }\r\n\r\n /**\r\n * Adjust the field to fit its content and show/hide placeholder if needed\r\n */\r\n #adjustWidth() {\r\n if (this.#searchInput.value) {\r\n this.#searchInput.size = this.#searchInput.value.length + 1;\r\n } else {\r\n // Show the placeholder only if empty\r\n if (this.getSelectedValues().length) {\r\n this.#searchInput.placeholder = \"\";\r\n this.#searchInput.size = 1;\r\n } else {\r\n this.#searchInput.size = this.placeholder.length > 0 ? this.placeholder.length : 1;\r\n this.#searchInput.placeholder = this.placeholder;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Add suggestions to the drop element\r\n * @param {array}\r\n */\r\n #buildSuggestions(suggestions = null) {\r\n while (this.#dropElement.lastChild) {\r\n this.#dropElement.removeChild(this.#dropElement.lastChild);\r\n }\r\n for (let i = 0; i < suggestions.length; i++) {\r\n let suggestion = suggestions[i];\r\n if (!suggestion.value) {\r\n continue;\r\n }\r\n let newChild = document.createElement(\"li\");\r\n let newChildLink = document.createElement(\"a\");\r\n newChild.append(newChildLink);\r\n newChildLink.classList.add(\"dropdown-item\");\r\n newChildLink.setAttribute(VALUE_ATTRIBUTE, suggestion.value);\r\n newChildLink.setAttribute(\"href\", \"#\");\r\n newChildLink.innerText = suggestion.label;\r\n if (suggestion.data) {\r\n for (const [key, value] of Object.entries(suggestion.data)) {\r\n newChildLink.dataset[key] = value;\r\n }\r\n }\r\n this.#dropElement.appendChild(newChild);\r\n\r\n // Hover sets active item\r\n newChildLink.addEventListener(\"mouseenter\", (event) => {\r\n // Don't trigger enter if using arrows\r\n if (this.#keyboardNavigation) {\r\n return;\r\n }\r\n this.removeActiveSelection();\r\n newChild.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n });\r\n // Moving the mouse means no longer using keyboard\r\n newChildLink.addEventListener(\"mousemove\", (event) => {\r\n this.#keyboardNavigation = false;\r\n });\r\n\r\n newChildLink.addEventListener(\"mousedown\", (event) => {\r\n // Otherwise searchInput would lose focus and close the menu\r\n event.preventDefault();\r\n });\r\n newChildLink.addEventListener(\"click\", (event) => {\r\n event.preventDefault();\r\n let text = newChildLink.innerText;\r\n if (!this.canAdd(text)) {\r\n return;\r\n }\r\n this.addItem(text, newChildLink.getAttribute(VALUE_ATTRIBUTE), newChildLink.dataset);\r\n this.#resetSearchInput();\r\n });\r\n }\r\n }\r\n\r\n reset() {\r\n this.removeAll();\r\n\r\n // Reset doesn't fire change event\r\n this.#fireEvents = false;\r\n let initialValues = this.#selectElement.querySelectorAll(\"option[data-init]\");\r\n for (let j = 0; j < initialValues.length; j++) {\r\n let initialValue = initialValues[j];\r\n this.addItem(initialValue.innerText, initialValue.value);\r\n }\r\n this.#adjustWidth();\r\n this.#fireEvents = true;\r\n }\r\n\r\n #resetSearchInput(init = false) {\r\n this.#searchInput.value = \"\";\r\n this.#adjustWidth();\r\n\r\n if (!init) {\r\n this.#hideSuggestions();\r\n // Trigger input even to show suggestions if needed\r\n this.#searchInput.dispatchEvent(new Event(\"input\"));\r\n }\r\n\r\n // We use visibility instead of display to keep layout intact\r\n if (this.max && this.getSelectedValues().length === this.max) {\r\n this.#searchInput.style.visibility = \"hidden\";\r\n } else if (this.#searchInput.style.visibility == \"hidden\") {\r\n this.#searchInput.style.visibility = \"visible\";\r\n }\r\n\r\n if (this.isSingle() && !init) {\r\n document.activeElement.blur();\r\n }\r\n }\r\n\r\n /**\r\n * @returns {array}\r\n */\r\n getSelectedValues() {\r\n // option[selected] is used rather that selectedOptions as it works more consistently\r\n let selected = this.#selectElement.querySelectorAll(\"option[selected]\");\r\n return Array.from(selected).map((el) => el.value);\r\n }\r\n\r\n /**\r\n * The element create with buildSuggestions\r\n */\r\n #showSuggestions() {\r\n if (this.#searchInput.style.visibility == \"hidden\") {\r\n return;\r\n }\r\n\r\n // Position next to search input\r\n this.#dropElement.style.left = this.#searchInput.offsetLeft + \"px\";\r\n\r\n // Get search value\r\n let search = this.#searchInput.value.toLocaleLowerCase();\r\n\r\n // Get current values\r\n let values = this.getSelectedValues();\r\n\r\n // Filter the list according to search string\r\n let list = this.#dropElement.querySelectorAll(\"li\");\r\n let found = false;\r\n let firstItem = null;\r\n let hasPossibleValues = false;\r\n for (let i = 0; i < list.length; i++) {\r\n let item = list[i];\r\n let text = item.innerText.toLocaleLowerCase();\r\n let link = item.querySelector(\"a\");\r\n\r\n // Remove previous selection\r\n link.classList.remove(...ACTIVE_CLASSES);\r\n\r\n // Hide selected values\r\n if (values.indexOf(link.getAttribute(VALUE_ATTRIBUTE)) != -1) {\r\n item.style.display = \"none\";\r\n continue;\r\n }\r\n\r\n hasPossibleValues = true;\r\n\r\n // Check search length since we can trigger dropdown with arrow\r\n let isMatched = search.length === 0 || text.indexOf(search) !== -1;\r\n if (this.showAllSuggestions || this.suggestionsThreshold === 0 || isMatched) {\r\n item.style.display = \"list-item\";\r\n found = true;\r\n if (!firstItem && isMatched) {\r\n firstItem = item;\r\n }\r\n } else {\r\n item.style.display = \"none\";\r\n }\r\n }\r\n\r\n // Always select first item\r\n if (firstItem) {\r\n this.#holderElement.classList.remove(\"is-invalid\");\r\n firstItem.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n firstItem.parentNode.scrollTop = firstItem.offsetTop - firstItem.parentNode.offsetTop;\r\n } else {\r\n // No item and we don't allow new items => error\r\n if (!this.allowNew && !(search.length === 0 && !hasPossibleValues)) {\r\n this.#holderElement.classList.add(\"is-invalid\");\r\n } else if (this.validationRegex && this.isInvalid()) {\r\n this.#holderElement.classList.remove(\"is-invalid\");\r\n }\r\n }\r\n\r\n // Remove dropdown if not found or to show validation message\r\n if (!found || this.isInvalid()) {\r\n this.#dropElement.classList.remove(\"show\");\r\n } else {\r\n // Or show it if necessary\r\n this.#dropElement.classList.add(\"show\");\r\n }\r\n }\r\n\r\n /**\r\n * The element create with buildSuggestions\r\n */\r\n #hideSuggestions() {\r\n this.#dropElement.classList.remove(\"show\");\r\n this.#holderElement.classList.remove(\"is-invalid\");\r\n this.removeActiveSelection();\r\n }\r\n\r\n /**\r\n * @returns {Number}\r\n */\r\n #getBootstrapVersion() {\r\n let ver = 5;\r\n // If we have jQuery and the tooltip plugin for BS4\r\n if (window.jQuery && $.fn.tooltip != undefined && $.fn.tooltip.Constructor != undefined) {\r\n ver = parseInt($.fn.tooltip.Constructor.VERSION.charAt(0));\r\n }\r\n return ver;\r\n }\r\n\r\n /**\r\n * Find if label is already selected (based on attribute)\r\n * @param {string} text\r\n * @returns {boolean}\r\n */\r\n #isSelected(text) {\r\n const opt = Array.from(this.#selectElement.querySelectorAll(\"option\")).find((el) => el.textContent == text);\r\n if (opt && opt.getAttribute(\"selected\")) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Checks if value matches a configured regex\r\n * @param {string} value\r\n * @returns {boolean}\r\n */\r\n #validateRegex(value) {\r\n const regex = new RegExp(this.validationRegex.trim());\r\n return regex.test(value);\r\n }\r\n\r\n /**\r\n * @returns {HTMLElement}\r\n */\r\n getActiveSelection() {\r\n return this.#dropElement.querySelector(\"a.\" + ACTIVE_CLASS);\r\n }\r\n\r\n removeActiveSelection() {\r\n let selection = this.getActiveSelection();\r\n if (selection) {\r\n selection.classList.remove(...ACTIVE_CLASSES);\r\n }\r\n }\r\n\r\n removeAll() {\r\n let items = this.getSelectedValues();\r\n items.forEach((item) => {\r\n this.removeItem(item);\r\n });\r\n this.#adjustWidth();\r\n }\r\n\r\n /**\r\n * @param {boolean} noEvents\r\n */\r\n removeLastItem(noEvents) {\r\n if (noEvents) {\r\n this.#fireEvents = false;\r\n }\r\n let items = this.#containerElement.querySelectorAll(\"span\");\r\n if (!items.length) {\r\n return;\r\n }\r\n let lastItem = items[items.length - 1];\r\n this.removeItem(lastItem.getAttribute(VALUE_ATTRIBUTE));\r\n this.#fireEvents = true;\r\n }\r\n\r\n /**\r\n * @returns {boolean}\r\n */\r\n isDisabled() {\r\n return this.#selectElement.hasAttribute(\"disabled\") || this.#selectElement.disabled || this.#selectElement.hasAttribute(\"readonly\");\r\n }\r\n\r\n /**\r\n * @returns {boolean}\r\n */\r\n isInvalid() {\r\n return this.#holderElement.classList.contains(\"is-invalid\");\r\n }\r\n\r\n /**\r\n * @returns {boolean}\r\n */\r\n isSingle() {\r\n return !this.#selectElement.hasAttribute(\"multiple\");\r\n }\r\n\r\n /**\r\n * @param {string} text\r\n * @returns {boolean}\r\n */\r\n canAdd(text) {\r\n if (!text) {\r\n return false;\r\n }\r\n // Check for max\r\n if (this.max && this.getSelectedValues().length >= this.max) {\r\n return false;\r\n }\r\n // Check for regex\r\n if (this.validationRegex && !this.#validateRegex(text)) {\r\n this.#holderElement.classList.add(\"is-invalid\");\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * You might want to use canAdd before to ensure the item is valid\r\n * @param {string} text\r\n * @param {string} value\r\n * @param {object} data\r\n */\r\n addItem(text, value = null, data = {}) {\r\n if (!value) {\r\n value = text;\r\n }\r\n\r\n // Single items remove first\r\n if (this.isSingle() && this.getSelectedValues().length) {\r\n this.removeLastItem(true);\r\n }\r\n\r\n const bver = this.#getBootstrapVersion();\r\n let opt = this.#selectElement.querySelector('option[value=\"' + value + '\"]');\r\n if (opt) {\r\n data = opt.dataset;\r\n }\r\n\r\n // create span\r\n let html = text;\r\n let span = document.createElement(\"span\");\r\n let classes = [\"badge\"];\r\n let badgeStyle = this.badgeStyle;\r\n if (data.badgeStyle) {\r\n badgeStyle = data.badgeStyle;\r\n }\r\n if (data.badgeClass) {\r\n classes.push(data.badgeClass);\r\n }\r\n if (bver === 5) {\r\n //https://getbootstrap.com/docs/5.1/components/badge/\r\n classes = [...classes, ...[\"me-2\", \"bg-\" + badgeStyle]];\r\n } else {\r\n // https://getbootstrap.com/docs/4.6/components/badge/\r\n classes = [...classes, ...[\"mr-2\", \"badge-\" + badgeStyle]];\r\n }\r\n span.classList.add(...classes);\r\n span.setAttribute(VALUE_ATTRIBUTE, value);\r\n\r\n if (this.allowClear) {\r\n const btn =\r\n bver === 5\r\n ? ''\r\n : '';\r\n html = btn + html;\r\n }\r\n\r\n span.innerHTML = html;\r\n this.#containerElement.insertBefore(span, this.#searchInput);\r\n\r\n if (this.allowClear) {\r\n span.querySelector(\"button\").addEventListener(\"click\", (event) => {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n if (!this.isDisabled()) {\r\n this.removeItem(value);\r\n document.activeElement.blur();\r\n this.#adjustWidth();\r\n }\r\n });\r\n }\r\n\r\n // we need to create a new option\r\n if (!opt) {\r\n opt = document.createElement(\"option\");\r\n opt.value = value;\r\n opt.innerText = text;\r\n // Pass along data provided\r\n for (const [key, value] of Object.entries(data)) {\r\n opt.dataset[key] = value;\r\n }\r\n this.#selectElement.appendChild(opt);\r\n }\r\n\r\n // update select, we need to set attribute for option[selected]\r\n opt.setAttribute(\"selected\", \"selected\");\r\n opt.selected = true;\r\n\r\n // Fire change event\r\n if (this.#fireEvents) {\r\n this.#selectElement.dispatchEvent(new Event(\"change\", { bubbles: true }));\r\n }\r\n }\r\n\r\n /**\r\n * @param {string} value\r\n */\r\n removeItem(value) {\r\n let item = this.#containerElement.querySelector(\"span[\" + VALUE_ATTRIBUTE + '=\"' + value + '\"]');\r\n if (!item) {\r\n return;\r\n }\r\n item.remove();\r\n\r\n // update select\r\n let opt = this.#selectElement.querySelector('option[value=\"' + value + '\"]');\r\n if (opt) {\r\n opt.removeAttribute(\"selected\");\r\n opt.selected = false;\r\n\r\n // Fire change event\r\n if (this.#fireEvents) {\r\n this.#selectElement.dispatchEvent(new Event(\"change\", { bubbles: true }));\r\n }\r\n }\r\n\r\n // Make input visible\r\n if (this.#searchInput.style.visibility == \"hidden\" && this.max && this.getSelectedValues().length < this.max) {\r\n this.#searchInput.style.visibility = \"visible\";\r\n }\r\n }\r\n}\r\n\r\nexport default Tags;\r\n"], - "mappings": "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", + "sourcesContent": ["/**\r\n * Bootstrap 5 (and 4!) tags\r\n *\r\n * Turns your select[multiple] into nice tags lists\r\n *\r\n * Required Bootstrap 5 styles:\r\n * - badge\r\n * - background-color utility\r\n * - margin-end utility\r\n * - float-start utility\r\n * - forms\r\n * - dropdown\r\n */\r\n\r\nconst ACTIVE_CLASS = \"is-active\";\r\nconst ACTIVE_CLASSES = [\"is-active\", \"bg-primary\", \"text-white\"];\r\nconst VALUE_ATTRIBUTE = \"data-value\";\r\n\r\n// Static map will minify very badly as class prop, so we use an external constant\r\nconst INSTANCE_MAP = new WeakMap();\r\n\r\nclass Tags {\r\n #abortController;\r\n #selectElement;\r\n #holderElement;\r\n #containerElement;\r\n #dropElement;\r\n #searchInput;\r\n #keyboardNavigation;\r\n #fireEvents;\r\n\r\n /**\r\n * @param {HTMLSelectElement} el\r\n * @param {Object} globalOpts\r\n */\r\n constructor(el, globalOpts = {}) {\r\n // Hide the select element and register a tags attr\r\n el.style.display = \"none\";\r\n INSTANCE_MAP.set(el, this);\r\n this.#selectElement = el;\r\n\r\n // Allow 1/0, true/false as strings\r\n const parseBool = (value) => [\"true\", \"false\", \"1\", \"0\", true, false].includes(value) && !!JSON.parse(value);\r\n\r\n // Handle options, using global settings first and data attr override\r\n const opts = { ...globalOpts, ...el.dataset };\r\n this.allowNew = opts.allowNew ? parseBool(opts.allowNew) : false;\r\n this.showAllSuggestions = opts.showAllSuggestions ? parseBool(opts.showAllSuggestions) : false;\r\n this.badgeStyle = opts.badgeStyle || \"primary\";\r\n this.allowClear = opts.allowClear ? parseBool(opts.allowClear) : false;\r\n this.server = opts.server || false;\r\n this.liveServer = opts.liveServer ? parseBool(opts.liveServer) : false;\r\n this.serverParams = opts.serverParams || {};\r\n if (typeof this.serverParams == \"string\") {\r\n this.serverParams = JSON.parse(this.serverParams);\r\n }\r\n this.suggestionsThreshold = typeof opts.suggestionsThreshold != \"undefined\" ? parseInt(opts.suggestionsThreshold) : 1;\r\n this.validationRegex = opts.regex || \"\";\r\n this.separator = opts.separator ? opts.separator.split(\"|\") : [];\r\n this.max = opts.max ? parseInt(opts.max) : null;\r\n this.clearLabel = opts.clearLabel || \"Clear\";\r\n this.searchLabel = opts.searchLabel || \"Type a value\";\r\n\r\n this.placeholder = this.#getPlaceholder();\r\n this.#keyboardNavigation = false;\r\n this.#fireEvents = true;\r\n\r\n this.parentForm = el.parentElement;\r\n while (this.parentForm) {\r\n this.parentForm = this.parentForm.parentElement;\r\n if (this.parentForm && this.parentForm.nodeName == \"FORM\") {\r\n break;\r\n }\r\n }\r\n this.reset = this.reset.bind(this);\r\n if (this.parentForm) {\r\n this.parentForm.addEventListener(\"reset\", this.reset);\r\n }\r\n\r\n // Create elements\r\n this.#holderElement = document.createElement(\"div\"); // this is the one holding the fake input and the dropmenu\r\n this.#containerElement = document.createElement(\"div\"); // this is the one for the fake input (labels + input)\r\n this.#dropElement = document.createElement(\"ul\");\r\n this.#searchInput = document.createElement(\"input\");\r\n\r\n this.#holderElement.appendChild(this.#containerElement);\r\n this.#containerElement.appendChild(this.#searchInput);\r\n this.#holderElement.appendChild(this.#dropElement);\r\n // insert after\r\n this.#selectElement.parentNode.insertBefore(this.#holderElement, this.#selectElement.nextSibling);\r\n\r\n // Configure them\r\n this.#configureHolderElement();\r\n this.#configureDropElement();\r\n this.#configureContainerElement();\r\n this.#configureSearchInput();\r\n this.resetState();\r\n\r\n if (this.server && !this.liveServer) {\r\n this.#loadFromServer();\r\n } else {\r\n this.resetSuggestions();\r\n }\r\n }\r\n\r\n /**\r\n * Attach to all elements matched by the selector\r\n * @param {string} selector\r\n * @param {Object} opts\r\n */\r\n static init(selector = \"select[multiple]\", opts = {}) {\r\n let list = document.querySelectorAll(selector);\r\n for (let i = 0; i < list.length; i++) {\r\n if (Tags.getInstance(list[i])) {\r\n continue;\r\n }\r\n new Tags(list[i], opts);\r\n }\r\n }\r\n\r\n /**\r\n * @param {HTMLSelectElement} el\r\n */\r\n static getInstance(el) {\r\n if (INSTANCE_MAP.has(el)) {\r\n return INSTANCE_MAP.get(el);\r\n }\r\n }\r\n\r\n dispose() {\r\n INSTANCE_MAP.delete(this.#selectElement);\r\n this.#selectElement.style.display = \"block\";\r\n this.#holderElement.parentNode.removeChild(this.#holderElement);\r\n if (this.parentForm) {\r\n this.parentForm.removeEventListener(\"reset\", this.reset);\r\n }\r\n }\r\n\r\n resetState() {\r\n if (this.isDisabled()) {\r\n this.#holderElement.setAttribute(\"readonly\", \"\");\r\n this.#searchInput.setAttribute(\"disabled\", \"\");\r\n } else {\r\n if (this.#holderElement.hasAttribute(\"readonly\")) {\r\n this.#holderElement.removeAttribute(\"readonly\");\r\n }\r\n if (this.#searchInput.hasAttribute(\"disabled\")) {\r\n this.#searchInput.removeAttribute(\"disabled\");\r\n }\r\n }\r\n }\r\n\r\n resetSuggestions() {\r\n let suggestions = Array.from(this.#selectElement.querySelectorAll(\"option\"))\r\n .filter((option) => {\r\n return !option.disabled;\r\n })\r\n .map((option) => {\r\n return {\r\n value: option.getAttribute(\"value\"),\r\n label: option.textContent,\r\n };\r\n });\r\n this.#buildSuggestions(suggestions);\r\n }\r\n\r\n /**\r\n * @param {boolean} show\r\n */\r\n #loadFromServer(show = false) {\r\n if (this.#abortController) {\r\n this.#abortController.abort();\r\n }\r\n this.#abortController = new AbortController();\r\n\r\n this.serverParams.query = this.#searchInput.value;\r\n const params = new URLSearchParams(this.serverParams).toString();\r\n\r\n fetch(this.server + \"?\" + params, { signal: this.#abortController.signal })\r\n .then((r) => r.json())\r\n .then((suggestions) => {\r\n let data = suggestions.data || suggestions;\r\n this.#buildSuggestions(data);\r\n this.#abortController = null;\r\n if (show) {\r\n this.#showSuggestions();\r\n }\r\n })\r\n .catch((e) => {\r\n if (e.name === \"AbortError\") {\r\n return;\r\n }\r\n console.error(e);\r\n });\r\n }\r\n\r\n /**\r\n * @returns {string}\r\n */\r\n #getPlaceholder() {\r\n // Use placeholder and data-placeholder in priority\r\n if (this.#selectElement.hasAttribute(\"placeholder\")) {\r\n return this.#selectElement.getAttribute(\"placeholder\");\r\n }\r\n if (this.#selectElement.dataset.placeholder) {\r\n return this.#selectElement.dataset.placeholder;\r\n }\r\n // Fallback to first option if no value\r\n let firstOption = this.#selectElement.querySelector(\"option\");\r\n if (!firstOption) {\r\n return \"\";\r\n }\r\n if (firstOption.hasAttribute(\"selected\")) {\r\n firstOption.removeAttribute(\"selected\");\r\n }\r\n return !firstOption.value ? firstOption.textContent : \"\";\r\n }\r\n\r\n #configureDropElement() {\r\n this.#dropElement.classList.add(...[\"dropdown-menu\", \"p-0\"]);\r\n this.#dropElement.style.maxHeight = \"280px\";\r\n this.#dropElement.style.overflowY = \"auto\";\r\n\r\n // If the mouse was outside, entering remove keyboard nav mode\r\n this.#dropElement.addEventListener(\"mouseenter\", (event) => {\r\n this.#keyboardNavigation = false;\r\n });\r\n }\r\n\r\n #configureHolderElement() {\r\n this.#holderElement.classList.add(...[\"form-control\", \"dropdown\"]);\r\n if (this.#getBootstrapVersion() === 4) {\r\n // Prevent fixed height due to form-control\r\n this.#holderElement.style.height = \"auto\";\r\n }\r\n }\r\n\r\n #configureContainerElement() {\r\n this.#containerElement.addEventListener(\"click\", (event) => {\r\n if (this.isDisabled()) {\r\n return;\r\n }\r\n if (this.#searchInput.style.visibility != \"hidden\") {\r\n this.#searchInput.focus();\r\n }\r\n });\r\n\r\n // add initial values\r\n // we use selectedOptions because single select can have a selected option\r\n // without a selected attribute if it's the first value\r\n let initialValues = this.#selectElement.selectedOptions;\r\n for (let j = 0; j < initialValues.length; j++) {\r\n let initialValue = initialValues[j];\r\n if (!initialValue.value) {\r\n continue;\r\n }\r\n // track initial values for reset\r\n initialValue.dataset.init = 1;\r\n this.addItem(initialValue.textContent, initialValue.value);\r\n }\r\n }\r\n\r\n #configureSearchInput() {\r\n this.#searchInput.type = \"text\";\r\n this.#searchInput.autocomplete = \"off\";\r\n this.#searchInput.spellcheck = false;\r\n this.#searchInput.style.backgroundColor = \"transparent\";\r\n this.#searchInput.style.border = 0;\r\n this.#searchInput.style.outline = 0;\r\n this.#searchInput.style.maxWidth = \"100%\";\r\n this.#searchInput.ariaLabel = this.searchLabel;\r\n this.#resetSearchInput(true);\r\n\r\n this.#searchInput.addEventListener(\"input\", (event) => {\r\n // Add item if a separator is used\r\n // On mobile or copy paste, it can pass multiple chars (eg: when pressing space and it formats the string)\r\n if (event.data) {\r\n const lastChar = event.data.slice(-1);\r\n if (this.separator.length && this.#searchInput.value && this.separator.includes(lastChar)) {\r\n // Remove separator even if adding is prevented\r\n this.#searchInput.value = this.#searchInput.value.slice(0, -1);\r\n let text = this.#searchInput.value;\r\n if (!this.canAdd(text)) {\r\n return;\r\n }\r\n this.addItem(text, null);\r\n this.#resetSearchInput();\r\n return;\r\n }\r\n }\r\n\r\n // Adjust input width to current content\r\n this.#adjustWidth();\r\n\r\n // Check if we should display suggestions\r\n if (this.#searchInput.value.length >= this.suggestionsThreshold) {\r\n if (this.liveServer) {\r\n this.#loadFromServer(true);\r\n } else {\r\n this.#showSuggestions();\r\n }\r\n } else {\r\n this.#hideSuggestions();\r\n }\r\n });\r\n this.#searchInput.addEventListener(\"focus\", (event) => {\r\n if (this.#searchInput.value.length >= this.suggestionsThreshold) {\r\n this.#showSuggestions();\r\n }\r\n });\r\n this.#searchInput.addEventListener(\"focusout\", (event) => {\r\n this.#hideSuggestions();\r\n });\r\n // keypress doesn't send arrow keys, so we use keydown\r\n this.#searchInput.addEventListener(\"keydown\", (event) => {\r\n // Keycode reference : https://css-tricks.com/snippets/javascript/javascript-keycodes/\r\n let key = event.keyCode || event.key;\r\n\r\n // Keyboard keys\r\n switch (key) {\r\n case 13:\r\n case \"Enter\":\r\n event.preventDefault();\r\n let selection = this.getActiveSelection();\r\n if (selection) {\r\n selection.click();\r\n } else {\r\n // We use what is typed if not selected and not empty\r\n if (this.allowNew && this.#searchInput.value) {\r\n let text = this.#searchInput.value;\r\n if (!this.canAdd(text)) {\r\n return;\r\n }\r\n this.addItem(text, null);\r\n this.#resetSearchInput();\r\n }\r\n }\r\n break;\r\n case 38:\r\n case \"ArrowUp\":\r\n event.preventDefault();\r\n this.#keyboardNavigation = true;\r\n let newSelection = this.#moveSelectionUp();\r\n // If we use arrow up without input and there is no new selection, hide suggestions\r\n if (this.#searchInput.value.length == 0 && this.#dropElement.classList.contains(\"show\") && !newSelection) {\r\n this.#hideSuggestions();\r\n }\r\n break;\r\n case 40:\r\n case \"ArrowDown\":\r\n event.preventDefault();\r\n this.#keyboardNavigation = true;\r\n this.#moveSelectionDown();\r\n // If we use arrow down without input, show suggestions\r\n if (this.#searchInput.value.length == 0 && !this.#dropElement.classList.contains(\"show\")) {\r\n this.#showSuggestions();\r\n }\r\n break;\r\n case 8:\r\n case \"Backspace\":\r\n if (this.#searchInput.value.length == 0) {\r\n this.removeLastItem();\r\n this.#adjustWidth();\r\n this.#hideSuggestions();\r\n }\r\n break;\r\n case 27:\r\n case \"Escape\":\r\n // We may wish to not use the suggestions\r\n this.#hideSuggestions();\r\n break;\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * @returns {HTMLElement}\r\n */\r\n #moveSelectionUp() {\r\n let active = this.getActiveSelection();\r\n if (active) {\r\n let prev = active.parentNode;\r\n do {\r\n prev = prev.previousSibling;\r\n } while (prev && prev.style.display == \"none\");\r\n if (!prev) {\r\n return null;\r\n }\r\n active.classList.remove(...ACTIVE_CLASSES);\r\n prev.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n // Don't use scrollIntoView as it scrolls the whole window\r\n prev.parentNode.scrollTop = prev.offsetTop - prev.parentNode.offsetTop;\r\n return prev;\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * @returns {HTMLElement}\r\n */\r\n #moveSelectionDown() {\r\n let active = this.getActiveSelection();\r\n let next = null;\r\n if (active) {\r\n next = active.parentNode;\r\n do {\r\n next = next.nextSibling;\r\n } while (next && next.style.display == \"none\");\r\n if (!next) {\r\n return null;\r\n }\r\n active.classList.remove(...ACTIVE_CLASSES);\r\n next.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n // This is the equivalent of scrollIntoView(false) but only for parent node\r\n if (next.offsetTop > next.parentNode.offsetHeight - next.offsetHeight) {\r\n next.parentNode.scrollTop += next.offsetHeight;\r\n }\r\n return next;\r\n }\r\n return next;\r\n }\r\n\r\n /**\r\n * Adjust the field to fit its content and show/hide placeholder if needed\r\n */\r\n #adjustWidth() {\r\n if (this.#searchInput.value) {\r\n this.#searchInput.size = this.#searchInput.value.length + 1;\r\n } else {\r\n // Show the placeholder only if empty\r\n if (this.getSelectedValues().length) {\r\n this.#searchInput.placeholder = \"\";\r\n this.#searchInput.size = 1;\r\n } else {\r\n this.#searchInput.size = this.placeholder.length > 0 ? this.placeholder.length : 1;\r\n this.#searchInput.placeholder = this.placeholder;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Add suggestions to the drop element\r\n * @param {array}\r\n */\r\n #buildSuggestions(suggestions = null) {\r\n while (this.#dropElement.lastChild) {\r\n this.#dropElement.removeChild(this.#dropElement.lastChild);\r\n }\r\n for (let i = 0; i < suggestions.length; i++) {\r\n let suggestion = suggestions[i];\r\n if (!suggestion.value) {\r\n continue;\r\n }\r\n let newChild = document.createElement(\"li\");\r\n let newChildLink = document.createElement(\"a\");\r\n newChild.append(newChildLink);\r\n newChildLink.classList.add(\"dropdown-item\");\r\n newChildLink.setAttribute(VALUE_ATTRIBUTE, suggestion.value);\r\n newChildLink.setAttribute(\"href\", \"#\");\r\n newChildLink.textContent = suggestion.label;\r\n if (suggestion.data) {\r\n for (const [key, value] of Object.entries(suggestion.data)) {\r\n newChildLink.dataset[key] = value;\r\n }\r\n }\r\n this.#dropElement.appendChild(newChild);\r\n\r\n // Hover sets active item\r\n newChildLink.addEventListener(\"mouseenter\", (event) => {\r\n // Don't trigger enter if using arrows\r\n if (this.#keyboardNavigation) {\r\n return;\r\n }\r\n this.removeActiveSelection();\r\n newChild.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n });\r\n // Moving the mouse means no longer using keyboard\r\n newChildLink.addEventListener(\"mousemove\", (event) => {\r\n this.#keyboardNavigation = false;\r\n });\r\n\r\n newChildLink.addEventListener(\"mousedown\", (event) => {\r\n // Otherwise searchInput would lose focus and close the menu\r\n event.preventDefault();\r\n });\r\n newChildLink.addEventListener(\"click\", (event) => {\r\n event.preventDefault();\r\n let text = newChildLink.textContent;\r\n if (!this.canAdd(text, newChildLink.getAttribute(VALUE_ATTRIBUTE))) {\r\n return;\r\n }\r\n this.addItem(text, newChildLink.getAttribute(VALUE_ATTRIBUTE), newChildLink.dataset);\r\n this.#resetSearchInput();\r\n });\r\n }\r\n }\r\n\r\n reset() {\r\n this.removeAll();\r\n\r\n // Reset doesn't fire change event\r\n this.#fireEvents = false;\r\n let initialValues = this.#selectElement.querySelectorAll(\"option[data-init]\");\r\n for (let j = 0; j < initialValues.length; j++) {\r\n let initialValue = initialValues[j];\r\n this.addItem(initialValue.textContent, initialValue.value);\r\n }\r\n this.#adjustWidth();\r\n this.#fireEvents = true;\r\n }\r\n\r\n #resetSearchInput(init = false) {\r\n this.#searchInput.value = \"\";\r\n this.#adjustWidth();\r\n\r\n if (!init) {\r\n this.#hideSuggestions();\r\n // Trigger input even to show suggestions if needed\r\n this.#searchInput.dispatchEvent(new Event(\"input\"));\r\n }\r\n\r\n // We use visibility instead of display to keep layout intact\r\n if (this.max && this.getSelectedValues().length === this.max) {\r\n this.#searchInput.style.visibility = \"hidden\";\r\n } else if (this.#searchInput.style.visibility == \"hidden\") {\r\n this.#searchInput.style.visibility = \"visible\";\r\n }\r\n\r\n if (this.isSingle() && !init) {\r\n document.activeElement.blur();\r\n }\r\n }\r\n\r\n /**\r\n * @returns {array}\r\n */\r\n getSelectedValues() {\r\n // option[selected] is used rather that selectedOptions as it works more consistently\r\n let selected = this.#selectElement.querySelectorAll(\"option[selected]\");\r\n return Array.from(selected).map((el) => el.value);\r\n }\r\n\r\n /**\r\n * The element create with buildSuggestions\r\n */\r\n #showSuggestions() {\r\n if (this.#searchInput.style.visibility == \"hidden\") {\r\n return;\r\n }\r\n\r\n // Position next to search input\r\n this.#dropElement.style.left = this.#searchInput.offsetLeft + \"px\";\r\n\r\n // Get search value\r\n let search = this.#searchInput.value.toLocaleLowerCase();\r\n\r\n // Get current values\r\n let values = this.getSelectedValues();\r\n\r\n // Filter the list according to search string\r\n let list = this.#dropElement.querySelectorAll(\"li\");\r\n let found = false;\r\n let firstItem = null;\r\n let hasPossibleValues = false;\r\n for (let i = 0; i < list.length; i++) {\r\n let item = list[i];\r\n let text = item.textContent.toLocaleLowerCase();\r\n let link = item.querySelector(\"a\");\r\n\r\n // Remove previous selection\r\n link.classList.remove(...ACTIVE_CLASSES);\r\n\r\n // Hide selected values\r\n if (values.indexOf(link.getAttribute(VALUE_ATTRIBUTE)) != -1) {\r\n item.style.display = \"none\";\r\n continue;\r\n }\r\n\r\n hasPossibleValues = true;\r\n\r\n // Check search length since we can trigger dropdown with arrow\r\n let isMatched = search.length === 0 || text.indexOf(search) !== -1;\r\n if (this.showAllSuggestions || this.suggestionsThreshold === 0 || isMatched) {\r\n item.style.display = \"list-item\";\r\n found = true;\r\n if (!firstItem && isMatched) {\r\n firstItem = item;\r\n }\r\n } else {\r\n item.style.display = \"none\";\r\n }\r\n }\r\n\r\n // Always select first item\r\n if (firstItem) {\r\n this.#holderElement.classList.remove(\"is-invalid\");\r\n firstItem.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n firstItem.parentNode.scrollTop = firstItem.offsetTop - firstItem.parentNode.offsetTop;\r\n } else {\r\n // No item and we don't allow new items => error\r\n if (!this.allowNew && !(search.length === 0 && !hasPossibleValues)) {\r\n this.#holderElement.classList.add(\"is-invalid\");\r\n } else if (this.validationRegex && this.isInvalid()) {\r\n this.#holderElement.classList.remove(\"is-invalid\");\r\n }\r\n }\r\n\r\n // Remove dropdown if not found or to show validation message\r\n if (!found || this.isInvalid()) {\r\n this.#dropElement.classList.remove(\"show\");\r\n } else {\r\n // Or show it if necessary\r\n this.#dropElement.classList.add(\"show\");\r\n }\r\n }\r\n\r\n /**\r\n * The element create with buildSuggestions\r\n */\r\n #hideSuggestions() {\r\n this.#dropElement.classList.remove(\"show\");\r\n this.#holderElement.classList.remove(\"is-invalid\");\r\n this.removeActiveSelection();\r\n }\r\n\r\n /**\r\n * @returns {Number}\r\n */\r\n #getBootstrapVersion() {\r\n let ver = 5;\r\n // If we have jQuery and the tooltip plugin for BS4\r\n if (window.jQuery && $.fn.tooltip != undefined && $.fn.tooltip.Constructor != undefined) {\r\n ver = parseInt($.fn.tooltip.Constructor.VERSION.charAt(0));\r\n }\r\n return ver;\r\n }\r\n\r\n /**\r\n * Find if label is already selected (based on attribute)\r\n * @param {string} text\r\n * @returns {boolean}\r\n */\r\n #isSelected(text) {\r\n const opt = Array.from(this.#selectElement.querySelectorAll(\"option\")).find((el) => el.textContent == text);\r\n if (opt && opt.getAttribute(\"selected\")) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Checks if value matches a configured regex\r\n * @param {string} value\r\n * @returns {boolean}\r\n */\r\n #validateRegex(value) {\r\n const regex = new RegExp(this.validationRegex.trim());\r\n return regex.test(value);\r\n }\r\n\r\n /**\r\n * @returns {HTMLElement}\r\n */\r\n getActiveSelection() {\r\n return this.#dropElement.querySelector(\"a.\" + ACTIVE_CLASS);\r\n }\r\n\r\n removeActiveSelection() {\r\n let selection = this.getActiveSelection();\r\n if (selection) {\r\n selection.classList.remove(...ACTIVE_CLASSES);\r\n }\r\n }\r\n\r\n removeAll() {\r\n let items = this.getSelectedValues();\r\n items.forEach((item) => {\r\n this.removeItem(item);\r\n });\r\n this.#adjustWidth();\r\n }\r\n\r\n /**\r\n * @param {boolean} noEvents\r\n */\r\n removeLastItem(noEvents) {\r\n if (noEvents) {\r\n this.#fireEvents = false;\r\n }\r\n let items = this.#containerElement.querySelectorAll(\"span\");\r\n if (!items.length) {\r\n return;\r\n }\r\n let lastItem = items[items.length - 1];\r\n this.removeItem(lastItem.getAttribute(VALUE_ATTRIBUTE));\r\n this.#fireEvents = true;\r\n }\r\n\r\n /**\r\n * @returns {boolean}\r\n */\r\n isDisabled() {\r\n return this.#selectElement.hasAttribute(\"disabled\") || this.#selectElement.disabled || this.#selectElement.hasAttribute(\"readonly\");\r\n }\r\n\r\n /**\r\n * @returns {boolean}\r\n */\r\n isInvalid() {\r\n return this.#holderElement.classList.contains(\"is-invalid\");\r\n }\r\n\r\n /**\r\n * @returns {boolean}\r\n */\r\n isSingle() {\r\n return !this.#selectElement.hasAttribute(\"multiple\");\r\n }\r\n\r\n /**\r\n * @param {string} text\r\n * @param {string} value\r\n * @returns {boolean}\r\n */\r\n canAdd(text, value = null) {\r\n if (!value) {\r\n value = text;\r\n }\r\n\r\n // Check invalid input\r\n if (!text) {\r\n return false;\r\n }\r\n // Check disabled\r\n if (this.isDisabled()) {\r\n return false;\r\n }\r\n // Check already selected input (single will replace)\r\n if (!this.isSingle() && this.#isSelected(value)) {\r\n return false;\r\n }\r\n // Check for max\r\n if (this.max && this.getSelectedValues().length >= this.max) {\r\n return false;\r\n }\r\n // Check for regex\r\n if (this.validationRegex && !this.#validateRegex(text)) {\r\n this.#holderElement.classList.add(\"is-invalid\");\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * You might want to use canAdd before to ensure the item is valid\r\n * @param {string} text\r\n * @param {string} value\r\n * @param {object} data\r\n */\r\n addItem(text, value = null, data = {}) {\r\n if (!value) {\r\n value = text;\r\n }\r\n\r\n // Single items remove first\r\n if (this.isSingle() && this.getSelectedValues().length) {\r\n this.removeLastItem(true);\r\n }\r\n\r\n const bver = this.#getBootstrapVersion();\r\n let opt = this.#selectElement.querySelector('option[value=\"' + value + '\"]');\r\n if (opt) {\r\n data = opt.dataset;\r\n }\r\n\r\n // create span\r\n let html = text;\r\n let span = document.createElement(\"span\");\r\n let classes = [\"badge\"];\r\n let badgeStyle = this.badgeStyle;\r\n if (data.badgeStyle) {\r\n badgeStyle = data.badgeStyle;\r\n }\r\n if (data.badgeClass) {\r\n classes.push(data.badgeClass);\r\n }\r\n if (bver === 5) {\r\n //https://getbootstrap.com/docs/5.1/components/badge/\r\n classes = [...classes, ...[\"me-2\", \"bg-\" + badgeStyle]];\r\n } else {\r\n // https://getbootstrap.com/docs/4.6/components/badge/\r\n classes = [...classes, ...[\"mr-2\", \"badge-\" + badgeStyle]];\r\n }\r\n span.classList.add(...classes);\r\n span.setAttribute(VALUE_ATTRIBUTE, value);\r\n\r\n if (this.allowClear) {\r\n const btn =\r\n bver === 5\r\n ? ''\r\n : '';\r\n html = btn + html;\r\n }\r\n\r\n span.innerHTML = html;\r\n this.#containerElement.insertBefore(span, this.#searchInput);\r\n\r\n if (this.allowClear) {\r\n span.querySelector(\"button\").addEventListener(\"click\", (event) => {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n if (!this.isDisabled()) {\r\n this.removeItem(value);\r\n document.activeElement.blur();\r\n this.#adjustWidth();\r\n }\r\n });\r\n }\r\n\r\n // we need to create a new option\r\n if (!opt) {\r\n opt = document.createElement(\"option\");\r\n opt.value = value;\r\n opt.textContent = text; // innerText is not well supported by jsdom\r\n // Pass along data provided\r\n for (const [key, value] of Object.entries(data)) {\r\n opt.dataset[key] = value;\r\n }\r\n this.#selectElement.appendChild(opt);\r\n }\r\n\r\n // update select, we need to set attribute for option[selected]\r\n opt.setAttribute(\"selected\", \"selected\");\r\n opt.selected = true;\r\n\r\n // Fire change event\r\n if (this.#fireEvents) {\r\n this.#selectElement.dispatchEvent(new Event(\"change\", { bubbles: true }));\r\n }\r\n }\r\n\r\n /**\r\n * @param {string} value\r\n */\r\n removeItem(value) {\r\n let item = this.#containerElement.querySelector(\"span[\" + VALUE_ATTRIBUTE + '=\"' + value + '\"]');\r\n if (!item) {\r\n return;\r\n }\r\n item.remove();\r\n\r\n // update select\r\n let opt = this.#selectElement.querySelector('option[value=\"' + value + '\"]');\r\n if (opt) {\r\n opt.removeAttribute(\"selected\");\r\n opt.selected = false;\r\n\r\n // Fire change event\r\n if (this.#fireEvents) {\r\n this.#selectElement.dispatchEvent(new Event(\"change\", { bubbles: true }));\r\n }\r\n }\r\n\r\n // Make input visible\r\n if (this.#searchInput.style.visibility == \"hidden\" && this.max && this.getSelectedValues().length < this.max) {\r\n this.#searchInput.style.visibility = \"visible\";\r\n }\r\n }\r\n}\r\n\r\nexport default Tags;\r\n"], + "mappings": "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", "names": [] }