├── .editorconfig ├── .github └── FUNDING.yml ├── .gitignore ├── .npmrc ├── .prettierrc.mjs ├── .vscode └── settings.json ├── CHANGELOG.md ├── LICENSE ├── README.md ├── astro.config.mjs ├── docs ├── CNAME ├── assets │ ├── client.CMMtWkl7.js │ ├── customize.ChsKtbAZ.css │ ├── hind-siliguri-latin-300-normal.BmRGVauJ.woff │ ├── hind-siliguri-latin-300-normal.CxtQ64TU.woff2 │ ├── hind-siliguri-latin-400-normal.esES0U7a.woff2 │ ├── hind-siliguri-latin-400-normal.mAXWzDdv.woff │ ├── hind-siliguri-latin-500-normal.C39pZ2Wf.woff │ ├── hind-siliguri-latin-500-normal.S8HLIV69.woff2 │ ├── hind-siliguri-latin-600-normal.DHrLfb92.woff2 │ ├── hind-siliguri-latin-600-normal.DznM-F7B.woff │ ├── hind-siliguri-latin-700-normal.Bfx7EHGG.woff │ ├── hind-siliguri-latin-700-normal.DO_14aHP.woff2 │ ├── hoisted.BHYAm2h0.js │ ├── hoisted.Bfhi6YCy.js │ ├── inter-tight-latin-100-normal.BUQHjXUO.woff2 │ ├── inter-tight-latin-100-normal.D6j6PT36.woff │ ├── inter-tight-latin-200-normal.BpBSUNUw.woff2 │ ├── inter-tight-latin-200-normal.CxHSWdVf.woff │ ├── inter-tight-latin-300-normal.B7aEqmkm.woff │ ├── inter-tight-latin-300-normal.CcE1U6m0.woff2 │ ├── inter-tight-latin-400-normal.BW_APOAv.woff │ ├── inter-tight-latin-400-normal.CjmW70MP.woff2 │ ├── inter-tight-latin-500-normal.DHfo6WYp.woff2 │ ├── inter-tight-latin-500-normal.DSK3iurg.woff │ ├── inter-tight-latin-600-normal.BhR4EMHT.woff2 │ ├── inter-tight-latin-600-normal.RFJ2ueZL.woff │ ├── inter-tight-latin-700-normal.DXx9Bw8i.woff2 │ ├── inter-tight-latin-700-normal.R7r4QQK5.woff │ ├── inter-tight-latin-800-normal.Cs5FMU-_.woff2 │ ├── inter-tight-latin-800-normal.oIdnBkMp.woff │ ├── inter-tight-latin-900-normal.CTv59UVw.woff │ ├── inter-tight-latin-900-normal.EWT6IQYC.woff2 │ ├── page.D3gCUAtq.js │ └── tab.CrkoWeCF.js ├── customize.html ├── demo.html ├── favicon.svg ├── index.html ├── install.html └── methods.html ├── eslint.config.js ├── package.json ├── public ├── CNAME └── favicon.svg ├── purgecss.config.cjs ├── scss └── use-bootstrap-tag.scss ├── src ├── components │ ├── Code.astro │ ├── DemoCard.astro │ ├── Layout.astro │ ├── Pagination.astro │ ├── customize │ │ ├── CustomizeA.scss │ │ ├── CustomizeB.scss │ │ └── CustomizeStructure.txt │ └── demo │ │ ├── AllowDuplicates.astro │ │ ├── Basic.astro │ │ ├── CustomSeparator.astro │ │ ├── Disabled.astro │ │ ├── Label.astro │ │ ├── MaxLimit.astro │ │ ├── Methods.astro │ │ ├── NoInputOnblur.astro │ │ ├── Placeholder.astro │ │ ├── Sizing.astro │ │ ├── TransformTags.astro │ │ ├── Validation.astro │ │ ├── Variants.astro │ │ └── XPosition.astro ├── env.d.ts ├── global.d.ts ├── lib │ ├── use-bootstrap-tag.scss │ ├── use-bootstrap-tag.tsx │ └── util.ts ├── pages │ ├── customize.astro │ ├── demo.astro │ ├── index.astro │ ├── install.astro │ └── methods.astro └── style.scss ├── tsconfig.json └── vite.config.ts /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [use-bootstrap] 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | # generated types 4 | .astro/ 5 | 6 | # dependencies 7 | node_modules/ 8 | 9 | # logs 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | pnpm-debug.log* 14 | 15 | 16 | # environment variables 17 | .env 18 | .env.production 19 | 20 | # macOS-specific files 21 | .DS_Store 22 | 23 | # jetbrains setting folder 24 | .idea/ 25 | 26 | # locks 27 | pnpm-lock.yaml 28 | bun.lockb 29 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | save-exact=true 2 | -------------------------------------------------------------------------------- /.prettierrc.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import("prettier").Config} */ 2 | const config = { 3 | semi: false, 4 | singleQuote: true, 5 | printWidth: 999999999999, 6 | htmlWhitespaceSensitivity: 'ignore', 7 | } 8 | 9 | export default config 10 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "html-css-class-completion.includeGlobPattern": "node_modules/bootstrap/dist/css/bootstrap.css", 3 | "html-css-class-completion.excludeGlobPattern": "!node_modules/bootstrap/dist/css/bootstrap.css", 4 | "html-css-class-completion.HTMLLanguages": [ 5 | "html", 6 | "astro" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | v2.2.2 2 | - Fixed placeholder color 3 | 4 | v2.2.1 5 | - Fixed types 6 | - Update docs 7 | 8 | v2.2.0 9 | - Added no-input-onblur option. 10 | 11 | v2.1.1 12 | - Updated to bootstrap v5.3.2. 13 | - Small improvements. 14 | 15 | v2.1.0 16 | - Added max option. 17 | 18 | v2.0.1 19 | - Some rendering improvements. 20 | 21 | v2.0.0 22 | - Rewrite project back to vanilla-js to improve performance and reduce size. 23 | - Pressing Enter is now the default action for adding a tag. Previously, users had to include an attribute option. 24 | - Now pressing Backspace on a focused tag deletes it and shifts focus to the previous tag, while pressing Delete deletes the tag and moves focus to the next one. 25 | - Fixed the tag with long text not breaking words. 26 | - Fixed server-side validation styles. 27 | - Fixed where adding existing values programmatically did not trigger a warning for duplicate tags. 28 | 29 | v1.0.3 30 | - Remove placeholder when input value is not empty (native input placeholder behavior). 31 | 32 | v1.0.2 33 | - Fixed lost focus after deleting the focused tag with the backspace or delete key (Firefox only). 34 | 35 | v1.0.1 36 | - Fixed docs. 37 | 38 | v1.0.0 39 | - Named export to default export. 40 | - Added transition. 41 | - Added variant option. 42 | - Added x-position option. 43 | - Added focusable tag, when it focused you can press backspace or delete key to remove it. 44 | - Fixed clicking label not focusing input. 45 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Use Bootstrap 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # use-bootstrap-tag 2 | 3 | Tag input for Bootstrap 5 4 | 5 | Demo and documentation: [https://use-bootstrap-tag.js.org](https://use-bootstrap-tag.js.org) 6 | 7 | ## Features 8 | 9 | - **Custom separator**: Set a specific delimiter character between tag elements. 10 | - **Enable/disable duplicates**: Toggle the allowance of duplicate tags. 11 | - **Custom transformation**: Define personalized modifications to input tag entries. 12 | - **Max limit**: Set a maximum limit of tags that can be added. 13 | - **Sizing**: Adjustable sizing to match user preferences or layouts. 14 | - **Validation**: Reflects validation states visually to align with Bootstrap's form validation feedback. 15 | ## Installation 16 | 17 | Install use-bootstrap-tag from npm: 18 | 19 | ```bash 20 | npm install use-bootstrap-tag 21 | ``` 22 | 23 | ## Usage/Examples 24 | 25 | After installation, you can import the library into your project as follows 26 | 27 | ```javascript 28 | import UseBootstrapTag from 'use-bootstrap-tag' 29 | import 'use-bootstrap-tag/dist/use-bootstrap-tag.css' 30 | ``` 31 | 32 | or, since it also comes with an IIFE bundle, you can insert it directly into your HTML 33 | 34 | ```html 35 | 36 | 37 | 38 | 39 | 40 | Use Bootstrap Tag demo 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | ``` 51 | 52 | Once you imported the library, you can initiate it 53 | 54 | ```javascript 55 | const example = UseBootstrapTag(document.getElementById('example')) 56 | ``` 57 | 58 | ## Options 59 | 60 | All options can be embedded in attributes: 61 | 62 | ```html 63 | data-ub-tag-separator 64 | data-ub-tag-duplicate 65 | data-ub-tag-transform 66 | data-ub-tag-variant 67 | data-ub-tag-x-position 68 | data-ub-tag-max 69 | data-ub-tag-no-input-onblur 70 | ``` 71 | 72 | ```html 73 | 74 | 84 | ``` 85 | ## Methods 86 | 87 | | Name | Params | Returns | Example | 88 | |---------|-----------------|-----------------|-----------------------------------| 89 | | addValue | string \| array | void | `example.addValue('react')`
`example.addValue('vue,svelte')`
`example.addValue(['solid', 'qwik'])` | 90 | | removeValue | string \| array | void | `example.removeValue('react')`
`example.removeValue('vue,svelte')`
`example.removeValue(['solid', 'qwik'])` | 91 | | getValue | null | string | `example.getValue()` | 92 | | getValues | null | array | `example.getValues()` | 93 | 94 | ## License 95 | 96 | [MIT](./LICENSE) 97 | -------------------------------------------------------------------------------- /astro.config.mjs: -------------------------------------------------------------------------------- 1 | import solidJs from '@astrojs/solid-js' 2 | import { defineConfig } from 'astro/config' 3 | import FullReload from 'vite-plugin-full-reload' 4 | 5 | // https://astro.build/config 6 | export default defineConfig({ 7 | integrations: [solidJs()], 8 | devToolbar: { 9 | enabled: false, 10 | }, 11 | build: { 12 | format: 'file', 13 | assets: 'assets', 14 | }, 15 | outDir: 'docs', 16 | server: { 17 | port: 3000, 18 | }, 19 | prefetch: { 20 | prefetchAll: true, 21 | defaultStrategy: 'viewport', 22 | }, 23 | vite: { 24 | plugins: [ 25 | FullReload('src/lib/**/*'), 26 | ], 27 | }, 28 | }) 29 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | use-bootstrap-tag.js.org 2 | -------------------------------------------------------------------------------- /docs/assets/client.CMMtWkl7.js: -------------------------------------------------------------------------------- 1 | const c={context:void 0,registry:void 0};function E(e){c.context=e}function le(){return{...c.context,id:`${c.context.id}${c.context.count++}-`,count:0}}const oe=(e,n)=>e===n,m={equals:oe};let re=z;const A=1,$=2,K={owned:null,cleanups:null,context:null,owner:null};var a=null;let B=null,fe=null,p=null,g=null,b=null,O=0;function V(e,n){const t=p,s=a,i=e.length===0,l=n===void 0?s:n,f=i?K:{owned:null,cleanups:null,context:l?l.context:null,owner:l},o=i?e:()=>e(()=>N(()=>_(f)));a=f,p=null;try{return F(o,!0)}finally{p=t,a=s}}function M(e,n){n=n?Object.assign({},m,n):m;const t={value:e,observers:null,observerSlots:null,comparator:n.equals||void 0},s=i=>(typeof i=="function"&&(i=i(t.value)),Q(t,i));return[J.bind(t),s]}function I(e,n,t){const s=X(e,n,!1,A);R(s)}function v(e,n,t){t=t?Object.assign({},m,t):m;const s=X(e,n,!0,0);return s.observers=null,s.observerSlots=null,s.comparator=t.equals||void 0,R(s),J.bind(s)}function N(e){if(p===null)return e();const n=p;p=null;try{return e()}finally{p=n}}function ue(e){return a===null||(a.cleanups===null?a.cleanups=[e]:a.cleanups.push(e)),e}function ce(){return a}function ae(e){b.push.apply(b,e),e.length=0}function G(e,n){const t=Symbol("context");return{id:t,Provider:be(t),defaultValue:e}}function de(e){return a&&a.context&&a.context[e.id]!==void 0?a.context[e.id]:e.defaultValue}function he(e){const n=v(e),t=v(()=>j(n()));return t.toArray=()=>{const s=t();return Array.isArray(s)?s:s!=null?[s]:[]},t}let D;function pe(){return D||(D=G())}function J(){if(this.sources&&this.state)if(this.state===A)R(this);else{const e=g;g=null,F(()=>L(this),!1),g=e}if(p){const e=this.observers?this.observers.length:0;p.sources?(p.sources.push(this),p.sourceSlots.push(e)):(p.sources=[this],p.sourceSlots=[e]),this.observers?(this.observers.push(p),this.observerSlots.push(p.sources.length-1)):(this.observers=[p],this.observerSlots=[p.sources.length-1])}return this.value}function Q(e,n,t){let s=e.value;return(!e.comparator||!e.comparator(s,n))&&(e.value=n,e.observers&&e.observers.length&&F(()=>{for(let i=0;i1e6)throw g=[],new Error},!1)),n}function R(e){if(!e.fn)return;_(e);const n=O;ge(e,e.value,n)}function ge(e,n,t){let s;const i=a,l=p;p=a=e;try{s=e.fn(n)}catch(f){return e.pure&&(e.state=A,e.owned&&e.owned.forEach(_),e.owned=null),e.updatedAt=t+1,te(f)}finally{p=l,a=i}(!e.updatedAt||e.updatedAt<=t)&&(e.updatedAt!=null&&"observers"in e?Q(e,s):e.value=s,e.updatedAt=t)}function X(e,n,t,s=A,i){const l={fn:e,state:s,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:n,owner:a,context:a?a.context:null,pure:t};return a===null||a!==K&&(a.owned?a.owned.push(l):a.owned=[l]),l}function Z(e){if(e.state===0)return;if(e.state===$)return L(e);if(e.suspense&&N(e.suspense.inFallback))return e.suspense.effects.push(e);const n=[e];for(;(e=e.owner)&&(!e.updatedAt||e.updatedAt=0;t--)if(e=n[t],e.state===A)R(e);else if(e.state===$){const s=g;g=null,F(()=>L(e,n[0]),!1),g=s}}function F(e,n){if(g)return e();let t=!1;n||(g=[]),b?t=!0:b=[],O++;try{const s=e();return ye(t),s}catch(s){t||(b=null),g=null,te(s)}}function ye(e){if(g&&(z(g),g=null),e)return;const n=b;b=null,n.length&&F(()=>re(n),!1)}function z(e){for(let n=0;n=0;n--)_(e.owned[n]);e.owned=null}if(e.cleanups){for(n=e.cleanups.length-1;n>=0;n--)e.cleanups[n]();e.cleanups=null}e.state=0}function xe(e){return e instanceof Error?e:new Error(typeof e=="string"?e:"Unknown error",{cause:e})}function te(e,n=a){throw xe(e)}function j(e){if(typeof e=="function"&&!e.length)return j(e());if(Array.isArray(e)){const n=[];for(let t=0;ti=N(()=>(a.context={...a.context,[e]:s.value},he(()=>s.children))),void 0),i}}let ne=!1;function we(){ne=!0}function q(e,n){if(ne&&c.context){const t=c.context;E(le());const s=N(()=>e(n||{}));return E(t),s}return N(()=>e(n||{}))}const Ae=G();function Se(e){let n=0,t,s,i,l,f;const[o,r]=M(!1),h=pe(),u={increment:()=>{++n===1&&r(!0)},decrement:()=>{--n===0&&r(!1)},inFallback:o,effects:[],resolved:!1},y=ce();if(c.context&&c.load){const x=c.context.id+c.context.count;let S=c.load(x);if(S&&(typeof S!="object"||S.status!=="success"?i=S:c.gather(x)),i&&i!=="$$f"){const[k,T]=M(void 0,{equals:!1});l=k,i.then(()=>{if(c.done)return T();c.gather(x),E(s),T(),E()},P=>{f=P,T()})}}const w=de(Ae);w&&(t=w.register(u.inFallback));let d;return ue(()=>d&&d()),q(h.Provider,{value:u,get children(){return v(()=>{if(f)throw f;if(s=c.context,l)return l(),l=void 0;s&&i==="$$f"&&E();const x=v(()=>e.children);return v(S=>{const k=u.inFallback(),{showContent:T=!0,showFallback:P=!0}=t?t():{};if((!k||i&&i!=="$$f")&&T)return u.resolved=!0,d&&d(),d=s=i=void 0,ae(u.effects),x();if(P)return d?S:V(ie=>(d=ie,s&&(E({id:s.id+"f",count:0}),s=void 0),e.fallback),y)})})}})}function Ce(e,n,t){let s=t.length,i=n.length,l=s,f=0,o=0,r=n[i-1].nextSibling,h=null;for(;fu-o){const x=n[f];for(;o{i=l,n===document?e():Ee(n,e(),n.firstChild?null:void 0,t)},s.owner),()=>{i(),n.textContent=""}}function Ee(e,n,t,s){if(t!==void 0&&!s&&(s=[]),typeof n!="function")return H(e,n,s,t);I(i=>H(e,n(),i,t),s)}function Te(e,n,t={}){c.completed=globalThis._$HY.completed,c.events=globalThis._$HY.events,c.load=i=>globalThis._$HY.r[i],c.has=i=>i in globalThis._$HY.r,c.gather=i=>Y(n,i),c.registry=new Map,c.context={id:t.renderId||"",count:0},Y(n,t.renderId);const s=se(e,n,[...n.childNodes],t);return c.context=null,s}function H(e,n,t,s,i){const l=!!c.context&&e.isConnected;if(l){!t&&(t=[...e.childNodes]);let r=[];for(let h=0;h{let r=n();for(;typeof r=="function";)r=r();t=H(e,r,t,s)}),()=>t;if(Array.isArray(n)){const r=[],h=t&&Array.isArray(t);if(U(r,n,t,i))return I(()=>t=H(e,r,t,s,!0)),()=>t;if(l){if(!r.length)return t;if(s===void 0)return[...e.childNodes];let u=r[0],y=[u];for(;(u=u.nextSibling)!==s;)y.push(u);return t=y}if(r.length===0){if(t=C(e,t,s),o)return t}else h?t.length===0?W(e,r,s):Ce(e,t,r):(t&&C(e),W(e,r));t=r}else if(n.nodeType){if(l&&n.parentNode)return t=o?[n]:n;if(Array.isArray(t)){if(o)return t=C(e,t,s,n);C(e,t,null,n)}else t==null||t===""||!e.firstChild?e.appendChild(n):e.replaceChild(n,e.firstChild);t=n}}return t}function U(e,n,t,s){let i=!1;for(let l=0,f=n.length;l=0;f--){const o=n[f];if(i!==o){const r=o.parentNode===e;!l&&!f?r?e.replaceChild(i,o):e.insertBefore(i,t):r&&o.remove()}else l=!0}}else e.insertBefore(i,t);return[i]}function Y(e,n){const t=e.querySelectorAll("*[data-hk]");for(let s=0;s(we(),Te(...e));var Ne=e=>(n,t,s,{client:i})=>{if(!e.hasAttribute("ssr"))return;const l=i!=="only",f=l?ve:se;let o,r={};if(Object.keys(s).length>0){if(i!=="only"){const d=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT,x=>x===e?NodeFilter.FILTER_SKIP:x.nodeName==="ASTRO-SLOT"?NodeFilter.FILTER_ACCEPT:x.nodeName==="ASTRO-ISLAND"?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_SKIP);for(;o=d.nextNode();)r[o.getAttribute("name")||"default"]=o}for(const[d,x]of Object.entries(s))r[d]||(r[d]=document.createElement("astro-slot"),d!=="default"&&r[d].setAttribute("name",d),r[d].innerHTML=x)}const{default:h,...u}=r,y=e.dataset.solidRenderId,w=f(()=>{const d=()=>q(n,{...t,...u,children:h});return l?q(Se,{get children(){return d()}}):d()},e,{renderId:y});e.addEventListener("astro:unmount",()=>w(),{once:!0})};export{Ne as default}; 2 | -------------------------------------------------------------------------------- /docs/assets/customize.ChsKtbAZ.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8";@font-face{font-family:Hind Siliguri;font-style:normal;font-display:swap;font-weight:300;src:url(/assets/hind-siliguri-latin-300-normal.CxtQ64TU.woff2) format("woff2"),url(/assets/hind-siliguri-latin-300-normal.BmRGVauJ.woff) format("woff")}@font-face{font-family:Hind Siliguri;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/hind-siliguri-latin-400-normal.esES0U7a.woff2) format("woff2"),url(/assets/hind-siliguri-latin-400-normal.mAXWzDdv.woff) format("woff")}@font-face{font-family:Hind Siliguri;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/hind-siliguri-latin-500-normal.S8HLIV69.woff2) format("woff2"),url(/assets/hind-siliguri-latin-500-normal.C39pZ2Wf.woff) format("woff")}@font-face{font-family:Hind Siliguri;font-style:normal;font-display:swap;font-weight:600;src:url(/assets/hind-siliguri-latin-600-normal.DHrLfb92.woff2) format("woff2"),url(/assets/hind-siliguri-latin-600-normal.DznM-F7B.woff) format("woff")}@font-face{font-family:Hind Siliguri;font-style:normal;font-display:swap;font-weight:700;src:url(/assets/hind-siliguri-latin-700-normal.DO_14aHP.woff2) format("woff2"),url(/assets/hind-siliguri-latin-700-normal.Bfx7EHGG.woff) format("woff")}@font-face{font-family:Inter Tight;font-style:normal;font-display:swap;font-weight:100;src:url(/assets/inter-tight-latin-100-normal.BUQHjXUO.woff2) format("woff2"),url(/assets/inter-tight-latin-100-normal.D6j6PT36.woff) format("woff")}@font-face{font-family:Inter Tight;font-style:normal;font-display:swap;font-weight:200;src:url(/assets/inter-tight-latin-200-normal.BpBSUNUw.woff2) format("woff2"),url(/assets/inter-tight-latin-200-normal.CxHSWdVf.woff) format("woff")}@font-face{font-family:Inter Tight;font-style:normal;font-display:swap;font-weight:300;src:url(/assets/inter-tight-latin-300-normal.CcE1U6m0.woff2) format("woff2"),url(/assets/inter-tight-latin-300-normal.B7aEqmkm.woff) format("woff")}@font-face{font-family:Inter Tight;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/inter-tight-latin-400-normal.CjmW70MP.woff2) format("woff2"),url(/assets/inter-tight-latin-400-normal.BW_APOAv.woff) format("woff")}@font-face{font-family:Inter Tight;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/inter-tight-latin-500-normal.DHfo6WYp.woff2) format("woff2"),url(/assets/inter-tight-latin-500-normal.DSK3iurg.woff) format("woff")}@font-face{font-family:Inter Tight;font-style:normal;font-display:swap;font-weight:600;src:url(/assets/inter-tight-latin-600-normal.BhR4EMHT.woff2) format("woff2"),url(/assets/inter-tight-latin-600-normal.RFJ2ueZL.woff) format("woff")}@font-face{font-family:Inter Tight;font-style:normal;font-display:swap;font-weight:700;src:url(/assets/inter-tight-latin-700-normal.DXx9Bw8i.woff2) format("woff2"),url(/assets/inter-tight-latin-700-normal.R7r4QQK5.woff) format("woff")}@font-face{font-family:Inter Tight;font-style:normal;font-display:swap;font-weight:800;src:url(/assets/inter-tight-latin-800-normal.Cs5FMU-_.woff2) format("woff2"),url(/assets/inter-tight-latin-800-normal.oIdnBkMp.woff) format("woff")}@font-face{font-family:Inter Tight;font-style:normal;font-display:swap;font-weight:900;src:url(/assets/inter-tight-latin-900-normal.EWT6IQYC.woff2) format("woff2"),url(/assets/inter-tight-latin-900-normal.CTv59UVw.woff) format("woff")}/*! 2 | * Bootstrap v5.3.3 (https://getbootstrap.com/) 3 | * Copyright 2011-2024 The Bootstrap Authors 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | */:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-primary-text-emphasis:#052c65;--bs-secondary-text-emphasis:#2b2f32;--bs-success-text-emphasis:#0a3622;--bs-info-text-emphasis:#055160;--bs-warning-text-emphasis:#664d03;--bs-danger-text-emphasis:#58151c;--bs-light-text-emphasis:#495057;--bs-dark-text-emphasis:#495057;--bs-primary-bg-subtle:#cfe2ff;--bs-secondary-bg-subtle:#e2e3e5;--bs-success-bg-subtle:#d1e7dd;--bs-info-bg-subtle:#cff4fc;--bs-warning-bg-subtle:#fff3cd;--bs-danger-bg-subtle:#f8d7da;--bs-light-bg-subtle:#fcfcfd;--bs-dark-bg-subtle:#ced4da;--bs-primary-border-subtle:#9ec5fe;--bs-secondary-border-subtle:#c4c8cb;--bs-success-border-subtle:#a3cfbb;--bs-info-border-subtle:#9eeaf9;--bs-warning-border-subtle:#ffe69c;--bs-danger-border-subtle:#f1aeb5;--bs-light-border-subtle:#e9ecef;--bs-dark-border-subtle:#adb5bd;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, .15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-color-rgb:33,37,41;--bs-body-bg:#fff;--bs-body-bg-rgb:255,255,255;--bs-emphasis-color:#000;--bs-emphasis-color-rgb:0,0,0;--bs-secondary-color:rgba(33, 37, 41, .75);--bs-secondary-color-rgb:33,37,41;--bs-secondary-bg:#e9ecef;--bs-secondary-bg-rgb:233,236,239;--bs-tertiary-color:rgba(33, 37, 41, .5);--bs-tertiary-color-rgb:33,37,41;--bs-tertiary-bg:#f8f9fa;--bs-tertiary-bg-rgb:248,249,250;--bs-heading-color:inherit;--bs-link-color:#0d6efd;--bs-link-color-rgb:13,110,253;--bs-link-decoration:underline;--bs-link-hover-color:#0a58ca;--bs-link-hover-color-rgb:10,88,202;--bs-code-color:#d63384;--bs-highlight-color:#212529;--bs-highlight-bg:#fff3cd;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, .175);--bs-border-radius:.375rem;--bs-border-radius-sm:.25rem;--bs-border-radius-lg:.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-xxl:2rem;--bs-border-radius-2xl:var(--bs-border-radius-xxl);--bs-border-radius-pill:50rem;--bs-box-shadow:0 .5rem 1rem rgba(0, 0, 0, .15);--bs-box-shadow-sm:0 .125rem .25rem rgba(0, 0, 0, .075);--bs-box-shadow-lg:0 1rem 3rem rgba(0, 0, 0, .175);--bs-box-shadow-inset:inset 0 1px 2px rgba(0, 0, 0, .075);--bs-focus-ring-width:.25rem;--bs-focus-ring-opacity:.25;--bs-focus-ring-color:rgba(13, 110, 253, .25);--bs-form-valid-color:#198754;--bs-form-valid-border-color:#198754;--bs-form-invalid-color:#dc3545;--bs-form-invalid-border-color:#dc3545}[data-bs-theme=dark]{color-scheme:dark;--bs-body-color:#dee2e6;--bs-body-color-rgb:222,226,230;--bs-body-bg:#212529;--bs-body-bg-rgb:33,37,41;--bs-emphasis-color:#fff;--bs-emphasis-color-rgb:255,255,255;--bs-secondary-color:rgba(222, 226, 230, .75);--bs-secondary-color-rgb:222,226,230;--bs-secondary-bg:#343a40;--bs-secondary-bg-rgb:52,58,64;--bs-tertiary-color:rgba(222, 226, 230, .5);--bs-tertiary-color-rgb:222,226,230;--bs-tertiary-bg:#2b3035;--bs-tertiary-bg-rgb:43,48,53;--bs-primary-text-emphasis:#6ea8fe;--bs-secondary-text-emphasis:#a7acb1;--bs-success-text-emphasis:#75b798;--bs-info-text-emphasis:#6edff6;--bs-warning-text-emphasis:#ffda6a;--bs-danger-text-emphasis:#ea868f;--bs-light-text-emphasis:#f8f9fa;--bs-dark-text-emphasis:#dee2e6;--bs-primary-bg-subtle:#031633;--bs-secondary-bg-subtle:#161719;--bs-success-bg-subtle:#051b11;--bs-info-bg-subtle:#032830;--bs-warning-bg-subtle:#332701;--bs-danger-bg-subtle:#2c0b0e;--bs-light-bg-subtle:#343a40;--bs-dark-bg-subtle:#1a1d20;--bs-primary-border-subtle:#084298;--bs-secondary-border-subtle:#41464b;--bs-success-border-subtle:#0f5132;--bs-info-border-subtle:#087990;--bs-warning-border-subtle:#997404;--bs-danger-border-subtle:#842029;--bs-light-border-subtle:#495057;--bs-dark-border-subtle:#343a40;--bs-heading-color:inherit;--bs-link-color:#6ea8fe;--bs-link-hover-color:#8bb9fe;--bs-link-color-rgb:110,168,254;--bs-link-hover-color-rgb:139,185,254;--bs-code-color:#e685b5;--bs-highlight-color:#dee2e6;--bs-highlight-bg:#664d03;--bs-border-color:#495057;--bs-border-color-translucent:rgba(255, 255, 255, .15);--bs-form-valid-color:#75b798;--bs-form-valid-border-color:#75b798;--bs-form-invalid-color:#ea868f;--bs-form-invalid-border-color:#ea868f}*,:after,:before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;border:0;border-top:var(--bs-border-width) solid;opacity:.25}.h1,.h5,.h6,h1,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--bs-heading-color)}.h1,h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h1,h1{font-size:2.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}ol,ul{padding-left:2rem}ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}b{font-weight:bolder}.small,small{font-size:.875em}a{color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,1));text-decoration:underline}a:hover{--bs-link-color-rgb:var(--bs-link-hover-color-rgb)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,pre{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}::file-selector-button{font:inherit;-webkit-appearance:button}summary{display:list-item;cursor:pointer}[hidden]{display:none!important}.container{--bs-gutter-x:1.5rem;--bs-gutter-y:0;width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}@media (min-width:1400px){.container{max-width:1320px}}:root{--bs-breakpoint-xs:0;--bs-breakpoint-sm:576px;--bs-breakpoint-md:768px;--bs-breakpoint-lg:992px;--bs-breakpoint-xl:1200px;--bs-breakpoint-xxl:1400px}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col-12{flex:0 0 auto;width:100%}.g-4{--bs-gutter-x:1.5rem}.g-4{--bs-gutter-y:1.5rem}@media (min-width:992px){.col-lg-6{flex:0 0 auto;width:50%}}@media (min-width:1400px){.col-xxl-4{flex:0 0 auto;width:33.33333333%}}.table{--bs-table-color-type:initial;--bs-table-bg-type:initial;--bs-table-color-state:initial;--bs-table-bg-state:initial;--bs-table-color:var(--bs-emphasis-color);--bs-table-bg:var(--bs-body-bg);--bs-table-border-color:var(--bs-border-color);--bs-table-accent-bg:transparent;--bs-table-striped-color:var(--bs-emphasis-color);--bs-table-striped-bg:rgba(var(--bs-emphasis-color-rgb), .05);--bs-table-active-color:var(--bs-emphasis-color);--bs-table-active-bg:rgba(var(--bs-emphasis-color-rgb), .1);--bs-table-hover-color:var(--bs-emphasis-color);--bs-table-hover-bg:rgba(var(--bs-emphasis-color-rgb), .075);width:100%;margin-bottom:1rem;vertical-align:top;border-color:var(--bs-table-border-color)}.table>:not(caption)>*>*{padding:.5rem;color:var(--bs-table-color-state,var(--bs-table-color-type,var(--bs-table-color)));background-color:var(--bs-table-bg);border-bottom-width:var(--bs-border-width);box-shadow:inset 0 0 0 9999px var(--bs-table-bg-state,var(--bs-table-bg-type,var(--bs-table-accent-bg)))}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table-bordered>:not(caption)>*{border-width:var(--bs-border-width) 0}.table-bordered>:not(caption)>*>*{border-width:0 var(--bs-border-width)}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}.form-label{margin-bottom:.5rem}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-clip:padding-box;border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:var(--bs-body-color);background-color:var(--bs-body-bg);border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem #0d6efd40}.form-control::-webkit-date-and-time-value{min-width:85px;height:1.5em;margin:0}.form-control::-webkit-datetime-edit{display:block;padding:0}.form-control::-moz-placeholder{color:var(--bs-secondary-color);opacity:1}.form-control::placeholder{color:var(--bs-secondary-color);opacity:1}.form-control:disabled{background-color:var(--bs-secondary-bg);opacity:1}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:var(--bs-body-color);background-color:var(--bs-tertiary-bg);pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:var(--bs-border-width);border-radius:0;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control::file-selector-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:var(--bs-body-color);background-color:var(--bs-tertiary-bg);pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:var(--bs-border-width);border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::-webkit-file-upload-button{-webkit-transition:none;transition:none}.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:var(--bs-secondary-bg)}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:var(--bs-secondary-bg)}.form-control-sm{min-height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2));padding:.25rem .5rem;font-size:.875rem;border-radius:var(--bs-border-radius-sm)}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2));padding:.5rem 1rem;font-size:1.25rem;border-radius:var(--bs-border-radius-lg)}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + .75rem + calc(var(--bs-border-width) * 2))}textarea.form-control-sm{min-height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2))}textarea.form-control-lg{min-height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2))}.form-check{display:block;min-height:1.5rem;padding-left:1.5em;margin-bottom:.125rem}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-input{--bs-form-check-bg:var(--bs-body-bg);flex-shrink:0;width:1em;height:1em;margin-top:.25em;vertical-align:top;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-form-check-bg);background-image:var(--bs-form-check-bg-image);background-repeat:no-repeat;background-position:center;background-size:contain;border:var(--bs-border-width) solid var(--bs-border-color);-webkit-print-color-adjust:exact;color-adjust:exact;print-color-adjust:exact}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem #0d6efd40}.form-check-input:checked{background-color:#0d6efd;border-color:#0d6efd}.form-check-input:checked[type=checkbox]{--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate{background-color:#0d6efd;border-color:#0d6efd;--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{cursor:default;opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");width:2em;margin-left:-2.5em;background-image:var(--bs-form-switch-bg);background-position:left center;border-radius:2em;transition:background-position .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2386b7fe'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}[data-bs-theme=dark] .form-switch .form-check-input:not(:checked):not(:focus){--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%28255, 255, 255, 0.25%29'/%3e%3c/svg%3e")}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:var(--bs-form-valid-color)}.is-valid~.valid-feedback,.was-validated :valid~.valid-feedback{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:var(--bs-form-valid-border-color);padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:var(--bs-form-valid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:var(--bs-form-valid-border-color)}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:var(--bs-form-valid-color)}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:var(--bs-form-valid-color)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:var(--bs-form-invalid-color)}.is-invalid~.invalid-feedback,.was-validated :invalid~.invalid-feedback{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:var(--bs-form-invalid-border-color);padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:var(--bs-form-invalid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:var(--bs-form-invalid-border-color)}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:var(--bs-form-invalid-color)}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:var(--bs-form-invalid-color)}.btn{--bs-btn-padding-x:.75rem;--bs-btn-padding-y:.375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:var(--bs-body-color);--bs-btn-bg:transparent;--bs-btn-border-width:var(--bs-border-width);--bs-btn-border-color:transparent;--bs-btn-border-radius:var(--bs-border-radius);--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, .15),0 1px 1px rgba(0, 0, 0, .075);--bs-btn-disabled-opacity:.65;--bs-btn-focus-box-shadow:0 0 0 .25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0b5ed7;--bs-btn-hover-border-color:#0a58ca;--bs-btn-focus-shadow-rgb:49,132,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0a58ca;--bs-btn-active-border-color:#0a53be;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, .125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#0d6efd;--bs-btn-disabled-border-color:#0d6efd}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#5c636a;--bs-btn-hover-border-color:#565e64;--bs-btn-focus-shadow-rgb:130,138,145;--bs-btn-active-color:#fff;--bs-btn-active-bg:#565e64;--bs-btn-active-border-color:#51585e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, .125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#6c757d;--bs-btn-disabled-border-color:#6c757d}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#157347;--bs-btn-hover-border-color:#146c43;--bs-btn-focus-shadow-rgb:60,153,110;--bs-btn-active-color:#fff;--bs-btn-active-bg:#146c43;--bs-btn-active-border-color:#13653f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, .125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#198754;--bs-btn-disabled-border-color:#198754}.btn-info{--bs-btn-color:#000;--bs-btn-bg:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#31d2f2;--bs-btn-hover-border-color:#25cff2;--bs-btn-focus-shadow-rgb:11,172,204;--bs-btn-active-color:#000;--bs-btn-active-bg:#3dd5f3;--bs-btn-active-border-color:#25cff2;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, .125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#0dcaf0;--bs-btn-disabled-border-color:#0dcaf0}.btn-warning{--bs-btn-color:#000;--bs-btn-bg:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffca2c;--bs-btn-hover-border-color:#ffc720;--bs-btn-focus-shadow-rgb:217,164,6;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffcd39;--bs-btn-active-border-color:#ffc720;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, .125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#ffc107;--bs-btn-disabled-border-color:#ffc107}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#bb2d3b;--bs-btn-hover-border-color:#b02a37;--bs-btn-focus-shadow-rgb:225,83,97;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b02a37;--bs-btn-active-border-color:#a52834;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, .125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#dc3545;--bs-btn-disabled-border-color:#dc3545}.btn-light{--bs-btn-color:#000;--bs-btn-bg:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#d3d4d5;--bs-btn-hover-border-color:#c6c7c8;--bs-btn-focus-shadow-rgb:211,212,213;--bs-btn-active-color:#000;--bs-btn-active-bg:#c6c7c8;--bs-btn-active-border-color:#babbbc;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, .125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#f8f9fa;--bs-btn-disabled-border-color:#f8f9fa}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#424649;--bs-btn-hover-border-color:#373b3e;--bs-btn-focus-shadow-rgb:66,70,73;--bs-btn-active-color:#fff;--bs-btn-active-bg:#4d5154;--bs-btn-active-border-color:#373b3e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, .125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#212529;--bs-btn-disabled-border-color:#212529}.btn-lg{--bs-btn-padding-y:.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.25rem;--bs-btn-border-radius:var(--bs-border-radius-lg)}.btn-sm{--bs-btn-padding-y:.25rem;--bs-btn-padding-x:.5rem;--bs-btn-font-size:.875rem;--bs-btn-border-radius:var(--bs-border-radius-sm)}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.dropdown{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty:after{margin-left:0}.dropdown-menu{--bs-dropdown-zindex:1000;--bs-dropdown-min-width:10rem;--bs-dropdown-padding-x:0;--bs-dropdown-padding-y:.5rem;--bs-dropdown-spacer:.125rem;--bs-dropdown-font-size:1rem;--bs-dropdown-color:var(--bs-body-color);--bs-dropdown-bg:var(--bs-body-bg);--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-border-radius:var(--bs-border-radius);--bs-dropdown-border-width:var(--bs-border-width);--bs-dropdown-inner-border-radius:calc(var(--bs-border-radius) - var(--bs-border-width));--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-divider-margin-y:.5rem;--bs-dropdown-box-shadow:var(--bs-box-shadow);--bs-dropdown-link-color:var(--bs-body-color);--bs-dropdown-link-hover-color:var(--bs-body-color);--bs-dropdown-link-hover-bg:var(--bs-tertiary-bg);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#0d6efd;--bs-dropdown-link-disabled-color:var(--bs-tertiary-color);--bs-dropdown-item-padding-x:1rem;--bs-dropdown-item-padding-y:.25rem;--bs-dropdown-header-color:#6c757d;--bs-dropdown-header-padding-x:1rem;--bs-dropdown-header-padding-y:.5rem;position:absolute;z-index:var(--bs-dropdown-zindex);display:none;min-width:var(--bs-dropdown-min-width);padding:var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);margin:0;font-size:var(--bs-dropdown-font-size);color:var(--bs-dropdown-color);text-align:left;list-style:none;background-color:var(--bs-dropdown-bg);background-clip:padding-box;border:var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);border-radius:var(--bs-dropdown-border-radius)}.dropdown-menu.show{display:block}.nav{--bs-nav-link-padding-x:1rem;--bs-nav-link-padding-y:.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;background:0 0;border:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link:focus-visible{outline:0;box-shadow:0 0 0 .25rem #0d6efd40}.nav-link.disabled,.nav-link:disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-underline{--bs-nav-underline-gap:1rem;--bs-nav-underline-border-width:.125rem;--bs-nav-underline-link-active-color:var(--bs-emphasis-color);gap:var(--bs-nav-underline-gap)}.nav-underline .nav-link{padding-right:0;padding-left:0;border-bottom:var(--bs-nav-underline-border-width) solid transparent}.nav-underline .nav-link:focus,.nav-underline .nav-link:hover{border-bottom-color:currentcolor}.nav-underline .nav-link.active,.nav-underline .show>.nav-link{font-weight:700;color:var(--bs-nav-underline-link-active-color);border-bottom-color:currentcolor}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{--bs-navbar-padding-x:0;--bs-navbar-padding-y:.5rem;--bs-navbar-color:rgba(var(--bs-emphasis-color-rgb), .65);--bs-navbar-hover-color:rgba(var(--bs-emphasis-color-rgb), .8);--bs-navbar-disabled-color:rgba(var(--bs-emphasis-color-rgb), .3);--bs-navbar-active-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-padding-y:.3125rem;--bs-navbar-brand-margin-end:1rem;--bs-navbar-brand-font-size:1.25rem;--bs-navbar-brand-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-hover-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-nav-link-padding-x:.5rem;--bs-navbar-toggler-padding-y:.25rem;--bs-navbar-toggler-padding-x:.75rem;--bs-navbar-toggler-font-size:1.25rem;--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2833, 37, 41, 0.75%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");--bs-navbar-toggler-border-color:rgba(var(--bs-emphasis-color-rgb), .15);--bs-navbar-toggler-border-radius:var(--bs-border-radius);--bs-navbar-toggler-focus-width:.25rem;--bs-navbar-toggler-transition:box-shadow .15s ease-in-out;position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x)}.navbar>.container{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:var(--bs-navbar-brand-padding-y);padding-bottom:var(--bs-navbar-brand-padding-y);margin-right:var(--bs-navbar-brand-margin-end);font-size:var(--bs-navbar-brand-font-size);color:var(--bs-navbar-brand-color);text-decoration:none;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{color:var(--bs-navbar-brand-hover-color)}.navbar-nav{--bs-nav-link-padding-x:0;--bs-nav-link-padding-y:.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-navbar-color);--bs-nav-link-hover-color:var(--bs-navbar-hover-color);--bs-nav-link-disabled-color:var(--bs-navbar-disabled-color);display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link.active,.navbar-nav .nav-link.show{color:var(--bs-navbar-active-color)}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-navbar-color)}.navbar-text a,.navbar-text a:focus,.navbar-text a:hover{color:var(--bs-navbar-active-color)}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar[data-bs-theme=dark]{--bs-navbar-color:rgba(255, 255, 255, .55);--bs-navbar-hover-color:rgba(255, 255, 255, .75);--bs-navbar-disabled-color:rgba(255, 255, 255, .25);--bs-navbar-active-color:#fff;--bs-navbar-brand-color:#fff;--bs-navbar-brand-hover-color:#fff;--bs-navbar-toggler-border-color:rgba(255, 255, 255, .1);--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.card{--bs-card-spacer-y:1rem;--bs-card-spacer-x:1rem;--bs-card-title-spacer-y:.5rem;--bs-card-title-color: ;--bs-card-subtitle-color: ;--bs-card-border-width:var(--bs-border-width);--bs-card-border-color:var(--bs-border-color-translucent);--bs-card-border-radius:var(--bs-border-radius);--bs-card-box-shadow: ;--bs-card-inner-border-radius:calc(var(--bs-border-radius) - (var(--bs-border-width)));--bs-card-cap-padding-y:.5rem;--bs-card-cap-padding-x:1rem;--bs-card-cap-bg:rgba(var(--bs-body-color-rgb), .03);--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg:var(--bs-body-bg);--bs-card-img-overlay-padding:1rem;--bs-card-group-margin:.75rem;position:relative;display:flex;flex-direction:column;min-width:0;height:var(--bs-card-height);color:var(--bs-body-color);word-wrap:break-word;background-color:var(--bs-card-bg);background-clip:border-box;border:var(--bs-card-border-width) solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius)}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card-body{flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x);color:var(--bs-card-color)}.pagination{--bs-pagination-padding-x:.75rem;--bs-pagination-padding-y:.375rem;--bs-pagination-font-size:1rem;--bs-pagination-color:var(--bs-link-color);--bs-pagination-bg:var(--bs-body-bg);--bs-pagination-border-width:var(--bs-border-width);--bs-pagination-border-color:var(--bs-border-color);--bs-pagination-border-radius:var(--bs-border-radius);--bs-pagination-hover-color:var(--bs-link-hover-color);--bs-pagination-hover-bg:var(--bs-tertiary-bg);--bs-pagination-hover-border-color:var(--bs-border-color);--bs-pagination-focus-color:var(--bs-link-hover-color);--bs-pagination-focus-bg:var(--bs-secondary-bg);--bs-pagination-focus-box-shadow:0 0 0 .25rem rgba(13, 110, 253, .25);--bs-pagination-active-color:#fff;--bs-pagination-active-bg:#0d6efd;--bs-pagination-active-border-color:#0d6efd;--bs-pagination-disabled-color:var(--bs-secondary-color);--bs-pagination-disabled-bg:var(--bs-secondary-bg);--bs-pagination-disabled-border-color:var(--bs-border-color);display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;padding:var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);font-size:var(--bs-pagination-font-size);color:var(--bs-pagination-color);text-decoration:none;background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--bs-pagination-hover-color);background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color)}.page-link:focus{z-index:3;color:var(--bs-pagination-focus-color);background-color:var(--bs-pagination-focus-bg);outline:0;box-shadow:var(--bs-pagination-focus-box-shadow)}.active>.page-link,.page-link.active{z-index:3;color:var(--bs-pagination-active-color);background-color:var(--bs-pagination-active-bg);border-color:var(--bs-pagination-active-border-color)}.disabled>.page-link,.page-link.disabled{color:var(--bs-pagination-disabled-color);pointer-events:none;background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color)}.page-item:not(:first-child) .page-link{margin-left:calc(var(--bs-border-width) * -1)}.page-item:first-child .page-link{border-top-left-radius:var(--bs-pagination-border-radius);border-bottom-left-radius:var(--bs-pagination-border-radius)}.page-item:last-child .page-link{border-top-right-radius:var(--bs-pagination-border-radius);border-bottom-right-radius:var(--bs-pagination-border-radius)}.badge{--bs-badge-padding-x:.65em;--bs-badge-padding-y:.35em;--bs-badge-font-size:.75em;--bs-badge-font-weight:700;--bs-badge-color:#fff;--bs-badge-border-radius:var(--bs-border-radius);display:inline-block;padding:var(--bs-badge-padding-y) var(--bs-badge-padding-x);font-size:var(--bs-badge-font-size);font-weight:var(--bs-badge-font-weight);line-height:1;color:var(--bs-badge-color);text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:var(--bs-badge-border-radius)}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{--bs-alert-bg:transparent;--bs-alert-padding-x:1rem;--bs-alert-padding-y:1rem;--bs-alert-margin-bottom:1rem;--bs-alert-color:inherit;--bs-alert-border-color:transparent;--bs-alert-border:var(--bs-border-width) solid var(--bs-alert-border-color);--bs-alert-border-radius:var(--bs-border-radius);--bs-alert-link-color:inherit;position:relative;padding:var(--bs-alert-padding-y) var(--bs-alert-padding-x);margin-bottom:var(--bs-alert-margin-bottom);color:var(--bs-alert-color);background-color:var(--bs-alert-bg);border:var(--bs-alert-border);border-radius:var(--bs-alert-border-radius)}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.list-group{--bs-list-group-color:var(--bs-body-color);--bs-list-group-bg:var(--bs-body-bg);--bs-list-group-border-color:var(--bs-border-color);--bs-list-group-border-width:var(--bs-border-width);--bs-list-group-border-radius:var(--bs-border-radius);--bs-list-group-item-padding-x:1rem;--bs-list-group-item-padding-y:.5rem;--bs-list-group-action-color:var(--bs-secondary-color);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-tertiary-bg);--bs-list-group-action-active-color:var(--bs-body-color);--bs-list-group-action-active-bg:var(--bs-secondary-bg);--bs-list-group-disabled-color:var(--bs-secondary-color);--bs-list-group-disabled-bg:var(--bs-body-bg);--bs-list-group-active-color:#fff;--bs-list-group-active-bg:#0d6efd;--bs-list-group-active-border-color:#0d6efd;display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:var(--bs-list-group-border-radius)}.list-group-item{position:relative;display:block;padding:var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);color:var(--bs-list-group-color);text-decoration:none;background-color:var(--bs-list-group-bg);border:var(--bs-list-group-border-width) solid var(--bs-list-group-border-color)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--bs-list-group-disabled-color);pointer-events:none;background-color:var(--bs-list-group-disabled-bg)}.list-group-item.active{z-index:2;color:var(--bs-list-group-active-color);background-color:var(--bs-list-group-active-bg);border-color:var(--bs-list-group-active-border-color)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:calc(-1 * var(--bs-list-group-border-width));border-top-width:var(--bs-list-group-border-width)}@keyframes spinner-border{to{transform:rotate(360deg)}}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentcolor;opacity:.5}.placeholder.btn:before{display:inline-block;content:""}@keyframes placeholder-glow{50%{opacity:.2}}@keyframes placeholder-wave{to{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}.text-bg-light{color:#000!important;background-color:RGBA(var(--bs-light-rgb),var(--bs-bg-opacity,1))!important}.link-body-emphasis{color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,1))!important}.link-body-emphasis:focus,.link-body-emphasis:hover{color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-opacity,.75))!important;-webkit-text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,.75))!important;text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,.75))!important}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.overflow-x-auto{overflow-x:auto!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.border-0{border:0!important}.border-bottom{border-bottom:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.h-100{height:100%!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.justify-content-end{justify-content:flex-end!important}.justify-content-between{justify-content:space-between!important}.align-items-center{align-items:center!important}.m-0{margin:0!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.me-auto{margin-right:auto!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.ms-auto{margin-left:auto!important}.py-0{padding-top:0!important;padding-bottom:0!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.fs-5{font-size:1.25rem!important}.fw-bold{font-weight:700!important}.text-nowrap{white-space:nowrap!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-body{--bs-text-opacity:1;color:rgba(var(--bs-body-color-rgb),var(--bs-text-opacity))!important}.bg-body-tertiary{--bs-bg-opacity:1;background-color:rgba(var(--bs-tertiary-bg-rgb),var(--bs-bg-opacity))!important}.rounded{border-radius:var(--bs-border-radius)!important}.visible{visibility:visible!important}.use-bootstrap-tag-target{position:fixed;left:-9999rem;top:-9999rem}.use-bootstrap-tag .input-wrapper{position:relative;min-width:4px;flex-grow:1;white-space:nowrap}.use-bootstrap-tag .input-wrapper>span{visibility:hidden}.use-bootstrap-tag input[type=text]{position:absolute;top:0;left:0;padding:0;outline:0;border:0;width:100%;background-color:transparent}.use-bootstrap-tag input[type=text]::placeholder{color:var(--bs-secondary-color);opacity:1}.use-bootstrap-tag-target:not(:disabled)+.use-bootstrap-tag{cursor:text}.use-bootstrap-tag>button{transition-property:transform,height;transition-duration:.15s;transition-timing-function:cubic-bezier(.17,.84,.44,1);border-radius:calc(var(--bs-border-radius) - var(--bs-border-width));overflow-wrap:anywhere}.use-bootstrap-tag>button.duplicate{transform:scale(1.1)}.use-bootstrap-tag>button.btn-sm{border-radius:calc(var(--bs-border-radius-sm) - var(--bs-border-width))}.use-bootstrap-tag>button.btn-lg{border-radius:calc(var(--bs-border-radius-lg) - var(--bs-border-width))}.use-bootstrap-tag>button:not(:disabled){cursor:default}.use-bootstrap-tag.focus{color:var(--bs-body-color);background-color:var(--bs-body-bg);border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem #0d6efd40}.was-validated .form-control:valid+.use-bootstrap-tag,.form-control.is-valid+.use-bootstrap-tag{border-color:var(--bs-form-valid-border-color);padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.was-validated .form-control:valid+.use-bootstrap-tag.focus,.form-control.is-valid+.use-bootstrap-tag.focus{border-color:var(--bs-form-valid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.was-validated .form-control:invalid+.use-bootstrap-tag,.form-control.is-invalid+.use-bootstrap-tag{border-color:var(--bs-form-invalid-border-color);padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.was-validated .form-control:invalid+.use-bootstrap-tag.focus,.form-control.is-invalid+.use-bootstrap-tag.focus{border-color:var(--bs-form-invalid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}:root{--bs-font-sans-serif: "Hind Siliguri"}.h1,.h5,.h6,h1,h5,h6{font-family:Inter Tight;font-weight:900}.form-switch .form-check-input,.form-switch .form-check-label{cursor:pointer;user-select:none}.page-link:focus{box-shadow:none}.shiki{padding:1rem 1.25rem;border-radius:var(--bs-border-radius)}[data-bs-theme=light] .shiki{background-color:#fafaf9!important;box-shadow:inset 0 2px 4px #0000000d;text-shadow:1px 1px #fff}[data-bs-theme=dark] .shiki{--shiki-dark-bg: #2b3035 !important;border:1px solid var(--bs-border-color);text-shadow:1px 1px #000}[data-bs-theme=dark] .shiki,[data-bs-theme=dark] .shiki span{color:var(--shiki-dark)!important;background-color:var(--shiki-dark-bg)!important}@media (min-width: 576px){.shiki{scrollbar-width:thin}}@media (max-width: 575.98px){.navbar-brand{font-size:1rem}.badge{font-family:Inter Tight}#main-nav::-webkit-scrollbar{display:none}#main-nav{-ms-overflow-style:none;scrollbar-width:none}} 6 | -------------------------------------------------------------------------------- /docs/assets/hind-siliguri-latin-300-normal.BmRGVauJ.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/use-bootstrap/use-bootstrap-tag/a668472f9646f0f900d881aec09170fc6592db16/docs/assets/hind-siliguri-latin-300-normal.BmRGVauJ.woff -------------------------------------------------------------------------------- /docs/assets/hind-siliguri-latin-300-normal.CxtQ64TU.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/use-bootstrap/use-bootstrap-tag/a668472f9646f0f900d881aec09170fc6592db16/docs/assets/hind-siliguri-latin-300-normal.CxtQ64TU.woff2 -------------------------------------------------------------------------------- /docs/assets/hind-siliguri-latin-400-normal.esES0U7a.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/use-bootstrap/use-bootstrap-tag/a668472f9646f0f900d881aec09170fc6592db16/docs/assets/hind-siliguri-latin-400-normal.esES0U7a.woff2 -------------------------------------------------------------------------------- /docs/assets/hind-siliguri-latin-400-normal.mAXWzDdv.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/use-bootstrap/use-bootstrap-tag/a668472f9646f0f900d881aec09170fc6592db16/docs/assets/hind-siliguri-latin-400-normal.mAXWzDdv.woff -------------------------------------------------------------------------------- /docs/assets/hind-siliguri-latin-500-normal.C39pZ2Wf.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/use-bootstrap/use-bootstrap-tag/a668472f9646f0f900d881aec09170fc6592db16/docs/assets/hind-siliguri-latin-500-normal.C39pZ2Wf.woff -------------------------------------------------------------------------------- /docs/assets/hind-siliguri-latin-500-normal.S8HLIV69.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/use-bootstrap/use-bootstrap-tag/a668472f9646f0f900d881aec09170fc6592db16/docs/assets/hind-siliguri-latin-500-normal.S8HLIV69.woff2 -------------------------------------------------------------------------------- /docs/assets/hind-siliguri-latin-600-normal.DHrLfb92.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/use-bootstrap/use-bootstrap-tag/a668472f9646f0f900d881aec09170fc6592db16/docs/assets/hind-siliguri-latin-600-normal.DHrLfb92.woff2 -------------------------------------------------------------------------------- /docs/assets/hind-siliguri-latin-600-normal.DznM-F7B.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/use-bootstrap/use-bootstrap-tag/a668472f9646f0f900d881aec09170fc6592db16/docs/assets/hind-siliguri-latin-600-normal.DznM-F7B.woff -------------------------------------------------------------------------------- /docs/assets/hind-siliguri-latin-700-normal.Bfx7EHGG.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/use-bootstrap/use-bootstrap-tag/a668472f9646f0f900d881aec09170fc6592db16/docs/assets/hind-siliguri-latin-700-normal.Bfx7EHGG.woff -------------------------------------------------------------------------------- /docs/assets/hind-siliguri-latin-700-normal.DO_14aHP.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/use-bootstrap/use-bootstrap-tag/a668472f9646f0f900d881aec09170fc6592db16/docs/assets/hind-siliguri-latin-700-normal.DO_14aHP.woff2 -------------------------------------------------------------------------------- /docs/assets/hoisted.BHYAm2h0.js: -------------------------------------------------------------------------------- 1 | import{T as K}from"./tab.CrkoWeCF.js";const w=[];function Q(e){for(const t of e.dependencies)t.delete(e);e.dependencies.clear()}function R(e,t){t.add(e),e.dependencies.add(t)}function k(e){const t=new Set;function c(){const d=w[w.length-1];return d&&R(d,t),e}function i(d){e=d;for(const s of[...t])s.execute()}return[c,i]}function U(e){const t={execute(){Q(t),w.push(t),e(),w.pop()},dependencies:new Set};t.execute()}function M(e,t){return e.length===t.length&&e.every((c,i)=>c===t[i])}function $(e,t){e.value=t,e.dispatchEvent(new Event("change"))}function W(e,t){const c=e.lastIndexOf(t);c!==-1&&e.splice(c,1)}function f(e,t){const c=document.createElement(e);return Object.assign(c,t)}function H(e,t){return typeof e=="string"?e.split(t):Array.isArray(e)?e.flatMap(c=>typeof c=="string"?c.split(t):[]):[]}const S="use-bootstrap-tag",j=`${S}-target`;function Y(e){const t=e,c=t.nextElementSibling;c&&c.classList.contains(S)&&c.remove();const i=f("div");t.insertAdjacentElement("afterend",i);const d=t.dataset,s={separator:d.ubTagSeparator||",",variant:d.ubTagVariant||"secondary",xPosition:d.ubTagXPosition||"right",transform:d.ubTagTransform||"input => input",isDuplicate:d.ubTagDuplicate!==void 0,max:+d.ubTagMax>0?+d.ubTagMax:void 0,noInputOnblur:d.ubTagNoInputOnblur!==void 0},v=()=>i.querySelectorAll("button"),q=n=>{n.classList.add("duplicate"),setTimeout(()=>{n.classList.remove("duplicate")},150)},A=()=>t.value,E=()=>A().split(s.separator).filter(n=>n!==""),N=n=>{const a=E(),o=H(n,s.separator);if(!s.max||a.lengtho.includes(l)&&r.push(p));const u=[];o.forEach(l=>{a.includes(l)?s.isDuplicate&&u.push(l):u.push(l)}),a.push(...u),M(E(),a)||($(t,a.join(s.separator)),u.forEach(l=>{const p=v()[a.lastIndexOf(l)],G=p.offsetHeight;p.style.height=0,setTimeout(()=>p.style.height=`${G}px`,0),setTimeout(()=>p.style.removeProperty("height"),150)})),s.isDuplicate||r.forEach(l=>q(v()[l]))}else o.length>0&&v().forEach(q)},D=n=>{const a=E();H(n,s.separator).forEach(r=>W(a,r)),M(E(),a)||$(t,a.join(s.separator))},x=t.classList,L=t.disabled;t.tabIndex=-1,x.add(j);const[F,P]=k(t.value),[z,y]=k(!1),[g,T]=k(""),h=()=>F().split(s.separator).filter(n=>n.trim()!==""),C=()=>Function(`return ${s.transform}`)()(g().trim()),O=()=>h().length?"":t.placeholder;i.className=`${S} d-flex flex-wrap align-items-center gap-1 ${x.value}`.replace(j,""),U(()=>{z()?i.classList.add("focus"):i.classList.remove("focus")});const B=()=>i.querySelector("input")?.focus(),I=n=>{n>=0&&D(h()[n])},V=(n=!1)=>{const a=C();a===""&&T(""),(g().includes(s.separator)||n&&g()!=="")&&(N(a.split(s.separator).filter(o=>o.trim()!=="")),T(""))},b=f("button",{type:"button",className:`align-items-center gap-1 d-inline-flex py-0 border-0 btn btn-${s.variant}`,disabled:L});x.contains("form-control-sm")&&b.classList.add("btn-sm"),x.contains("form-control-lg")&&b.classList.add("btn-lg"),s.xPosition==="left"&&b.classList.add("flex-row-reverse");const J=f("span",{className:"d-inline-flex",role:"button",tabIndex:-1,innerHTML:''}),X=n=>{v().forEach(a=>a.remove()),n.reverse().forEach((a,o)=>{const r=n.length-1-o,u=b.cloneNode();if(u.innerHTML=a,u.onfocus=()=>{u.classList.add("active"),y(!0)},u.onblur=()=>{u.classList.remove("active"),y(!1)},u.onkeydown=({key:l})=>{if(l==="Backspace"||l==="Delete"){I(r);const p=l==="Backspace"?r-1:h().length===r?-1:r;p===-1?B():v()[p].focus()}},!L){const l=J.cloneNode(!0);l.onclick=()=>{I(r),B()},u.append(l)}i.prepend(u)})};if(U(()=>{X(h())}),!L){const n=f("div",{className:"input-wrapper"}),a=f("span"),o=f("input",{type:"text"});o.onfocus=()=>{y(!0)},o.onblur=()=>{y(!1),s.noInputOnblur?T(""):V(!0)},o.onkeydown=r=>{g()===""&&r.key==="Backspace"&&I(h().length-1),g()!==""&&r.key==="Enter"&&(V(!0),r.preventDefault())},o.oninput=()=>{T(o.value),V()},U(()=>{a.innerHTML=g()||O()||"i",o.placeholder=O(),o.value=g()}),n.append(a,o),i.append(n)}return i.onclick=n=>{n.target.tagName!=="BUTTON"&&B()},t.addEventListener("change",()=>{P(t.value)}),t.addEventListener("focus",B),{getValue:A,getValues:E,addValue:N,removeValue:D}}window.bootstrap={};window.bootstrap.Tab=K;window.UseBootstrapTag=Y;UseBootstrapTag(document.getElementById("example-basic"));UseBootstrapTag(document.getElementById("example-placeholder"));UseBootstrapTag(document.getElementById("example-max"));UseBootstrapTag(document.getElementById("example-separator"));UseBootstrapTag(document.getElementById("example-duplicate"));UseBootstrapTag(document.getElementById("example-transform"));UseBootstrapTag(document.getElementById("example-disabled"));UseBootstrapTag(document.getElementById("example-no-input-onblur"));UseBootstrapTag(document.getElementById("example-label"));document.querySelectorAll(".example-x-position").forEach(e=>{UseBootstrapTag(e)});document.querySelectorAll(".example-sizing").forEach(e=>{UseBootstrapTag(e)});document.querySelectorAll(".example-validation").forEach(e=>{UseBootstrapTag(e)});(function(){document.querySelectorAll(".needs-validation").forEach(e=>{e instanceof HTMLFormElement&&e.addEventListener("submit",t=>{e.checkValidity()||(t.preventDefault(),t.stopPropagation()),e.classList.add("was-validated")})})})();const m=UseBootstrapTag(document.getElementById("example-methods"));document.getElementById("addValue-string").addEventListener("click",()=>{m.addValue("react")});document.getElementById("addValue-string-with-separator").addEventListener("click",()=>{m.addValue("vue,svelte")});document.getElementById("addValue-array").addEventListener("click",()=>{m.addValue(["solid","qwik"])});document.getElementById("removeValue-string").addEventListener("click",()=>{m.removeValue("react")});document.getElementById("removeValue-string-with-separator").addEventListener("click",()=>{m.removeValue("vue,svelte")});document.getElementById("removeValue-array").addEventListener("click",()=>{m.removeValue(["solid","qwik"])});document.getElementById("getValue").addEventListener("click",()=>{alert(m.getValue())});document.getElementById("getValues").addEventListener("click",()=>{alert(JSON.stringify(m.getValues()))});document.querySelectorAll(".example-variant").forEach(e=>{UseBootstrapTag(e)}); 2 | -------------------------------------------------------------------------------- /docs/assets/hoisted.Bfhi6YCy.js: -------------------------------------------------------------------------------- 1 | import{T as o}from"./tab.CrkoWeCF.js";window.bootstrap={};window.bootstrap.Tab=o; 2 | -------------------------------------------------------------------------------- /docs/assets/inter-tight-latin-100-normal.BUQHjXUO.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/use-bootstrap/use-bootstrap-tag/a668472f9646f0f900d881aec09170fc6592db16/docs/assets/inter-tight-latin-100-normal.BUQHjXUO.woff2 -------------------------------------------------------------------------------- /docs/assets/inter-tight-latin-100-normal.D6j6PT36.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/use-bootstrap/use-bootstrap-tag/a668472f9646f0f900d881aec09170fc6592db16/docs/assets/inter-tight-latin-100-normal.D6j6PT36.woff -------------------------------------------------------------------------------- /docs/assets/inter-tight-latin-200-normal.BpBSUNUw.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/use-bootstrap/use-bootstrap-tag/a668472f9646f0f900d881aec09170fc6592db16/docs/assets/inter-tight-latin-200-normal.BpBSUNUw.woff2 -------------------------------------------------------------------------------- /docs/assets/inter-tight-latin-200-normal.CxHSWdVf.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/use-bootstrap/use-bootstrap-tag/a668472f9646f0f900d881aec09170fc6592db16/docs/assets/inter-tight-latin-200-normal.CxHSWdVf.woff -------------------------------------------------------------------------------- /docs/assets/inter-tight-latin-300-normal.B7aEqmkm.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/use-bootstrap/use-bootstrap-tag/a668472f9646f0f900d881aec09170fc6592db16/docs/assets/inter-tight-latin-300-normal.B7aEqmkm.woff -------------------------------------------------------------------------------- /docs/assets/inter-tight-latin-300-normal.CcE1U6m0.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/use-bootstrap/use-bootstrap-tag/a668472f9646f0f900d881aec09170fc6592db16/docs/assets/inter-tight-latin-300-normal.CcE1U6m0.woff2 -------------------------------------------------------------------------------- /docs/assets/inter-tight-latin-400-normal.BW_APOAv.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/use-bootstrap/use-bootstrap-tag/a668472f9646f0f900d881aec09170fc6592db16/docs/assets/inter-tight-latin-400-normal.BW_APOAv.woff -------------------------------------------------------------------------------- /docs/assets/inter-tight-latin-400-normal.CjmW70MP.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/use-bootstrap/use-bootstrap-tag/a668472f9646f0f900d881aec09170fc6592db16/docs/assets/inter-tight-latin-400-normal.CjmW70MP.woff2 -------------------------------------------------------------------------------- /docs/assets/inter-tight-latin-500-normal.DHfo6WYp.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/use-bootstrap/use-bootstrap-tag/a668472f9646f0f900d881aec09170fc6592db16/docs/assets/inter-tight-latin-500-normal.DHfo6WYp.woff2 -------------------------------------------------------------------------------- /docs/assets/inter-tight-latin-500-normal.DSK3iurg.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/use-bootstrap/use-bootstrap-tag/a668472f9646f0f900d881aec09170fc6592db16/docs/assets/inter-tight-latin-500-normal.DSK3iurg.woff -------------------------------------------------------------------------------- /docs/assets/inter-tight-latin-600-normal.BhR4EMHT.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/use-bootstrap/use-bootstrap-tag/a668472f9646f0f900d881aec09170fc6592db16/docs/assets/inter-tight-latin-600-normal.BhR4EMHT.woff2 -------------------------------------------------------------------------------- /docs/assets/inter-tight-latin-600-normal.RFJ2ueZL.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/use-bootstrap/use-bootstrap-tag/a668472f9646f0f900d881aec09170fc6592db16/docs/assets/inter-tight-latin-600-normal.RFJ2ueZL.woff -------------------------------------------------------------------------------- /docs/assets/inter-tight-latin-700-normal.DXx9Bw8i.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/use-bootstrap/use-bootstrap-tag/a668472f9646f0f900d881aec09170fc6592db16/docs/assets/inter-tight-latin-700-normal.DXx9Bw8i.woff2 -------------------------------------------------------------------------------- /docs/assets/inter-tight-latin-700-normal.R7r4QQK5.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/use-bootstrap/use-bootstrap-tag/a668472f9646f0f900d881aec09170fc6592db16/docs/assets/inter-tight-latin-700-normal.R7r4QQK5.woff -------------------------------------------------------------------------------- /docs/assets/inter-tight-latin-800-normal.Cs5FMU-_.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/use-bootstrap/use-bootstrap-tag/a668472f9646f0f900d881aec09170fc6592db16/docs/assets/inter-tight-latin-800-normal.Cs5FMU-_.woff2 -------------------------------------------------------------------------------- /docs/assets/inter-tight-latin-800-normal.oIdnBkMp.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/use-bootstrap/use-bootstrap-tag/a668472f9646f0f900d881aec09170fc6592db16/docs/assets/inter-tight-latin-800-normal.oIdnBkMp.woff -------------------------------------------------------------------------------- /docs/assets/inter-tight-latin-900-normal.CTv59UVw.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/use-bootstrap/use-bootstrap-tag/a668472f9646f0f900d881aec09170fc6592db16/docs/assets/inter-tight-latin-900-normal.CTv59UVw.woff -------------------------------------------------------------------------------- /docs/assets/inter-tight-latin-900-normal.EWT6IQYC.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/use-bootstrap/use-bootstrap-tag/a668472f9646f0f900d881aec09170fc6592db16/docs/assets/inter-tight-latin-900-normal.EWT6IQYC.woff2 -------------------------------------------------------------------------------- /docs/assets/page.D3gCUAtq.js: -------------------------------------------------------------------------------- 1 | const d=new Set,c=new WeakSet;let f=!0,h="viewport",l=!1;function v(e){l||(l=!0,f??=!1,h??="hover",g(),p(),w(),L())}function g(){for(const e of["touchstart","mousedown"])document.body.addEventListener(e,t=>{i(t.target,"tap")&&s(t.target.href,{ignoreSlowConnection:!0})},{passive:!0})}function p(){let e;document.body.addEventListener("focusin",n=>{i(n.target,"hover")&&t(n)},{passive:!0}),document.body.addEventListener("focusout",o,{passive:!0}),u(()=>{for(const n of document.getElementsByTagName("a"))c.has(n)||i(n,"hover")&&(c.add(n),n.addEventListener("mouseenter",t,{passive:!0}),n.addEventListener("mouseleave",o,{passive:!0}))});function t(n){const r=n.target.href;e&&clearTimeout(e),e=setTimeout(()=>{s(r)},80)}function o(){e&&(clearTimeout(e),e=0)}}function w(){let e;u(()=>{for(const t of document.getElementsByTagName("a"))c.has(t)||i(t,"viewport")&&(c.add(t),e??=y(),e.observe(t))})}function y(){const e=new WeakMap;return new IntersectionObserver((t,o)=>{for(const n of t){const r=n.target,a=e.get(r);n.isIntersecting?(a&&clearTimeout(a),e.set(r,setTimeout(()=>{o.unobserve(r),e.delete(r),s(r.href)},300))):a&&(clearTimeout(a),e.delete(r))}})}function L(){u(()=>{for(const e of document.getElementsByTagName("a"))i(e,"load")&&s(e.href)})}function s(e,t){const o=t?.ignoreSlowConnection??!1;if(S(e,o))if(d.add(e),document.createElement("link").relList?.supports?.("prefetch")&&t?.with!=="fetch"){const n=document.createElement("link");n.rel="prefetch",n.setAttribute("href",e),document.head.append(n)}else fetch(e,{priority:"low"})}function S(e,t){if(!navigator.onLine||!t&&m())return!1;try{const o=new URL(e,location.href);return location.origin===o.origin&&(location.pathname!==o.pathname||location.search!==o.search)&&!d.has(e)}catch{}return!1}function i(e,t){if(e?.tagName!=="A")return!1;const o=e.dataset.astroPrefetch;return o==="false"?!1:t==="tap"&&(o!=null||f)&&m()?!0:o==null&&f||o===""?t===h:o===t}function m(){if("connection"in navigator){const e=navigator.connection;return e.saveData||/2g/.test(e.effectiveType)}return!1}function u(e){e();let t=!1;document.addEventListener("astro:page-load",()=>{if(!t){t=!0;return}e()})}v(); 2 | -------------------------------------------------------------------------------- /docs/assets/tab.CrkoWeCF.js: -------------------------------------------------------------------------------- 1 | const E=new Map,y={set(e,t,r){E.has(e)||E.set(e,new Map);const n=E.get(e);if(!n.has(t)&&n.size!==0){console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(n.keys())[0]}.`);return}n.set(t,r)},get(e,t){return E.has(e)&&E.get(e).get(t)||null},remove(e,t){if(!E.has(e))return;const r=E.get(e);r.delete(t),r.size===0&&E.delete(e)}},rt=1e3,L="transitionend",q=e=>(e&&window.CSS&&window.CSS.escape&&(e=e.replace(/#([^\s"#']+)/g,(t,r)=>`#${CSS.escape(r)}`)),e),nt=e=>e==null?`${e}`:Object.prototype.toString.call(e).match(/\s([a-z]+)/i)[1].toLowerCase(),st=e=>{if(!e)return 0;let{transitionDuration:t,transitionDelay:r}=window.getComputedStyle(e);const n=Number.parseFloat(t),s=Number.parseFloat(r);return!n&&!s?0:(t=t.split(",")[0],r=r.split(",")[0],(Number.parseFloat(t)+Number.parseFloat(r))*rt)},ot=e=>{e.dispatchEvent(new Event(L))},m=e=>!e||typeof e!="object"?!1:(typeof e.jquery<"u"&&(e=e[0]),typeof e.nodeType<"u"),M=e=>m(e)?e.jquery?e[0]:e:typeof e=="string"&&e.length>0?document.querySelector(q(e)):null,it=e=>{if(!m(e)||e.getClientRects().length===0)return!1;const t=getComputedStyle(e).getPropertyValue("visibility")==="visible",r=e.closest("details:not([open])");if(!r)return t;if(r!==e){const n=e.closest("summary");if(n&&n.parentNode!==r||n===null)return!1}return t},$=e=>!e||e.nodeType!==Node.ELEMENT_NODE||e.classList.contains("disabled")?!0:typeof e.disabled<"u"?e.disabled:e.hasAttribute("disabled")&&e.getAttribute("disabled")!=="false",U=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,O=[],at=e=>{document.readyState==="loading"?(O.length||document.addEventListener("DOMContentLoaded",()=>{for(const t of O)t()}),O.push(e)):e()},ut=e=>{at(()=>{const t=U();if(t){const r=e.NAME,n=t.fn[r];t.fn[r]=e.jQueryInterface,t.fn[r].Constructor=e,t.fn[r].noConflict=()=>(t.fn[r]=n,e.jQueryInterface)}})},P=(e,t=[],r=e)=>typeof e=="function"?e(...t):r,ct=(e,t,r=!0)=>{if(!r){P(e);return}const s=st(t)+5;let i=!1;const o=({target:a})=>{a===t&&(i=!0,t.removeEventListener(L,o),P(e))};t.addEventListener(L,o),setTimeout(()=>{i||ot(t)},s)},lt=(e,t,r,n)=>{const s=e.length;let i=e.indexOf(t);return i===-1?!r&&n?e[s-1]:e[0]:(i+=r?1:-1,i=(i+s)%s,e[Math.max(0,Math.min(i,s-1))])},ft=/[^.]*(?=\..*)\.|.*/,dt=/\..*/,gt=/::\d+$/,N={};let k=1;const Q={mouseenter:"mouseover",mouseleave:"mouseout"},Et=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function G(e,t){return t&&`${t}::${k++}`||e.uidEvent||k++}function z(e){const t=G(e);return e.uidEvent=t,N[t]=N[t]||{},N[t]}function pt(e,t){return function r(n){return R(n,{delegateTarget:e}),r.oneOff&&f.off(e,n.type,t),t.apply(e,[n])}}function ht(e,t,r){return function n(s){const i=e.querySelectorAll(t);for(let{target:o}=s;o&&o!==this;o=o.parentNode)for(const a of i)if(a===o)return R(s,{delegateTarget:o}),n.oneOff&&f.off(e,s.type,t,r),r.apply(o,[s])}}function B(e,t,r=null){return Object.values(e).find(n=>n.callable===t&&n.delegationSelector===r)}function J(e,t,r){const n=typeof t=="string",s=n?r:t||r;let i=Z(e);return Et.has(i)||(i=e),[n,s,i]}function K(e,t,r,n,s){if(typeof t!="string"||!e)return;let[i,o,a]=J(t,r,n);t in Q&&(o=(et=>function(b){if(!b.relatedTarget||b.relatedTarget!==b.delegateTarget&&!b.delegateTarget.contains(b.relatedTarget))return et.call(this,b)})(o));const u=z(e),g=u[a]||(u[a]={}),c=B(g,o,i?r:null);if(c){c.oneOff=c.oneOff&&s;return}const _=G(o,t.replace(ft,"")),d=i?ht(e,r,o):pt(e,o);d.delegationSelector=i?r:null,d.callable=o,d.oneOff=s,d.uidEvent=_,g[_]=d,e.addEventListener(a,d,i)}function I(e,t,r,n,s){const i=B(t[r],n,s);i&&(e.removeEventListener(r,i,!!s),delete t[r][i.uidEvent])}function _t(e,t,r,n){const s=t[r]||{};for(const[i,o]of Object.entries(s))i.includes(n)&&I(e,t,r,o.callable,o.delegationSelector)}function Z(e){return e=e.replace(dt,""),Q[e]||e}const f={on(e,t,r,n){K(e,t,r,n,!1)},one(e,t,r,n){K(e,t,r,n,!0)},off(e,t,r,n){if(typeof t!="string"||!e)return;const[s,i,o]=J(t,r,n),a=o!==t,u=z(e),g=u[o]||{},c=t.startsWith(".");if(typeof i<"u"){if(!Object.keys(g).length)return;I(e,u,o,i,s?r:null);return}if(c)for(const _ of Object.keys(u))_t(e,u,_,t.slice(1));for(const[_,d]of Object.entries(g)){const x=_.replace(gt,"");(!a||t.includes(x))&&I(e,u,o,d.callable,d.delegationSelector)}},trigger(e,t,r){if(typeof t!="string"||!e)return null;const n=U(),s=Z(t),i=t!==s;let o=null,a=!0,u=!0,g=!1;i&&n&&(o=n.Event(t,r),n(e).trigger(o),a=!o.isPropagationStopped(),u=!o.isImmediatePropagationStopped(),g=o.isDefaultPrevented());const c=R(new Event(t,{bubbles:a,cancelable:!0}),r);return g&&c.preventDefault(),u&&e.dispatchEvent(c),c.defaultPrevented&&o&&o.preventDefault(),c}};function R(e,t={}){for(const[r,n]of Object.entries(t))try{e[r]=n}catch{Object.defineProperty(e,r,{configurable:!0,get(){return n}})}return e}function W(e){if(e==="true")return!0;if(e==="false")return!1;if(e===Number(e).toString())return Number(e);if(e===""||e==="null")return null;if(typeof e!="string")return e;try{return JSON.parse(decodeURIComponent(e))}catch{return e}}function D(e){return e.replace(/[A-Z]/g,t=>`-${t.toLowerCase()}`)}const Y={setDataAttribute(e,t,r){e.setAttribute(`data-bs-${D(t)}`,r)},removeDataAttribute(e,t){e.removeAttribute(`data-bs-${D(t)}`)},getDataAttributes(e){if(!e)return{};const t={},r=Object.keys(e.dataset).filter(n=>n.startsWith("bs")&&!n.startsWith("bsConfig"));for(const n of r){let s=n.replace(/^bs/,"");s=s.charAt(0).toLowerCase()+s.slice(1,s.length),t[s]=W(e.dataset[n])}return t},getDataAttribute(e,t){return W(e.getAttribute(`data-bs-${D(t)}`))}};class bt{static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(t){return t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t}_mergeConfigObj(t,r){const n=m(r)?Y.getDataAttribute(r,"config"):{};return{...this.constructor.Default,...typeof n=="object"?n:{},...m(r)?Y.getDataAttributes(r):{},...typeof t=="object"?t:{}}}_typeCheckConfig(t,r=this.constructor.DefaultType){for(const[n,s]of Object.entries(r)){const i=t[n],o=m(i)?"element":nt(i);if(!new RegExp(s).test(o))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${n}" provided type "${o}" but expected type "${s}".`)}}}const At="5.3.3";class mt extends bt{constructor(t,r){super(),t=M(t),t&&(this._element=t,this._config=this._getConfig(r),y.set(this._element,this.constructor.DATA_KEY,this))}dispose(){y.remove(this._element,this.constructor.DATA_KEY),f.off(this._element,this.constructor.EVENT_KEY);for(const t of Object.getOwnPropertyNames(this))this[t]=null}_queueCallback(t,r,n=!0){ct(t,r,n)}_getConfig(t){return t=this._mergeConfigObj(t,this._element),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}static getInstance(t){return y.get(M(t),this.DATA_KEY)}static getOrCreateInstance(t,r={}){return this.getInstance(t)||new this(t,typeof r=="object"?r:null)}static get VERSION(){return At}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(t){return`${t}${this.EVENT_KEY}`}}const C=e=>{let t=e.getAttribute("data-bs-target");if(!t||t==="#"){let r=e.getAttribute("href");if(!r||!r.includes("#")&&!r.startsWith("."))return null;r.includes("#")&&!r.startsWith("#")&&(r=`#${r.split("#")[1]}`),t=r&&r!=="#"?r.trim():null}return t?t.split(",").map(r=>q(r)).join(","):null},l={find(e,t=document.documentElement){return[].concat(...Element.prototype.querySelectorAll.call(t,e))},findOne(e,t=document.documentElement){return Element.prototype.querySelector.call(t,e)},children(e,t){return[].concat(...e.children).filter(r=>r.matches(t))},parents(e,t){const r=[];let n=e.parentNode.closest(t);for(;n;)r.push(n),n=n.parentNode.closest(t);return r},prev(e,t){let r=e.previousElementSibling;for(;r;){if(r.matches(t))return[r];r=r.previousElementSibling}return[]},next(e,t){let r=e.nextElementSibling;for(;r;){if(r.matches(t))return[r];r=r.nextElementSibling}return[]},focusableChildren(e){const t=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map(r=>`${r}:not([tabindex^="-"])`).join(",");return this.find(t,e).filter(r=>!$(r)&&it(r))},getSelectorFromElement(e){const t=C(e);return t&&l.findOne(t)?t:null},getElementFromSelector(e){const t=C(e);return t?l.findOne(t):null},getMultipleElementsFromSelector(e){const t=C(e);return t?l.find(t):[]}},yt="tab",Ot="bs.tab",h=`.${Ot}`,Nt=`hide${h}`,Dt=`hidden${h}`,Ct=`show${h}`,Tt=`shown${h}`,St=`click${h}`,wt=`keydown${h}`,vt=`load${h}`,Lt="ArrowLeft",V="ArrowRight",It="ArrowUp",j="ArrowDown",T="Home",F="End",p="active",H="fade",S="show",$t="dropdown",X=".dropdown-toggle",Rt=".dropdown-menu",w=`:not(${X})`,xt='.list-group, .nav, [role="tablist"]',Mt=".nav-item, .list-group-item",Pt=`.nav-link${w}, .list-group-item${w}, [role="tab"]${w}`,tt='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',v=`${Pt}, ${tt}`,kt=`.${p}[data-bs-toggle="tab"], .${p}[data-bs-toggle="pill"], .${p}[data-bs-toggle="list"]`;class A extends mt{constructor(t){super(t),this._parent=this._element.closest(xt),this._parent&&(this._setInitialAttributes(this._parent,this._getChildren()),f.on(this._element,wt,r=>this._keydown(r)))}static get NAME(){return yt}show(){const t=this._element;if(this._elemIsActive(t))return;const r=this._getActiveElem(),n=r?f.trigger(r,Nt,{relatedTarget:t}):null;f.trigger(t,Ct,{relatedTarget:r}).defaultPrevented||n&&n.defaultPrevented||(this._deactivate(r,t),this._activate(t,r))}_activate(t,r){if(!t)return;t.classList.add(p),this._activate(l.getElementFromSelector(t));const n=()=>{if(t.getAttribute("role")!=="tab"){t.classList.add(S);return}t.removeAttribute("tabindex"),t.setAttribute("aria-selected",!0),this._toggleDropDown(t,!0),f.trigger(t,Tt,{relatedTarget:r})};this._queueCallback(n,t,t.classList.contains(H))}_deactivate(t,r){if(!t)return;t.classList.remove(p),t.blur(),this._deactivate(l.getElementFromSelector(t));const n=()=>{if(t.getAttribute("role")!=="tab"){t.classList.remove(S);return}t.setAttribute("aria-selected",!1),t.setAttribute("tabindex","-1"),this._toggleDropDown(t,!1),f.trigger(t,Dt,{relatedTarget:r})};this._queueCallback(n,t,t.classList.contains(H))}_keydown(t){if(![Lt,V,It,j,T,F].includes(t.key))return;t.stopPropagation(),t.preventDefault();const r=this._getChildren().filter(s=>!$(s));let n;if([T,F].includes(t.key))n=r[t.key===T?0:r.length-1];else{const s=[V,j].includes(t.key);n=lt(r,t.target,s,!0)}n&&(n.focus({preventScroll:!0}),A.getOrCreateInstance(n).show())}_getChildren(){return l.find(v,this._parent)}_getActiveElem(){return this._getChildren().find(t=>this._elemIsActive(t))||null}_setInitialAttributes(t,r){this._setAttributeIfNotExists(t,"role","tablist");for(const n of r)this._setInitialAttributesOnChild(n)}_setInitialAttributesOnChild(t){t=this._getInnerElement(t);const r=this._elemIsActive(t),n=this._getOuterElement(t);t.setAttribute("aria-selected",r),n!==t&&this._setAttributeIfNotExists(n,"role","presentation"),r||t.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(t,"role","tab"),this._setInitialAttributesOnTargetPanel(t)}_setInitialAttributesOnTargetPanel(t){const r=l.getElementFromSelector(t);r&&(this._setAttributeIfNotExists(r,"role","tabpanel"),t.id&&this._setAttributeIfNotExists(r,"aria-labelledby",`${t.id}`))}_toggleDropDown(t,r){const n=this._getOuterElement(t);if(!n.classList.contains($t))return;const s=(i,o)=>{const a=l.findOne(i,n);a&&a.classList.toggle(o,r)};s(X,p),s(Rt,S),n.setAttribute("aria-expanded",r)}_setAttributeIfNotExists(t,r,n){t.hasAttribute(r)||t.setAttribute(r,n)}_elemIsActive(t){return t.classList.contains(p)}_getInnerElement(t){return t.matches(v)?t:l.findOne(v,t)}_getOuterElement(t){return t.closest(Mt)||t}static jQueryInterface(t){return this.each(function(){const r=A.getOrCreateInstance(this);if(typeof t=="string"){if(r[t]===void 0||t.startsWith("_")||t==="constructor")throw new TypeError(`No method named "${t}"`);r[t]()}})}}f.on(document,St,tt,function(e){["A","AREA"].includes(this.tagName)&&e.preventDefault(),!$(this)&&A.getOrCreateInstance(this).show()});f.on(window,vt,()=>{for(const e of l.find(kt))A.getOrCreateInstance(e)});ut(A);export{A as T}; 2 | -------------------------------------------------------------------------------- /docs/customize.html: -------------------------------------------------------------------------------- 1 | Customize | use-bootstrap-tag

Customize

Assuming you’re using a package manager like npm, you’ll have a file structure that looks like this:

your-project/
16 | ├── scss/
17 |    └── custom.scss
18 | └── node_modules/
19 |    └── bootstrap/
20 |        ├── js/
21 |        └── scss/
22 |    └── use-bootstrap-tag/
23 |        ├── dist/
24 |        └── scss/
25 | └── index.html
26 | 

In your custom.scss, you’ll import Bootstrap’s source Sass files. You have two options: include all of Bootstrap, or pick the parts you need.

// Custom.scss
27 | // Option A: Include all of Bootstrap
28 | 
29 | // Include any default variable overrides here (though functions won't be available)
30 | 
31 | @import "../node_modules/bootstrap/scss/bootstrap";
32 | @import "../node_modules/use-bootstrap-tag/scss/use-bootstrap-tag";
33 | 
34 | // Then add additional custom code here
35 | 
// Custom.scss
36 | // Option B: Include parts of Bootstrap
37 | 
38 | // 1. Include functions first (so you can manipulate colors, SVGs, calc, etc)
39 | @import "../node_modules/bootstrap/scss/functions";
40 | 
41 | // 2. Include any default variable overrides here
42 | 
43 | // 3. Include remainder of required Bootstrap stylesheets (including any separate color mode stylesheets)
44 | @import "../node_modules/bootstrap/scss/variables";
45 | @import "../node_modules/bootstrap/scss/variables-dark";
46 | 
47 | // 4. Include any default map overrides here
48 | 
49 | // 5. Include remainder of required parts
50 | @import "../node_modules/bootstrap/scss/maps";
51 | @import "../node_modules/bootstrap/scss/mixins";
52 | @import "../node_modules/bootstrap/scss/root";
53 | 
54 | // 6. Optionally include any other parts as needed
55 | @import "../node_modules/bootstrap/scss/utilities";
56 | @import "../node_modules/bootstrap/scss/reboot";
57 | @import "../node_modules/bootstrap/scss/type";
58 | @import "../node_modules/bootstrap/scss/images";
59 | @import "../node_modules/bootstrap/scss/containers";
60 | @import "../node_modules/bootstrap/scss/grid";
61 | @import "../node_modules/bootstrap/scss/helpers";
62 | 
63 | // 7. Optionally include utilities API last to generate classes based on the Sass map in `_utilities.scss`
64 | @import "../node_modules/bootstrap/scss/utilities/api";
65 | 
66 | // 8. Include use-bootstrap-tag
67 | @import "../node_modules/use-bootstrap-tag/scss/use-bootstrap-tag";
68 | 
69 | // 9. Add additional custom code here
70 | 

By default, components inherit their styles from the default Bootstrap theme. Therefore, any changes made to Bootstrap will automatically affect the styling of these components as well.

Read more about customize bootstrap styles at https://getbootstrap.com/docs/5.3/customize/sass/.

-------------------------------------------------------------------------------- /docs/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | use-bootstrap-tag | Tag input for Bootstrap 5

use-bootstrap-tag

Tag input for Bootstrap 5.

versionminified + gzipdownloads per monthtypes

Features
  • Custom separator: Set a specific delimiter character between tag elements.
  • Enable/disable duplicates: Toggle the allowance of duplicate tags.
  • Custom transformation: Define personalized modifications to input tag entries.
  • Max limit: Set a maximum limit of tags that can be added.
  • Sizing: Adjustable sizing to match user preferences or layouts.
  • Validation: Reflects validation states visually to align with Bootstrap's form validationfeedback.

Repository
https://github.com/use-bootstrap/use-bootstrap-tag
License

MIT

-------------------------------------------------------------------------------- /docs/install.html: -------------------------------------------------------------------------------- 1 | Install | use-bootstrap-tag 9 |

Install

To install this library, you can use npm for package management, the CDN for direct inclusion, or manually download it from the GitHub releases page.

  1. Install use-bootstrap-tag in your Node.js powered apps with the npm package:

    npm install use-bootstrap-tag
  2. After installation, you can import the library into your project as follows:

    import 'use-bootstrap-tag/dist/use-bootstrap-tag.css'
    17 | import UseBootstrapTag from 'use-bootstrap-tag'

You can use use-bootstrap-tag directly via CDN:

<link href="https://cdn.jsdelivr.net/npm/use-bootstrap-tag@2.2.2/dist/use-bootstrap-tag.min.css" rel="stylesheet">
18 | <script src="https://cdn.jsdelivr.net/npm/use-bootstrap-tag@2.2.2/dist/use-bootstrap-tag.min.js"></script>

Example

<!doctype html>
19 | <html lang="en">
20 |   <head>
21 |     <meta charset="utf-8">
22 |     <meta name="viewport" content="width=device-width, initial-scale=1">
23 |     <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
24 |     <link href="https://cdn.jsdelivr.net/npm/use-bootstrap-tag@2.2.2/dist/use-bootstrap-tag.min.css" rel="stylesheet">
25 |     <title>Example</title>
26 |   </head>
27 |   <body>
28 |     <div class="container pt-4">
29 |       <input type="text" class="form-control" value="html,css,js" id="example">
30 |     </div>
31 |     <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
32 |     <script src="https://cdn.jsdelivr.net/npm/use-bootstrap-tag@2.2.2/dist/use-bootstrap-tag.min.js"></script>
33 |     <script>
34 |       UseBootstrapTag(document.getElementById('example'))
35 |     </script>
36 |   </body>
37 | </html>

Visit the GitHub releases page to download the latest version

-------------------------------------------------------------------------------- /docs/methods.html: -------------------------------------------------------------------------------- 1 | Methods | use-bootstrap-tag 9 |

Methods

NameParamsReturnsExample
addValuestring | arrayvoid
example.addValue('react')
example.addValue('vue,svelte')
example.addValue(['solid', 'qwik'])
removeValuestring | arrayvoid
example.removeValue('react')
example.removeValue('vue,svelte')
example.removeValue(['solid', 'qwik'])
getValuenullstring
example.getValue()
getValuesnullarray
example.getValues()
-------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | import antfu from '@antfu/eslint-config' 2 | 3 | export default antfu({ 4 | rules: { 5 | 'style/jsx-one-expression-per-line': 'off', 6 | }, 7 | ignores: [ 8 | 'docs/*', 9 | 'public/*', 10 | '.vscode/*', 11 | ], 12 | }) 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "use-bootstrap-tag", 3 | "type": "module", 4 | "version": "2.2.2", 5 | "description": "Tag input for Bootstrap 5", 6 | "license": "MIT", 7 | "homepage": "https://use-bootstrap-tag.js.org", 8 | "repository": "https://github.com/use-bootstrap/use-bootstrap-tag", 9 | "bugs": { 10 | "url": "https://github.com/use-bootstrap/use-bootstrap-tag/issues" 11 | }, 12 | "keywords": [ 13 | "bootstrap tag", 14 | "tag input", 15 | "bootstrap input" 16 | ], 17 | "source": "./src/lib/use-bootstrap-tag.tsx", 18 | "main": "./dist/use-bootstrap-tag.esm.js", 19 | "module": "./dist/use-bootstrap-tag.esm.js", 20 | "types": "./dist/use-bootstrap-tag.esm.d.ts", 21 | "libName": "UseBootstrapTag", 22 | "files": [ 23 | "dist", 24 | "scss" 25 | ], 26 | "browserslist": [ 27 | ">= 0.5%", 28 | "last 2 major versions", 29 | "not dead", 30 | "Chrome >= 60", 31 | "Firefox >= 60", 32 | "Firefox ESR", 33 | "iOS >= 12", 34 | "Safari >= 12", 35 | "not Explorer <= 11" 36 | ], 37 | "scripts": { 38 | "dev": "astro dev --host", 39 | "prebuild": "rm -rf dist && tsc && eslint .", 40 | "build": "jalankan build:*", 41 | "build:js": "vite build", 42 | "build:js:min": "esbuild dist/*.js --minify --outdir=dist --out-extension:.js=.min.js --tsconfig-raw='{}'", 43 | "build:css": "sass --source-map --embed-sources src/lib:dist", 44 | "build:css:prefix": "postcss dist/*.css --use autoprefixer --map --replace", 45 | "build:css:min": "esbuild dist/*.css --minify --outdir=dist --out-extension:.css=.min.css", 46 | "build:docs": "astro build", 47 | "postbuild": "purgecss --config ./purgecss.config.cjs", 48 | "preview": "astro preview --host", 49 | "depcheck": "depcheck", 50 | "lint": "eslint .", 51 | "lint:fix": "eslint . --fix" 52 | }, 53 | "devDependencies": { 54 | "@antfu/eslint-config": "4.12.0", 55 | "@astrojs/solid-js": "5.0.7", 56 | "@fontsource/hind-siliguri": "5.2.5", 57 | "@fontsource/inter-tight": "5.2.5", 58 | "@types/node": "22.14.0", 59 | "astro": "4.16.18", 60 | "autoprefixer": "10.4.21", 61 | "bootstrap": "5.3.5", 62 | "bootstrap-esm": "1.0.1", 63 | "depcheck": "1.4.7", 64 | "esbuild": "0.25.2", 65 | "eslint": "9.24.0", 66 | "fast-dts": "1.0.1", 67 | "jalankan": "0.0.1", 68 | "postcss": "8.5.3", 69 | "postcss-cli": "11.0.1", 70 | "prettier": "3.5.3", 71 | "purgecss": "7.0.2", 72 | "sass": "npm:sass-embedded@1.78.0", 73 | "scule": "1.3.0", 74 | "shiki": "3.2.2", 75 | "solid-js": "1.9.5", 76 | "stef": "0.0.1", 77 | "typescript": "5.8.3", 78 | "vite": "6.2.6", 79 | "vite-plugin-full-reload": "1.2.0", 80 | "vite-plugin-solid": "2.11.6" 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /public/CNAME: -------------------------------------------------------------------------------- 1 | use-bootstrap-tag.js.org 2 | -------------------------------------------------------------------------------- /public/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /purgecss.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | css: ['docs/assets/*.css'], 3 | output: 'docs/assets', 4 | content: ['docs/**/*.{html,js}'], 5 | safelist: [ 6 | /^use-bootstrap-tag/, 7 | 'btn-secondary', 8 | 'btn-primary', 9 | 'btn-success', 10 | 'btn-danger', 11 | 'btn-warning', 12 | 'btn-info', 13 | 'btn-dark', 14 | 'btn-light', 15 | ], 16 | } 17 | -------------------------------------------------------------------------------- /scss/use-bootstrap-tag.scss: -------------------------------------------------------------------------------- 1 | $name: 'use-bootstrap-tag'; 2 | $target: #{$name}-target; 3 | $duplicate-transform: 'scale(1.1)'; 4 | 5 | // Hide target 6 | .#{$target} { 7 | position: fixed; 8 | left: -9999rem; 9 | top: -9999rem; 10 | } 11 | 12 | .#{$name} { 13 | .input-wrapper { 14 | position: relative; 15 | min-width: 4px; 16 | flex-grow: 1; 17 | white-space: nowrap; 18 | 19 | >span { 20 | visibility: hidden; 21 | } 22 | } 23 | 24 | input[type="text"] { 25 | position: absolute; 26 | top: 0; 27 | left: 0; 28 | padding: 0; 29 | outline: 0; 30 | border: 0; 31 | width: 100%; 32 | background-color: transparent; 33 | 34 | // Source: bootstrap/scss/forms/_form-control.scss:75 35 | &::placeholder { 36 | color: $input-placeholder-color; 37 | opacity: 1; 38 | } 39 | } 40 | 41 | .#{$target}:not(:disabled)+& { 42 | cursor: text; 43 | } 44 | 45 | // Tags 46 | >button { 47 | transition-property: transform, height; 48 | transition-duration: .15s; 49 | transition-timing-function: cubic-bezier(.17, .84, .44, 1); 50 | border-radius: calc(#{$input-border-radius} - #{$input-border-width}); 51 | overflow-wrap: anywhere; 52 | 53 | &.duplicate { 54 | transform: #{$duplicate-transform}; 55 | } 56 | 57 | &.btn-sm { 58 | border-radius: calc(#{$input-border-radius-sm} - #{$input-border-width}); 59 | } 60 | 61 | &.btn-lg { 62 | border-radius: calc(#{$input-border-radius-lg} - #{$input-border-width}); 63 | } 64 | 65 | &:not(:disabled) { 66 | cursor: default; 67 | } 68 | } 69 | 70 | // Keep the focus style. Source: bootstrap/scss/forms/_form-control.scss:34 71 | &.focus { 72 | color: $input-focus-color; 73 | background-color: $input-focus-bg; 74 | border-color: $input-focus-border-color; 75 | outline: 0; 76 | 77 | @if $enable-shadows { 78 | @include box-shadow($input-box-shadow, $input-focus-box-shadow); 79 | } 80 | 81 | @else { 82 | box-shadow: $input-focus-box-shadow; 83 | } 84 | } 85 | 86 | } 87 | 88 | // Source: bootstrap/scss/mixins/_forms.scss:58 89 | @mixin use-bootstrap-tag-form-validation-state($state, 90 | $color, 91 | $icon, 92 | $tooltip-color: color-contrast($color), 93 | $tooltip-bg-color: rgba($color, $form-feedback-tooltip-opacity), 94 | $focus-box-shadow: 0 0 $input-btn-focus-blur $input-focus-width rgba($color, $input-btn-focus-color-opacity), 95 | $border-color: $color) { 96 | .form-control { 97 | @include form-validation-state-selector($state) { 98 | +.#{$name} { 99 | border-color: $border-color; 100 | 101 | @if $enable-validation-icons { 102 | padding-right: $input-height-inner; 103 | background-image: escape-svg($icon); 104 | background-repeat: no-repeat; 105 | background-position: right $input-height-inner-quarter center; 106 | background-size: $input-height-inner-half $input-height-inner-half; 107 | } 108 | 109 | &.focus { 110 | border-color: $border-color; 111 | box-shadow: $focus-box-shadow; 112 | } 113 | } 114 | } 115 | } 116 | } 117 | 118 | // Source: bootstrap/scss/forms/_validation.css:9 119 | @each $state, 120 | $data in $form-validation-states { 121 | @include use-bootstrap-tag-form-validation-state($state, $data...); 122 | } 123 | -------------------------------------------------------------------------------- /src/components/Code.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { readFile } from 'node:fs/promises' 3 | import type { BuiltinLanguage, LanguageRegistration, SpecialLanguage } from 'shiki' 4 | 5 | interface Props { 6 | code: any 7 | /** 8 | * The language of your code. 9 | * Supports all languages listed here: https://shiki.style/languages 10 | * Instructions for loading a custom language: https://shiki.style/guide/load-lang 11 | * 12 | * @default "html" 13 | */ 14 | lang?: BuiltinLanguage | SpecialLanguage | LanguageRegistration 15 | } 16 | 17 | let { code, lang = 'html' } = Astro.props 18 | if (typeof code !== 'string') { 19 | code = await readFile(code.moduleId, 'utf8') 20 | code = (code as string).split('\n').filter(line => !line.includes('// @ts-ignore')).join('\n') 21 | } 22 | import { codeToHtml } from 'shiki' 23 | const value = await codeToHtml(code, { 24 | lang: lang as any, 25 | themes: { 26 | light: 'one-light', 27 | dark: 'one-dark-pro', 28 | }, 29 | }) 30 | --- 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/components/DemoCard.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { titleCase } from 'scule' 3 | import Code from './Code.astro' 4 | 5 | const randomId = () => Math.random().toString(36).slice(2, 7) 6 | const id = randomId() 7 | const previewId = randomId() 8 | const codeId = randomId() 9 | interface Props { 10 | title: string 11 | code: any 12 | } 13 | const props = Astro.props 14 | --- 15 | 16 |
17 |
18 | 29 |
30 |
31 | 32 |
33 |
34 | 35 |
36 |
37 |
38 |
39 | 40 | -------------------------------------------------------------------------------- /src/components/Layout.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import '@fontsource/hind-siliguri/latin.css' 3 | import '@fontsource/inter-tight/latin.css' 4 | import 'bootstrap/dist/css/bootstrap.min.css' 5 | import '../lib/use-bootstrap-tag.scss' 6 | import '../style.scss' 7 | import pkg from '../../package.json' 8 | import Pagination from './Pagination.astro' 9 | interface Props { 10 | title?: string 11 | } 12 | const props = Astro.props 13 | const pathname = Astro.url.pathname 14 | 15 | const links = [ 16 | { 17 | href: '/', 18 | text: 'Home', 19 | }, 20 | { 21 | href: '/install.html', 22 | text: 'Install', 23 | }, 24 | { 25 | href: '/demo.html', 26 | text: 'Demo', 27 | }, 28 | { 29 | href: '/methods.html', 30 | text: 'Methods', 31 | }, 32 | { 33 | href: '/customize.html', 34 | text: 'Customize', 35 | }, 36 | ] 37 | --- 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | {props.title ?? pkg.name} | {props.title ? pkg.name : pkg.description} 48 | 56 | 57 | 58 | 59 | 60 |
61 | 85 |
86 |
87 | 100 |
101 |
102 |
103 | 104 | 105 |
106 | 107 |
108 | 109 | 110 |
111 | 112 |
113 | 114 | 115 | -------------------------------------------------------------------------------- /src/components/Pagination.astro: -------------------------------------------------------------------------------- 1 | --- 2 | interface Props { 3 | links: { 4 | href: string 5 | text: string 6 | }[] 7 | } 8 | const props = Astro.props 9 | const links = props.links 10 | const pathname = Astro.url.pathname 11 | 12 | let prevLink = null as null | { href: any; text: any } 13 | for (let i = 0; i < links.length; i++) { 14 | if (links[i].href === pathname) { 15 | if (i > 0) { 16 | prevLink = links[i - 1] 17 | } 18 | break 19 | } 20 | } 21 | 22 | let nextLink = null as null | { href: any; text: any } 23 | for (let i = 0; i < links.length; i++) { 24 | if (links[i].href === pathname) { 25 | if (i < links.length - 1) { 26 | nextLink = links[i + 1] 27 | } 28 | break 29 | } 30 | } 31 | --- 32 | 33 | 73 | -------------------------------------------------------------------------------- /src/components/customize/CustomizeA.scss: -------------------------------------------------------------------------------- 1 | // Custom.scss 2 | // Option A: Include all of Bootstrap 3 | 4 | // Include any default variable overrides here (though functions won't be available) 5 | 6 | @import "../node_modules/bootstrap/scss/bootstrap"; 7 | @import "../node_modules/use-bootstrap-tag/scss/use-bootstrap-tag"; 8 | 9 | // Then add additional custom code here 10 | -------------------------------------------------------------------------------- /src/components/customize/CustomizeB.scss: -------------------------------------------------------------------------------- 1 | // Custom.scss 2 | // Option B: Include parts of Bootstrap 3 | 4 | // 1. Include functions first (so you can manipulate colors, SVGs, calc, etc) 5 | @import "../node_modules/bootstrap/scss/functions"; 6 | 7 | // 2. Include any default variable overrides here 8 | 9 | // 3. Include remainder of required Bootstrap stylesheets (including any separate color mode stylesheets) 10 | @import "../node_modules/bootstrap/scss/variables"; 11 | @import "../node_modules/bootstrap/scss/variables-dark"; 12 | 13 | // 4. Include any default map overrides here 14 | 15 | // 5. Include remainder of required parts 16 | @import "../node_modules/bootstrap/scss/maps"; 17 | @import "../node_modules/bootstrap/scss/mixins"; 18 | @import "../node_modules/bootstrap/scss/root"; 19 | 20 | // 6. Optionally include any other parts as needed 21 | @import "../node_modules/bootstrap/scss/utilities"; 22 | @import "../node_modules/bootstrap/scss/reboot"; 23 | @import "../node_modules/bootstrap/scss/type"; 24 | @import "../node_modules/bootstrap/scss/images"; 25 | @import "../node_modules/bootstrap/scss/containers"; 26 | @import "../node_modules/bootstrap/scss/grid"; 27 | @import "../node_modules/bootstrap/scss/helpers"; 28 | 29 | // 7. Optionally include utilities API last to generate classes based on the Sass map in `_utilities.scss` 30 | @import "../node_modules/bootstrap/scss/utilities/api"; 31 | 32 | // 8. Include use-bootstrap-tag 33 | @import "../node_modules/use-bootstrap-tag/scss/use-bootstrap-tag"; 34 | 35 | // 9. Add additional custom code here 36 | -------------------------------------------------------------------------------- /src/components/customize/CustomizeStructure.txt: -------------------------------------------------------------------------------- 1 | your-project/ 2 | ├── scss/ 3 | │ └── custom.scss 4 | └── node_modules/ 5 | │ └── bootstrap/ 6 | │ ├── js/ 7 | │ └── scss/ 8 | │ └── use-bootstrap-tag/ 9 | │ ├── dist/ 10 | │ └── scss/ 11 | └── index.html 12 | -------------------------------------------------------------------------------- /src/components/demo/AllowDuplicates.astro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /src/components/demo/Basic.astro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /src/components/demo/CustomSeparator.astro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /src/components/demo/Disabled.astro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /src/components/demo/Label.astro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /src/components/demo/MaxLimit.astro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /src/components/demo/Methods.astro: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 50 | -------------------------------------------------------------------------------- /src/components/demo/NoInputOnblur.astro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /src/components/demo/Placeholder.astro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /src/components/demo/Sizing.astro: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 |
6 | 7 | 12 | -------------------------------------------------------------------------------- /src/components/demo/TransformTags.astro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /src/components/demo/Validation.astro: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
This field is required.
5 |
Looks good!
6 |
7 | 8 |
9 | 10 | 30 | 31 | 32 |
Server-side
33 |
34 |
35 | 36 |
This field is required.
37 |
38 |
39 | 40 |
Looks good!
41 |
42 |
43 | -------------------------------------------------------------------------------- /src/components/demo/Variants.astro: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 16 | -------------------------------------------------------------------------------- /src/components/demo/XPosition.astro: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 5 |
6 | 7 | 8 | 13 | -------------------------------------------------------------------------------- /src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /src/global.d.ts: -------------------------------------------------------------------------------- 1 | import type library from './lib/use-bootstrap-tag' 2 | 3 | declare global { 4 | interface Window { 5 | UseBootstrapTag: typeof library 6 | } 7 | const UseBootstrapTag: typeof library 8 | } 9 | -------------------------------------------------------------------------------- /src/lib/use-bootstrap-tag.scss: -------------------------------------------------------------------------------- 1 | @import '../../node_modules/bootstrap/scss/functions'; 2 | 3 | // any default variable overrides here 4 | 5 | @import '../../node_modules/bootstrap/scss/variables'; 6 | @import '../../node_modules/bootstrap/scss/variables-dark'; 7 | 8 | // any default map overrides here 9 | 10 | @import '../../node_modules/bootstrap/scss/maps'; 11 | @import '../../node_modules/bootstrap/scss/mixins'; 12 | 13 | @import '../../scss/use-bootstrap-tag.scss'; 14 | -------------------------------------------------------------------------------- /src/lib/use-bootstrap-tag.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-new-func */ 2 | import { effect, state } from 'stef' 3 | import { arraysAreEqual, change, createElement, processData, pull } from './util' 4 | 5 | const name = 'use-bootstrap-tag' 6 | const classTarget = `${name}-target` 7 | 8 | interface UseBootstrapTagReturnType { 9 | getValue: () => string 10 | getValues: () => string[] 11 | addValue: (value: string | string[]) => void 12 | removeValue: (value: string | string[]) => void 13 | } 14 | 15 | export default function UseBootstrapTag(element: Element | HTMLElement | null): UseBootstrapTagReturnType { 16 | const target = element as HTMLInputElement 17 | 18 | // If reinitialized 19 | const nextElement = target.nextElementSibling 20 | if (nextElement && nextElement.classList.contains(name)) { 21 | nextElement.remove() 22 | } 23 | 24 | // Root 25 | const root = createElement('div') 26 | target.insertAdjacentElement('afterend', root) 27 | 28 | // Config 29 | const dataset = target.dataset 30 | const config = { 31 | separator: dataset.ubTagSeparator || ',', 32 | variant: dataset.ubTagVariant || 'secondary', 33 | xPosition: dataset.ubTagXPosition as 'left' | 'right' || 'right', 34 | transform: dataset.ubTagTransform || 'input => input', 35 | isDuplicate: dataset.ubTagDuplicate !== undefined, 36 | max: +dataset.ubTagMax! > 0 ? +dataset.ubTagMax! : undefined, 37 | noInputOnblur: dataset.ubTagNoInputOnblur !== undefined, 38 | } 39 | 40 | const tags = () => root.querySelectorAll('button') 41 | const animateTag = (tag: HTMLButtonElement) => { 42 | tag.classList.add('duplicate') 43 | setTimeout(() => { 44 | tag.classList.remove('duplicate') 45 | }, 150) 46 | } 47 | 48 | // Returned methods 49 | const getValue = (): string => target.value 50 | const getValues = (): string[] => getValue().split(config.separator).filter(i => i !== '') 51 | const addValue = (value: string | string[]): void => { 52 | const values = getValues() 53 | const insert = processData(value, config.separator) 54 | if (!config.max || values.length < config.max) { 55 | // Get duplicates 56 | const duplicates = [] as number[] 57 | !config.isDuplicate && values.forEach((value, index) => insert.includes(value) && duplicates.push(index)) 58 | 59 | // Get inserted 60 | const inserted = [] as string[] 61 | insert.forEach((i) => { 62 | if (values.includes(i)) { 63 | config.isDuplicate && inserted.push(i) 64 | } 65 | else { 66 | inserted.push(i) 67 | } 68 | }) 69 | 70 | values.push(...inserted) 71 | if (!arraysAreEqual(getValues(), values)) { 72 | change(target, values.join(config.separator)) 73 | // Animate inserts 74 | inserted.forEach((item) => { 75 | const tag = tags()[values.lastIndexOf(item)] 76 | const tagHeight = tag.offsetHeight 77 | tag!.style.height = 0 as unknown as string 78 | setTimeout(() => (tag.style.height = `${tagHeight}px`), 0) 79 | setTimeout(() => tag.style.removeProperty('height'), 150) 80 | }) 81 | } 82 | // Animate duplicates 83 | if (!config.isDuplicate) { 84 | duplicates.forEach(index => animateTag(tags()[index])) 85 | } 86 | } 87 | else { 88 | insert.length > 0 && tags().forEach(animateTag) 89 | } 90 | } 91 | const removeValue = (value: string | string[]): void => { 92 | const values = getValues() 93 | const remove = processData(value, config.separator) 94 | remove.forEach(i => pull(values, i)) 95 | if (!arraysAreEqual(getValues(), values)) { 96 | change(target, values.join(config.separator)) 97 | } 98 | } 99 | 100 | // Target states 101 | const classList = target.classList 102 | const disabled = target.disabled 103 | 104 | target.tabIndex = -1 105 | classList.add(classTarget) 106 | 107 | // Local states 108 | const [value, setValue] = state(target.value) 109 | const [focus, setFocus] = state(false) 110 | const [text, setText] = state('') 111 | const values = () => value().split(config.separator).filter(i => i.trim() !== '') 112 | const texts = () => new Function(`return ${config.transform}`)()(text().trim()) as string 113 | const placeholder = () => values().length ? '' : target.placeholder 114 | 115 | // Styling 116 | root.className = `${name} d-flex flex-wrap align-items-center gap-1 ${classList.value}`.replace(classTarget, '') 117 | effect(() => { 118 | focus() ? root.classList.add('focus') : root.classList.remove('focus') 119 | }) 120 | 121 | // Functions 122 | const textFocus = () => root.querySelector('input')?.focus() 123 | const removeByIndex = (index: number) => { 124 | if (index >= 0) { 125 | removeValue(values()[index]) 126 | } 127 | } 128 | const appendTag = (force = false) => { 129 | const value = texts() 130 | value === '' && setText('') 131 | if (text().includes(config.separator) || (force && text() !== '')) { 132 | addValue(value.split(config.separator).filter(i => i.trim() !== '')) 133 | setText('') 134 | } 135 | } 136 | 137 | // Tags 138 | const tagElement = createElement('button', { 139 | type: 'button', 140 | className: `align-items-center gap-1 d-inline-flex py-0 border-0 btn btn-${config.variant}`, 141 | disabled, 142 | }) 143 | classList.contains('form-control-sm') && tagElement.classList.add('btn-sm') 144 | classList.contains('form-control-lg') && tagElement.classList.add('btn-lg') 145 | config.xPosition === 'left' && tagElement.classList.add('flex-row-reverse') 146 | const closeTagElement = createElement('span', { 147 | className: 'd-inline-flex', 148 | role: 'button', 149 | tabIndex: -1, 150 | innerHTML: '', 151 | }) 152 | const renderTags = (items: string[]) => { 153 | tags().forEach(tag => tag.remove()) 154 | items.reverse().forEach((value, i) => { 155 | const index = items.length - 1 - i 156 | const tag = tagElement.cloneNode() as typeof tagElement 157 | tag.innerHTML = value 158 | tag.onfocus = () => { 159 | tag.classList.add('active') 160 | setFocus(true) 161 | } 162 | tag.onblur = () => { 163 | tag.classList.remove('active') 164 | setFocus(false) 165 | } 166 | tag.onkeydown = ({ key }) => { 167 | if (key === 'Backspace' || key === 'Delete') { 168 | removeByIndex(index) 169 | const nextFocus = key === 'Backspace' ? index - 1 : values().length === index ? -1 : index 170 | if (nextFocus === -1) { 171 | textFocus() 172 | } 173 | else { 174 | tags()[nextFocus].focus() 175 | } 176 | } 177 | } 178 | if (!disabled) { 179 | const span = closeTagElement.cloneNode(true) as typeof closeTagElement 180 | span.onclick = () => { 181 | removeByIndex(index) 182 | textFocus() 183 | } 184 | tag.append(span) 185 | } 186 | root.prepend(tag) 187 | }) 188 | } 189 | effect(() => { 190 | renderTags(values()) 191 | }) 192 | 193 | // Input 194 | if (!disabled) { 195 | const wrapper = createElement('div', { 196 | className: 'input-wrapper', 197 | }) 198 | const span = createElement('span') 199 | const input = createElement('input', { 200 | type: 'text', 201 | }) 202 | input.onfocus = () => { 203 | setFocus(true) 204 | } 205 | input.onblur = () => { 206 | setFocus(false) 207 | config.noInputOnblur ? setText('') : appendTag(true) 208 | } 209 | input.onkeydown = (e) => { 210 | if (text() === '' && e.key === 'Backspace') { 211 | removeByIndex(values().length - 1) 212 | } 213 | if (text() !== '' && e.key === 'Enter') { 214 | appendTag(true) 215 | e.preventDefault() // prevent form submit 216 | } 217 | } 218 | input.oninput = () => { 219 | setText(input.value) 220 | appendTag() 221 | } 222 | effect(() => { 223 | span.innerHTML = text() || placeholder() || 'i' 224 | input.placeholder = placeholder() 225 | input.value = text() 226 | }) 227 | wrapper.append(span, input) 228 | root.append(wrapper) 229 | } 230 | 231 | root.onclick = (e) => { 232 | if ((e.target as Element).tagName !== 'BUTTON') { 233 | textFocus() 234 | } 235 | } 236 | 237 | target.addEventListener('change', () => { 238 | setValue(target.value) 239 | }) 240 | target.addEventListener('focus', textFocus) 241 | 242 | return { getValue, getValues, addValue, removeValue } 243 | } 244 | -------------------------------------------------------------------------------- /src/lib/util.ts: -------------------------------------------------------------------------------- 1 | export function arraysAreEqual(arr1: T[], arr2: T[]) { 2 | return arr1.length === arr2.length && arr1.every((value, index) => value === arr2[index]) 3 | } 4 | 5 | export function change(target: HTMLInputElement, value: string) { 6 | target.value = value 7 | target.dispatchEvent(new Event('change')) 8 | } 9 | 10 | export function pull(items: T[], value: T): void { 11 | const i = items.lastIndexOf(value) 12 | i !== -1 && items.splice(i, 1) 13 | } 14 | 15 | export function createElement(tagName: T, attributes?: { [K in keyof HTMLElementTagNameMap[T]]?: HTMLElementTagNameMap[T][K] }): HTMLElementTagNameMap[T] { 16 | const element = document.createElement(tagName) 17 | return Object.assign(element, attributes) 18 | } 19 | 20 | export function processData(data: string | string[] | (string | string[])[], separator: string): string[] { 21 | return (typeof data === 'string' 22 | ? data.split(separator) 23 | : Array.isArray(data) 24 | ? data.flatMap(item => (typeof item === 'string' ? item.split(separator) : [])) 25 | : []) as string[] 26 | } 27 | -------------------------------------------------------------------------------- /src/pages/customize.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import Layout from '../components/Layout.astro' 3 | import Code from '../components/Code.astro' 4 | import CustomizeStructure from '../components/customize/CustomizeStructure.txt?raw' 5 | import CustomizeA from '../components/customize/CustomizeA.scss?raw' 6 | import CustomizeB from '../components/customize/CustomizeB.scss?raw' 7 | --- 8 | 9 | 10 |

Customize

11 |

Assuming you’re using a package manager like npm, you’ll have a file structure that looks like this:

12 | 13 |

In your custom.scss, you’ll import Bootstrap’s source Sass files. You have two options: include all of Bootstrap, or pick the parts you need.

14 | 15 | 16 |

By default, components inherit their styles from the default Bootstrap theme. Therefore, any changes made to Bootstrap will automatically affect the styling of these components as well.

17 |

Read more about customize bootstrap styles at https://getbootstrap.com/docs/5.3/customize/sass/.

18 |
19 | -------------------------------------------------------------------------------- /src/pages/demo.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import Layout from '../components/Layout.astro' 3 | import DemoCard from '../components/DemoCard.astro' 4 | import Basic from '../components/demo/Basic.astro' 5 | import Placeholder from '../components/demo/Placeholder.astro' 6 | import MaxLimit from '../components/demo/MaxLimit.astro' 7 | import CustomSeparator from '../components/demo/CustomSeparator.astro' 8 | import AllowDuplicates from '../components/demo/AllowDuplicates.astro' 9 | import TransformTags from '../components/demo/TransformTags.astro' 10 | import Disabled from '../components/demo/Disabled.astro' 11 | import NoInputOnblur from '../components/demo/NoInputOnblur.astro' 12 | import Label from '../components/demo/Label.astro' 13 | import XPosition from '../components/demo/XPosition.astro' 14 | import Sizing from '../components/demo/Sizing.astro' 15 | import Validation from '../components/demo/Validation.astro' 16 | import Methods from '../components/demo/Methods.astro' 17 | import Variants from '../components/demo/Variants.astro' 18 | 19 | const demo = [ 20 | { 21 | title: 'Basic', 22 | code: Basic, 23 | }, 24 | { 25 | title: 'Placeholder', 26 | code: Placeholder, 27 | }, 28 | { 29 | title: 'MaxLimit', 30 | code: MaxLimit, 31 | }, 32 | { 33 | title: 'CustomSeparator', 34 | code: CustomSeparator, 35 | }, 36 | { 37 | title: 'AllowDuplicates', 38 | code: AllowDuplicates, 39 | }, 40 | { 41 | title: 'TransformTags', 42 | code: TransformTags, 43 | }, 44 | { 45 | title: 'Disabled', 46 | code: Disabled, 47 | }, 48 | { 49 | title: 'NoInputOnblur', 50 | code: NoInputOnblur, 51 | }, 52 | { 53 | title: 'Label', 54 | code: Label, 55 | }, 56 | { 57 | title: 'XPosition', 58 | code: XPosition, 59 | }, 60 | { 61 | title: 'Sizing', 62 | code: Sizing, 63 | }, 64 | { 65 | title: 'Validation', 66 | code: Validation, 67 | }, 68 | { 69 | title: 'Methods', 70 | code: Methods, 71 | }, 72 | { 73 | title: 'Variants', 74 | code: Variants, 75 | }, 76 | ] 77 | --- 78 | 79 | 84 | 85 | 86 |

Demo

87 |
88 | { 89 | demo.map((item) => ( 90 |
91 | 92 | 93 | 94 |
95 | )) 96 | } 97 |
98 |
99 | 100 | 107 | -------------------------------------------------------------------------------- /src/pages/index.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import Layout from '../components/Layout.astro' 3 | import pkg from '../../package.json' 4 | const badges = [ 5 | { 6 | src: `https://img.shields.io/npm/v/${pkg.name}`, 7 | alt: 'version', 8 | }, 9 | { 10 | src: `https://img.shields.io/bundlephobia/minzip/${pkg.name}/${pkg.version}`, 11 | alt: 'minified + gzip', 12 | }, 13 | { 14 | src: `https://img.shields.io/npm/dm/${pkg.name}`, 15 | alt: 'downloads per month', 16 | }, 17 | { 18 | src: `https://badgen.net/npm/types/${pkg.name}`, 19 | alt: 'types', 20 | }, 21 | ] 22 | --- 23 | 24 | 25 |

{pkg.name}

26 |

{pkg.description}.

27 |
28 | {badges.map((badge) => {badge.alt})} 29 |
30 |
31 |
Features
32 |
    33 |
  • Custom separator: Set a specific delimiter character between tag elements.
  • 34 |
  • Enable/disable duplicates: Toggle the allowance of duplicate tags.
  • 35 |
  • Custom transformation: Define personalized modifications to input tag entries.
  • 36 |
  • Max limit: Set a maximum limit of tags that can be added.
  • 37 |
  • Sizing: Adjustable sizing to match user preferences or layouts.
  • 38 |
  • Validation: Reflects validation states visually to align with Bootstrap's form validationfeedback.
  • 39 |
40 |
41 |
Repository
42 | {pkg.repository} 43 |
44 |
License
45 |

{pkg.license}

46 |
47 | -------------------------------------------------------------------------------- /src/pages/install.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import Layout from '../components/Layout.astro' 3 | import Code from '../components/Code.astro' 4 | import pkg from '../../package.json' 5 | 6 | const npmImport = `import '${pkg.name}/dist/${pkg.name}.css' 7 | import ${pkg.libName} from '${pkg.name}'` 8 | const cdnCss = `` 9 | const cdnJs = `` 10 | const cdnExample = ` 11 | 12 | 13 | 14 | 15 | 16 | ${cdnCss} 17 | Example 18 | 19 | 20 |
21 | 22 |
23 | 24 | ${cdnJs} 25 | 28 | 29 | ` 30 | --- 31 | 32 | 33 |

Install

34 |

To install this library, you can use npm for package management, the CDN for direct inclusion, or manually download it from the GitHub releases page.

35 | 46 |
47 |
48 |
    49 |
  1. 50 |

    Install {pkg.name} in your Node.js powered apps with the npm package:

    51 | 52 |
  2. 53 |
  3. 54 |

    After installation, you can import the library into your project as follows:

    55 | 56 |
  4. 57 |
58 |
59 |
60 |

You can use {pkg.name} directly via CDN:

61 | 62 |

Example

63 | 64 |
65 |
66 |

Visit the GitHub releases page to download the latest version

67 |
68 |
69 |
70 | 71 | 76 | -------------------------------------------------------------------------------- /src/pages/methods.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import Layout from '../components/Layout.astro' 3 | import Code from '../components/Code.astro' 4 | --- 5 | 6 | 11 | 12 | 13 |

Methods

14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 34 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 46 | 47 | 48 | 49 | 52 | 53 | 54 | 55 | 56 | 57 | 60 | 61 | 62 |
NameParamsReturnsExample
addValuestring | arrayvoid 30 | 31 | 32 | 33 |
removeValuestring | arrayvoid 40 | 41 | 42 | 43 |
getValuenullstring 50 | 51 |
getValuesnullarray 58 | 59 |
63 |
64 |
65 | -------------------------------------------------------------------------------- /src/style.scss: -------------------------------------------------------------------------------- 1 | @import '../node_modules/bootstrap/scss/functions'; 2 | @import '../node_modules/bootstrap/scss/variables'; 3 | @import '../node_modules/bootstrap/scss/variables-dark'; 4 | @import '../node_modules/bootstrap/scss/mixins'; 5 | 6 | :root { 7 | --bs-font-sans-serif: 'Hind Siliguri'; 8 | } 9 | 10 | .h1, 11 | .h2, 12 | .h3, 13 | .h4, 14 | .h5, 15 | .h6, 16 | h1, 17 | h2, 18 | h3, 19 | h4, 20 | h5, 21 | h6 { 22 | font-family: 'Inter Tight'; 23 | font-weight: 900; 24 | } 25 | 26 | .form-switch { 27 | 28 | .form-check-input, 29 | .form-check-label { 30 | cursor: pointer; 31 | user-select: none; 32 | } 33 | } 34 | 35 | .page-link:focus { 36 | box-shadow: none; 37 | } 38 | 39 | .shiki { 40 | padding: 1rem 1.25rem; 41 | border-radius: var(--bs-border-radius); 42 | 43 | [data-bs-theme="light"] & { 44 | background-color: #fafaf9 !important; 45 | box-shadow: inset 0 2px 4px 0 #0000000d; 46 | text-shadow: 1px 1px #fff; 47 | } 48 | 49 | [data-bs-theme="dark"] & { 50 | --shiki-dark-bg: #2b3035 !important; 51 | border: 1px solid var(--bs-border-color); 52 | text-shadow: 1px 1px #000; 53 | 54 | &, 55 | & span { 56 | color: var(--shiki-dark) !important; 57 | background-color: var(--shiki-dark-bg) !important; 58 | } 59 | } 60 | 61 | @include media-breakpoint-up(sm) { 62 | scrollbar-width: thin; 63 | } 64 | } 65 | 66 | @include media-breakpoint-down(sm) { 67 | .navbar-brand { 68 | font-size: 1rem; 69 | } 70 | 71 | .badge { 72 | font-family: 'Inter Tight'; 73 | } 74 | 75 | #main-nav::-webkit-scrollbar { 76 | display: none; 77 | } 78 | 79 | #main-nav { 80 | -ms-overflow-style: none; 81 | scrollbar-width: none; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "astro/tsconfigs/strict", 3 | "compilerOptions": { 4 | "jsx": "preserve", 5 | "jsxImportSource": "solid-js" 6 | }, 7 | "exclude": ["dist"] 8 | } 9 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'node:path' 2 | import { generate } from 'fast-dts' 3 | import { defineConfig } from 'vite' 4 | import solid from 'vite-plugin-solid' 5 | import pkg from './package.json' 6 | 7 | // https://vitejs.dev/config/ 8 | export default defineConfig({ 9 | build: { 10 | outDir: 'dist', 11 | minify: false, 12 | copyPublicDir: false, 13 | lib: { 14 | entry: resolve(__dirname, pkg.source), 15 | name: pkg.libName, 16 | formats: ['es', 'iife'], 17 | fileName: format => `${pkg.name}.${format === 'es' ? 'esm.js' : 'js'}`, 18 | }, 19 | }, 20 | plugins: [ 21 | solid(), 22 | { 23 | name: 'dts', 24 | async closeBundle() { 25 | await generate(pkg.source, pkg.types) 26 | }, 27 | }, 28 | ], 29 | }) 30 | --------------------------------------------------------------------------------