Full Code of Choices-js/Choices for AI

main 59feffe87448 cached
199 files
2.2 MB
580.3k tokens
936 symbols
1 requests
Download .txt
Showing preview only (2,318K chars total). Download the full file or copy to clipboard to get everything.
Repository: Choices-js/Choices
Branch: main
Commit: 59feffe87448
Files: 199
Total size: 2.2 MB

Directory structure:
gitextract_040cemen/

├── .browserslistrc
├── .codebeatignore
├── .codecov.yml
├── .editorconfig
├── .eslintrc.json
├── .git-blame-ignore-revs
├── .gitattributes
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   ├── PULL_REQUEST_TEMPLATE.md
│   ├── actions-scripts/
│   │   └── polyfills-sync.cjs
│   ├── release-drafter.yml
│   └── workflows/
│       ├── browsers.yml
│       ├── bundlesize.yml
│       ├── deploy-pages.yml
│       ├── deployment.yml
│       ├── lint.yml
│       ├── polyfills-sync.yml
│       ├── release-drafter.yml
│       └── unit-tests.yml
├── .gitignore
├── .nvmrc
├── .prettierrc.json
├── .stylelintrc.json
├── .vscode/
│   ├── extensions.json
│   ├── launch.json
│   ├── settings.json
│   └── tasks.json
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── babel.config.json
├── jsconfig.json
├── package.json
├── playwright.config.ts
├── public/
│   ├── assets/
│   │   ├── images/
│   │   │   ├── browserconfig.xml
│   │   │   └── manifest.json
│   │   ├── scripts/
│   │   │   ├── choices.js
│   │   │   ├── choices.mjs
│   │   │   ├── choices.search-basic.js
│   │   │   ├── choices.search-basic.mjs
│   │   │   ├── choices.search-kmp.js
│   │   │   ├── choices.search-kmp.mjs
│   │   │   ├── choices.search-prefix.js
│   │   │   └── choices.search-prefix.mjs
│   │   └── styles/
│   │       ├── base.css
│   │       └── choices.css
│   ├── index.html
│   ├── robots.txt
│   ├── test/
│   │   ├── data.json
│   │   ├── disabled-data.json
│   │   ├── select-multiple/
│   │   │   ├── index-performance.html
│   │   │   └── index.html
│   │   ├── select-one/
│   │   │   └── index.html
│   │   └── text/
│   │       └── index.html
│   └── types/
│       └── src/
│           ├── index.d.ts
│           └── scripts/
│               ├── actions/
│               │   ├── choices.d.ts
│               │   ├── groups.d.ts
│               │   └── items.d.ts
│               ├── choices.d.ts
│               ├── components/
│               │   ├── container.d.ts
│               │   ├── dropdown.d.ts
│               │   ├── index.d.ts
│               │   ├── input.d.ts
│               │   ├── list.d.ts
│               │   ├── wrapped-element.d.ts
│               │   ├── wrapped-input.d.ts
│               │   └── wrapped-select.d.ts
│               ├── constants.d.ts
│               ├── defaults.d.ts
│               ├── interfaces/
│               │   ├── action-type.d.ts
│               │   ├── build-flags.d.ts
│               │   ├── choice-full.d.ts
│               │   ├── class-names.d.ts
│               │   ├── event-choice.d.ts
│               │   ├── event-type.d.ts
│               │   ├── group-full.d.ts
│               │   ├── index.d.ts
│               │   ├── input-choice.d.ts
│               │   ├── input-group.d.ts
│               │   ├── item.d.ts
│               │   ├── keycode-map.d.ts
│               │   ├── options.d.ts
│               │   ├── passed-element-type.d.ts
│               │   ├── passed-element.d.ts
│               │   ├── position-options-type.d.ts
│               │   ├── search.d.ts
│               │   ├── state.d.ts
│               │   ├── store.d.ts
│               │   ├── string-pre-escaped.d.ts
│               │   ├── string-untrusted.d.ts
│               │   ├── templates.d.ts
│               │   └── types.d.ts
│               ├── lib/
│               │   ├── choice-input.d.ts
│               │   ├── html-guard-statements.d.ts
│               │   └── utils.d.ts
│               ├── reducers/
│               │   ├── choices.d.ts
│               │   ├── groups.d.ts
│               │   └── items.d.ts
│               ├── search/
│               │   ├── fuse.d.ts
│               │   ├── index.d.ts
│               │   ├── kmp.d.ts
│               │   └── prefix-filter.d.ts
│               ├── store/
│               │   └── store.d.ts
│               └── templates.d.ts
├── scripts/
│   ├── lint-staged.config.js
│   ├── rollup.config.mjs
│   └── server.mjs
├── src/
│   ├── entry.js
│   ├── index.ts
│   ├── scripts/
│   │   ├── actions/
│   │   │   ├── choices.ts
│   │   │   ├── groups.ts
│   │   │   └── items.ts
│   │   ├── choices.ts
│   │   ├── components/
│   │   │   ├── container.ts
│   │   │   ├── dropdown.ts
│   │   │   ├── index.ts
│   │   │   ├── input.ts
│   │   │   ├── list.ts
│   │   │   ├── wrapped-element.ts
│   │   │   ├── wrapped-input.ts
│   │   │   └── wrapped-select.ts
│   │   ├── constants.ts
│   │   ├── defaults.ts
│   │   ├── interfaces/
│   │   │   ├── action-type.ts
│   │   │   ├── build-flags.ts
│   │   │   ├── choice-full.ts
│   │   │   ├── class-names.ts
│   │   │   ├── event-choice.ts
│   │   │   ├── event-type.ts
│   │   │   ├── group-full.ts
│   │   │   ├── index.ts
│   │   │   ├── input-choice.ts
│   │   │   ├── input-group.ts
│   │   │   ├── item.ts
│   │   │   ├── keycode-map.ts
│   │   │   ├── options.ts
│   │   │   ├── passed-element-type.ts
│   │   │   ├── passed-element.ts
│   │   │   ├── position-options-type.ts
│   │   │   ├── search.ts
│   │   │   ├── state.ts
│   │   │   ├── store.ts
│   │   │   ├── string-pre-escaped.ts
│   │   │   ├── string-untrusted.ts
│   │   │   ├── templates.ts
│   │   │   └── types.ts
│   │   ├── lib/
│   │   │   ├── choice-input.ts
│   │   │   ├── html-guard-statements.ts
│   │   │   └── utils.ts
│   │   ├── reducers/
│   │   │   ├── choices.ts
│   │   │   ├── groups.ts
│   │   │   └── items.ts
│   │   ├── search/
│   │   │   ├── fuse.ts
│   │   │   ├── index.ts
│   │   │   ├── kmp.ts
│   │   │   └── prefix-filter.ts
│   │   ├── store/
│   │   │   └── store.ts
│   │   └── templates.ts
│   ├── styles/
│   │   ├── base.scss
│   │   └── choices.scss
│   └── tsconfig.json
├── test/
│   ├── scripts/
│   │   ├── actions/
│   │   │   ├── choices.test.ts
│   │   │   ├── groups.test.ts
│   │   │   └── items.test.ts
│   │   ├── choices.test.ts
│   │   ├── components/
│   │   │   ├── container.test.ts
│   │   │   ├── dropdown.test.ts
│   │   │   ├── input.test.ts
│   │   │   ├── list.test.ts
│   │   │   ├── wrapped-element.test.ts
│   │   │   ├── wrapped-input.test.ts
│   │   │   └── wrapped-select.test.ts
│   │   ├── lib/
│   │   │   └── utils.test.ts
│   │   ├── reducers/
│   │   │   ├── choices.test.ts
│   │   │   ├── groups.test.ts
│   │   │   └── items.test.ts
│   │   ├── search/
│   │   │   └── index.test.ts
│   │   ├── store/
│   │   │   └── store.test.ts
│   │   └── templates.test.ts
│   ├── setupFiles/
│   │   └── window-matchMedia.ts
│   └── tsconfig.json
├── test-e2e/
│   ├── bundle-test.ts
│   ├── hars/
│   │   ├── 0432285dab6a62ab5e6efaf4cb1272720e0c3f1b.json
│   │   ├── 69c6136c671f1173ee6d6596d125e821dea44a4f.json
│   │   ├── a8763b95c9f6c98156a9100e8bed82cb17b93ecd.json
│   │   └── discogs.har
│   ├── select-test-suit.ts
│   ├── test-suit.ts
│   ├── tests/
│   │   ├── demo-page.spec.ts
│   │   ├── select-multiple-performance.spec.ts
│   │   ├── select-multiple.spec.ts
│   │   ├── select-one.spec.ts
│   │   └── text.spec.ts
│   ├── text-test-suit.ts
│   └── tsconfig.json
└── vitest.config.ts

================================================
FILE CONTENTS
================================================

================================================
FILE: .browserslistrc
================================================
> 1%


================================================
FILE: .codebeatignore
================================================
public/**
webpack.config.*.js
*.js

================================================
FILE: .codecov.yml
================================================
coverage:
  parsers:
    javascript:
      enable_partials: yes


================================================
FILE: .editorconfig
================================================

root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true

================================================
FILE: .eslintrc.json
================================================
{
  "parser": "@typescript-eslint/parser",
  "plugins": ["@typescript-eslint", "prettier", "sort-class-members"],
  "extends": [
    "airbnb-base",
    "airbnb-typescript",
    "plugin:prettier/recommended",
    "plugin:compat/recommended",
    "plugin:@typescript-eslint/recommended"
  ],
  "env": {
    "es6": true,
    "node": true,
    "browser": true
  },
  "parserOptions": {
    "sourceType": "module",
    "project": true
  },
  "rules": {
    "no-param-reassign": ["error", { "props": false }],
    "@typescript-eslint/explicit-function-return-type": "error",
    "import/no-named-as-default": "off",
    "import/prefer-default-export": "off",
    "import/no-extraneous-dependencies": [
      "error",
      {
        "devDependencies": true
      }
    ],
    "no-console": [
      "warn",
      {
        "allow": ["warn", "error"]
      }
    ],
    "no-plusplus": "off",
    "no-unused-expressions": "off",
    "no-underscore-dangle": "off",
    "consistent-return": "off",
    "import/no-useless-path-segments": "warn",
    "prefer-destructuring": [
      "warn",
      {
        "array": false,
        "object": true
      }
    ],
    "curly": ["error", "all"],
    "newline-before-return": "error",
    "sort-class-members/sort-class-members": [
      2,
      {
        "order": [
          "[static-properties]",
          "[static-methods]",
          "[properties]",
          "[conventional-private-properties]",
          "constructor",
          "[methods]",
          "[conventional-private-methods]"
        ],
        "accessorPairPositioning": "getThenSet"
      }
    ],
    "lines-between-class-members": "off",
    "@typescript-eslint/no-floating-promises": "error",
    "@typescript-eslint/no-namespace": "off",
    "react/jsx-filename-extension": [0],
    "import/extensions": [
      "error",
      "ignorePackages",
      {
        "js": "never",
        "mjs": "never",
        "jsx": "never",
        "ts": "never",
        "tsx": "never"
      }
    ]
  },
  "overrides": [
    {
      "files": ["*.test.ts", "*.spec.ts"],
      "rules": {
        "no-await-in-loop": "off",
        "@typescript-eslint/explicit-function-return-type": "off",
        "no-restricted-syntax": "off",
        "compat/compat": "off",
        "no-new": "off",
        "@typescript-eslint/no-empty-function": "off",
        "@typescript-eslint/no-explicit-any": "off",
        "@typescript-eslint/no-non-null-assertion": "off",
        "@typescript-eslint/no-unused-expressions": "off",
        "@typescript-eslint/naming-convention": [
          "error",
          {
            "selector": "default",
            "format": ["camelCase", "PascalCase", "UPPER_CASE"],
            "leadingUnderscore": "allow"
          }
        ]
      }
    }
  ],
  "settings": {
    "polyfills": [
      "Array.from",
      "Array.prototype.find",
      "Array.prototype.includes",
      "Symbol",
      "Symbol.iterator",
      "DOMTokenList",
      "Object.assign",
      "CustomEvent",
      "Element.prototype.classList",
      "Element.prototype.closest",
      "Element.prototype.dataset",
      "Element.prototype.replaceChildren"
    ],
    "import/resolver": {
      "node": {
        "extensions": [".js", ".ts"]
      }
    }
  },
  "ignorePatterns": ["node_modules/*", "public/*"]
}


================================================
FILE: .git-blame-ignore-revs
================================================
# byte shaving (hoist semi-commonly variables, remove some low level low-usage functions)
157a47a44a01e3ce4b54ad211b1756ff59985bef
5bee41d7ff08e05442b232e3e552dcb6c703568d
e9382df0ae63edfc7540f82f74cf969342c759c0

# prettier config change
00433d200d8cccc8b544fbc8f05d5e96bf8ccff7

# misc linting cleanup
00009d2effa8b41a6ce27ef8b06a35a04215aea6
62b786d1f13d0934137a62909d3a37db0a3e927e
5ad61841143508c9f91f0edd57f81f8b11066e0a
84a61cad1ddab1e851c98efa619a2cd35af434c1
33f573247e8badc9ee10defe326f13985342e09b
b0199538a82d49de429f35546e412d14fc8bfeb9

================================================
FILE: .gitattributes
================================================
## GITATTRIBUTES FOR WEB PROJECTS
#
# These settings are for any web project.
#
# Details per file setting:
#   text    These files should be normalized (i.e. convert CRLF to LF).
#   binary  These files are binary and should be left untouched.
#
# Note that binary is a macro for -text -diff.
######################################################################

# Auto detect
##   Handle line endings automatically for files detected as
##   text and leave all files detected as binary untouched.
##   This will handle all files NOT defined below.
*                 text eol=lf

# Source code
*.css             text eol=lf
*.html            text diff=html eol=lf
*.js              text eol=lf
*.json            text eol=lf
*.scss            text diff=css eol=lf
*.ts              text eol=lf

# Documentation
*.md              text eol=lf
*.txt             text eol=lf
AUTHORS           text eol=lf
CHANGELOG         text eol=lf
CHANGES           text eol=lf
CONTRIBUTING      text eol=lf
COPYING           text eol=lf
copyright         text eol=lf
*COPYRIGHT*       text eol=lf
INSTALL           text eol=lf
license           text eol=lf
LICENSE           text eol=lf
NEWS              text eol=lf
readme            text eol=lf
*README*          text eol=lf
TODO              text eol=lf

# Linters
.eslintrc         text eol=lf
.stylelintrc      text eol=lf

# Configs
.babelrc          text eol=lf
.browserslistrc   text eol=lf
.editorconfig     text eol=lf
.env              text eol=lf
.gitattributes    text eol=lf
.gitconfig        text eol=lf
package-lock.json text -diff eol=lf
*.npmignore       text eol=lf
*.yaml            text eol=lf
*.yml             text eol=lf
browserslist      text eol=lf

# Graphics
# SVG treated as an asset (binary) by default.
*.svg             text eol=lf
*.png             binary


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Using https://jsfiddle.net/ to create a minimal reproducible example.

Otherwise

Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Choices version and bundle**
- Version: [e.g. v11.0.0 choices.min.js]

**Desktop (please complete the following information):**
 - OS: [e.g. iOS]
 - Browser [e.g. chrome, safari]
 - Version [e.g. 22]

**Smartphone (please complete the following information):**
 - Device: [e.g. iPhone6]
 - OS: [e.g. iOS8.1]
 - Browser [e.g. stock browser, safari]
 - Version [e.g. 22]

**Additional context**
Add any other context about the problem here.


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: feature request
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.


================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
## Description

<!--- Describe your changes in detail -->
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->

## Screenshots (if appropriate)

## Types of changes

<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->

- [ ] Chore (tooling change or documentation change)
- [ ] Refactor (non-breaking change which maintains existing functionality)
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)

## Checklist

<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->

- [ ] My code follows the code style of this project.
- [ ] I have added new tests for the bug I fixed/the new feature I added.
- [ ] I have modified existing tests for the bug I fixed/the new feature I added.
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.


================================================
FILE: .github/actions-scripts/polyfills-sync.cjs
================================================
const { readFileSync } = require('fs');
const path = require('path');
const assert = require('assert');

const readme = readFileSync(path.resolve(__dirname, '../../README.md'), 'utf8');

const polyfillsFromDocs = /^```polyfills\s*\n([^`]+)\n^```/m
  .exec(readme)[1]
  .split('\n')
  .map(v => v.trim())
  .sort();
// @ts-ignore
const polyfillsFromSettings = require('../../.eslintrc.json').settings.polyfills.sort();
assert.deepStrictEqual(polyfillsFromDocs, polyfillsFromSettings);


================================================
FILE: .github/release-drafter.yml
================================================
name-template: 'Draft (next release)'
tag-template: 'v$NEXT_PATCH_VERSION'
sort-direction: descending
exclude-labels:
  - 'skip-changelog'
  - 'release'
categories:
  - title: '🚨 Breaking changes'
    labels:
      - 'breaking change'
  - title: '🚀 Features'
    labels:
      - 'feature'
      - 'enhancement'
  - title: '🐛 Bug Fixes'
    labels:
      - 'bugfix'
  - title: '🔧 Maintenance'
    labels:
      - 'chore'
      - 'housekeeping'
      - 'refactor'
      - 'documentation'
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
template: |
  # Changes
  $CHANGES
  # Contributors
  $CONTRIBUTORS


================================================
FILE: .github/workflows/browsers.yml
================================================
name: End-to-end tests (playwright)
on:
  push:
    branches: [ main ]
    paths:
      - 'src/**'
      - 'test-e2e/**'
      - 'package-lock.json'
      - '.browserslistrc'
      - 'babel.config.json'
      - 'public/index.html'
      - 'public/**/index.html'
      - '.github/workflows/browsers.yml'
      - 'playwright.config.ts'
  pull_request:
    paths:
      - 'src/**'
      - 'test-e2e/**'
      - 'package-lock.json'
      - '.browserslistrc'
      - 'babel.config.json'
      - 'public/index.html'
      - 'public/**/index.html'
      - '.github/workflows/browsers.yml'
      - 'playwright.config.ts'
jobs:
  test-e2e-playwright:
    timeout-minutes: 60
    strategy:
      fail-fast: false
      matrix:
        os: [windows-latest, macos-latest, ubuntu-latest]
        browser: [chromium, firefox, webkit]
        exclude:
          - os: windows-latest
            browser: webkit
          - os: windows-latest
            browser: firefox
          - os: macos-latest
            browser: firefox
    runs-on: ${{ matrix.os }}
    steps:
    - uses: actions/checkout@v4
      with:
        fetch-depth: 1

    - uses: actions/setup-node@v4
      with:
        node-version: 24
        cache: 'npm'

    - name: Install dependencies
      run: npm ci --no-audit
    - name: Install Playwright Browsers
      run: npx playwright install --with-deps
    - run: npx playwright install-deps

    - name: Run Playwright tests
      run: npx playwright test --project=${{ matrix.browser }}

    - uses: actions/upload-artifact@v4
      name: Upload screenshots to GitHub Actions Artifacts
      if: failure()
      with:
        name: screenshot-${{ matrix.os }}-${{ matrix.browser }}
        path: test-results/**/*.png

    - uses: actions/upload-artifact@v4
      name: Upload blob report to GitHub Actions Artifacts
      if: ${{ !cancelled() }}
      with:
        name: playwright-report-${{ matrix.os }}-${{ matrix.browser }}
        path: playwright-report/
        retention-days: 30

================================================
FILE: .github/workflows/bundlesize.yml
================================================
name: Bundle size checks

on:
  push:
    branches: [ main ]
    paths:
      - '.github/workflows/bundlesize.yml'
      - 'src/scripts/**'
      - 'src/styles/**'
      - 'package-lock.json'
      - '.browserslistrc'
  pull_request:
    paths:
      - '.github/workflows/bundlesize.yml'
      - 'src/scripts/**'
      - 'src/styles/**'
      - 'package-lock.json'
      - '.browserslistrc'

jobs:
  measure:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 1

      - uses: actions/setup-node@v4
        with:
          node-version: 24
          cache: 'npm'

      - name: Install dependencies
        run: npm ci --no-audit

      - run: npm run build

      # we don't need to build here, as even minized assets expected to be commited

      - run: npm run bundlesize
        env:
          # token has expired, don't block the test
          #CI: true
          #BUNDLESIZE_GITHUB_TOKEN: ${{secrets.BUNDLESIZE_GITHUB_TOKEN}}
          CI_REPO_NAME: ${{ github.event.repository.name }}
          CI_REPO_OWNER: ${{ github.event.organization.login }}
          CI_COMMIT_SHA: ${{ github.event.after }}
          GIT_COMMIT: ${{ github.event.after }}
          CI_BRANCH: ${{ github.head_ref }}
          FORCE_COLOR: 2


================================================
FILE: .github/workflows/deploy-pages.yml
================================================
name: Deploy Pages

on:
  release:
    types: [published]
  workflow_dispatch:

jobs:
  deploy-gh-pages:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 1
      - uses: actions/setup-node@v4
        with:
          node-version: 24
      - name: Build
        run: |
          npm ci
          npm run build
          rm -rf public/test
      - name: Deploy
        uses: peaceiris/actions-gh-pages@v4
        with:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          PUBLISH_BRANCH: gh-pages
          PUBLISH_DIR: ./public


================================================
FILE: .github/workflows/deployment.yml
================================================
name: Publish to npm

on:
  release:
    types: [published]

permissions:
  id-token: write  # Required for OIDC
  contents: read

jobs:
  publish-npm:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 1
      - uses: actions/setup-node@v4
        with:
          node-version: 24
      - run: npm ci
      - run: npm publish --provenance --access public


================================================
FILE: .github/workflows/lint.yml
================================================
name: Code linting

on:
  push:
    branches: [ main ]
    paths:
      - '.github/workflows/lint.yml'
      - 'src/scripts/**'
      - 'src/*.ts'
      - 'src/styles/**'
      - 'test/**'
      - 'test-e2e/**'
      - 'package-lock.json'
      - '.browserslistrc'
      - '.eslintrc.json'
      - '.editorconfig'
      - '.prettierrc.json'
      - '.stylelintrc.json'
  pull_request:
    paths:
      - '.github/workflows/lint.yml'
      - 'src/scripts/**'
      - 'src/*.ts'
      - 'src/styles/**'
      - 'test/**'
      - 'test-e2e/**'
      - 'package-lock.json'
      - '.browserslistrc'
      - '.eslintrc.json'
      - '.editorconfig'
      - '.prettierrc.json'
      - '.stylelintrc.json'

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 1

      - uses: actions/setup-node@v4
        with:
          node-version: 24
          cache: 'npm'

      - name: Install dependencies
        run: npm ci --no-audit
      - name: run eslint
        run: npm run lint:js

      ## Can't use same eslint config for TypeScript and JavaScript
      ## TypeScript rules cause rule definition not found errors
      ## Can be re-enabled if this is resolved: https://github.com/eslint/eslint/issues/14851
      # - name: Lint JS bundle
      #   run: |
      #     npm run js:build
      #     npx eslint --no-ignore ./public/assets/scripts/*.js

      - name: run stylelint
        run: npm run lint:scss

================================================
FILE: .github/workflows/polyfills-sync.yml
================================================
name: Polyfills documentation

on:
  pull_request:
    paths:
      - 'README.md'
      - '.browserslistrc'
      - '.eslintrc.json'

jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 1

      - uses: actions/setup-node@v4
        with:
          node-version: 24

      - name: Check Polyfills documentation and settings sync
        run: node .github/actions-scripts/polyfills-sync.cjs


================================================
FILE: .github/workflows/release-drafter.yml
================================================
name: Release drafter

on:
  push:
    branches: [ main ]

jobs:
  update-draft-release:
    runs-on: ubuntu-latest
    steps:
      - uses: release-drafter/release-drafter@v5
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


================================================
FILE: .github/workflows/unit-tests.yml
================================================
name: Unit tests

on:
  push:
    branches: [ main ]
    paths:
      - '.github/workflows/unit-tests.yml'
      - 'src/scripts/**'
      - 'src/*.ts'
      - 'test/**'
      - 'package-lock.json'
      - '.browserslistrc'
      - 'babel.config.json'
      - 'vitest.config.ts'
  pull_request:
    paths:
      - '.github/workflows/unit-tests.yml'
      - 'src/scripts/**'
      - 'src/*.ts'
      - 'test/**'
      - 'package-lock.json'
      - '.browserslistrc'
      - 'babel.config.json'
      - 'vitest.config.ts'

jobs:
  test-unit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 1

      - uses: actions/setup-node@v4
        with:
          node-version: 24
          cache: 'npm'

      - name: Install dependencies
        run: npm ci --no-audit

      - run: npm run build

      - run: npm run test:unit:coverage
        env:
          FORCE_COLOR: 2

      - name: Upload coverage to Codecov
        run: bash <(curl -s https://codecov.io/bash)
          -f ./coverage/lcov.info
          -B ${{ github.head_ref }}
          -C ${{ github.sha }}
          -Z || echo 'Codecov upload failed'
        env:
          CI: true
          GITLAB_CI: true # pretend we are GitLab CI, while Codecov adding support for Github Actions
          CODECOV_ENV: github-action
          CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}}


================================================
FILE: .gitignore
================================================
node_modules
npm-debug.log
.DS_Store
.idea
.rollup.cache
tsconfig.tsbuildinfo
.npmrc
.run

# Test
tests/reports
tests/results
.nyc_output
coverage
/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/


================================================
FILE: .nvmrc
================================================
v22.17.0

================================================
FILE: .prettierrc.json
================================================
{
  "printWidth": 120,
  "singleQuote": true,
  "trailingComma": "all",
  "endOfLine": "lf",
  "overrides": [
    {
      "files": ["*.svg"],
      "options": {
        "parser": "html",
        "htmlWhitespaceSensitivity": "ignore"
      }
    },
    {
      "files": ["public/*.html"],
      "options": {
        "trailingComma": "es5"
      }
    }
  ]
}


================================================
FILE: .stylelintrc.json
================================================
{
  "extends": "stylelint-config-standard-scss",
  "rules": {
    "media-feature-range-notation": null,
    "declaration-block-no-redundant-longhand-properties": null
  }
}

================================================
FILE: .vscode/extensions.json
================================================
{
  // See http://go.microsoft.com/fwlink/?LinkId=827846
  // for the documentation about the extensions.json format
  "recommendations": [
    // we enforce ESLint rules, so, recommend extension
    "dbaeumer.vscode-eslint",
    // we use prettier, so, recommend extension
    "esbenp.prettier-vscode",
    // we are on GitHub, so, recommend extension
    "github.vscode-pull-request-github",
    // needed for our configured debug configuration with Chrome
    "msjsdiag.debugger-for-chrome"
  ]
}


================================================
FILE: .vscode/launch.json
================================================
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "chrome",
      "request": "launch",
      "name": "Launch Chrome",
      "preLaunchTask": "buildAndWatch",
      "url": "http://localhost:3001",
      "webRoot": "${workspaceFolder}",
      "sourceMapPathOverrides": {
        "webpack://Choices/*": "${workspaceFolder}/*"
      }
    },
  ]
}


================================================
FILE: .vscode/settings.json
================================================
{
  "eslint.enable": true,
  // prevent watch task failures on lint errors
  "eslint.autoFixOnSave": true,
  // switch off default VSCode formatting rules
  "javascript.format.enable": false,
  // Javascript prettier runs via ESLint
  "prettier.disableLanguages": ["javascript"],
  "[json]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[html]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[scss]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[javascript]": {
    "editor.formatOnSave": false
  },
  "search.exclude": {
    "**/node_modules": true,
    "public/assets": true,
    "**/coverage": true
  },
  // for Windows collaborators
  "files.eol": "\n",
  "files.encoding": "utf8",
  // associations for some files this project is using
  "files.associations": {
    ".browserslistrc": "gitignore",
    ".npmrc": "ini"
  },
  // We use NPM as package manager
  "npm.packageManager": "npm",
  "npm.autoDetect": "on",
  "npm.fetchOnlinePackageInfo": true,
  "eslint.packageManager": "npm",
  "json.schemas": [
    // Prettier config
    {
      "fileMatch": [".prettierrc.json"],
      "url": "http://json.schemastore.org/prettierrc"
    }
  ],
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  },
  "stylelint.validate": [
    "css",
    "less",
    "postcss",
    "scss"
  ]
}


================================================
FILE: .vscode/tasks.json
================================================
{
  // See https://go.microsoft.com/fwlink/?LinkId=733558
  // for the documentation about the tasks.json format
  "version": "2.0.0",
  "tasks": [
    {
      "type": "npm",
      "label": "buildAndWatch",
      "script": "js:watch",
      "group": {
        "kind": "build",
        "isDefault": true
      },
      "isBackground": true,
      "presentation": {
        "echo": true,
        "reveal": "always",
        "focus": false,
        "panel": "dedicated",
        "showReuseMessage": true,
        "clear": false
      },
      "problemMatcher": [
        "$eslint-stylish",
        {
          "owner": "webpack",
          "fileLocation": "absolute",
          "pattern": [
            {
              "regexp": "^Module build failed \\(from (\\.+)\\)",
              "file": 1,
              "line": 2,
              "column": 3
            },
            {
              "regexp": "\\s*TS\\d+:\\s*(.*)",
              "message": 1
            }
          ],
          "severity": "error",
          "source": "webpack",
          "background": {
            "activeOnStart": true,
            "beginsPattern": "^Listening at",
            "endsPattern": "Compiled successfully\\."
          }
        }
      ]
    },
    {
      "type": "npm",
      "script": "css:build",
      "group": "build",
      "problemMatcher": ["$node-sass"]
    },
    {
      "type": "npm",
      "script": "lint",
      "problemMatcher": ["$eslint-stylish"]
    },
    {
      "type": "npm",
      "script": "build",
      "group": "build"
    },
    {
      "type": "npm",
      "script": "test",
      "group": "test"
    },
    {
      "type": "npm",
      "script": "test:e2e",
      "group": "test"
    },
    {
      "type": "npm",
      "script": "test:unit",
      "group": "test"
    },
  ]
}


================================================
FILE: CHANGELOG.md
================================================
# Changelog

## [11.2.0] (2026-01-05)

### Features
- Add `searchRenderSelectedChoices` configuration option to control whether selected choices appear in search results for select-multiple inputs. Defaults to `true` (backward compatible behavior). Set to `false` to hide selected choices from search results.
- Add support for `required` html attribute [#1332](https://github.com/Choices-js/Choices/pull/1332)
   - Note; This feature requires updating any css targeting the `.choices [hidden]` selector
- Improve UX on the select dropdown [#1361](https://github.com/Choices-js/Choices/pull/1361)
- Add `searchDisabledChoices` configuration option to allow disabled choices to appear in search results [#1357](https://github.com/Choices-js/Choices/pull/1357)
- Add additional SCSS variables [#1304](https://github.com/Choices-js/Choices/pull/1304)
- Add CSS custom properties support (+ dark mode for the intro page) (#1335](https://github.com/Choices-js/Choices/pull/1335)
- Soften constraints on remove buttons [#1338](https://github.com/Choices-js/Choices/pull/1338)

### Bugfixes
- Fix data-label-description from source html was not treated as trusted [#1365](https://github.com/Choices-js/Choices/pull/1365)
- Fix kmp search not returning results as expected [#1364](https://github.com/Choices-js/Choices/pull/1364)
- Fix selected choice was not reliably highlighted when opening the dropdown [#1339](https://github.com/Choices-js/Choices/pull/1339)
- Define `[aria-selected]` for selectable choices per WAI-ARIA 1.2 spec, and avoid triple state with aria-selected [#1330](https://github.com/Choices-js/Choices/pull/1330)
- Fix `appendGroupInSearch` option was non-functional [#1324](https://github.com/Choices-js/Choices/pull/1324)
- When resolving the remove item/label/icon, add a 3rd argument item argument. Update default remove item label to use this (Fixes #1296) [#1323](https://github.com/Choices-js/Choices/pull/1323)
- Fix `searchResultLimit` could not be set to `-1` when `renderChoiceLimit` was set [#1322](https://github.com/Choices-js/Choices/pull/1322)
- Fix dropdown would stick closed when a search loses focus [#1308](https://github.com/Choices-js/Choices/pull/1308)
- Fix `searchEnabled` being disabled for `select-multiple` did not work [#1366](https://github.com/Choices-js/Choices/pull/1366)

### Chore
- Update callback argument documentation
- Update development dependencies to fix npm install warning

## [11.1.0] (2025-03-14)

### Features
- Support `<option>` label attribute [#1289](https://github.com/Choices-js/Choices/pull/1289)
- Add KMP search algorithm (gated by build flag) [#1229](https://github.com/Choices-js/Choices/issue/1229) [#1277](https://github.com/Choices-js/Choices/pull/1277)

### Bug Fixes
- Remove `role="textbox"` from search input, per a11y practices. [#941](https://github.com/Choices-js/Choices/issues/941) @mlinnetz ([#1285](https://github.com/Choices-js/Choices/issues/1285))

## [11.0.6] (2025-02-27)

### Breaking changes
- Changes to `setChoices` & `clearChoices` adjust how the selection and new choices combine when using `replaceChoices: true` is used to better match v10 and v11.0.3 behavior.
  - To remove duplication, consider `duplicateItemsAllowed: false` to be set, or use the new 6th argument `replaceItems:true`

### Bug Fixes
- Fix `setChoices` & `clearChoices` related regressions @Xon ([#1278](https://github.com/Choices-js/Choices/issues/1278])) [#1283](https://github.com/Choices-js/Choices/issues/1283)
- Revert "Do not preventDefault on item to support dragging" [#1266](https://github.com/Choices-js/Choices/issues/1266) @Xon ([#1282](https://github.com/Choices-js/Choices/issues/1282))

### Chore
- Add e2e test for dropdown behavior on item mouse down/click
- Add e2e test for serveral `setChoices`/`clearChoices` actions

## [11.0.5] (2025-02-26)

### Bug Fixes
- Fix regression when calling setChoices [#1278](https://github.com/Choices-js/Choices/issues/1278)

## [11.0.4] (2025-02-23)

### Features
- Do not preventDefault on item to support dragging [#417](https://github.com/Choices-js/Choices/issues/417) [#1094](https://github.com/Choices-js/Choices/issues/1094) [#920](https://github.com/Choices-js/Choices/issues/920)

### Bug Fixes (from 11.0.0)
- Fix performance regression when calling setChoices [#1275](https://github.com/Choices-js/Choices/issues/1275)
* Fix `renderSelectedChoices` option when all choices are selected [#1274](https://github.com/Choices-js/Choices/issues/1274)
* Fix v11 regression for disabled placeholder option handling [#1203](https://github.com/Choices-js/Choices/issues/1203)
* Fix v11 regression where `clearChoices` (and `setChoices` with `replaceChoices:true`) did not remove selected items when preserving placeholders [#1261](https://github.com/Choices-js/Choices/issues/1261)
* Fix v11 regression where `duplicateItemsAllowed` option did not work with `select-one`/`select-multiple` [#1271](https://github.com/Choices-js/Choices/issues/1271)
* Fix: Reached maximum item limit notice is not cleared after removing selections [#1249](https://github.com/Choices-js/Choices/issues/1249)
* Fix: Disabled options are not visible [#1257](https://github.com/Choices-js/Choices/issues/1257) [#1269](https://github.com/Choices-js/Choices/issues/1257)
* Fix: Clear button reverses items order [#1251](https://github.com/Choices-js/Choices/issues/1251)
* Fix `tab` => direction keys handling with disabled search [#1260](https://github.com/Choices-js/Choices/issues/1260)
* Improve cjs compatibility by removing pinned "module" type in package.json [#1250](https://github.com/Choices-js/Choices/issues/1250)

## [11.0.3] (2024-12-22)

### Bug Fixes (from 11.0.0)
* Fix input text - method setValue didn't work [#1207](https://github.com/Choices-js/Choices/issues/1207)
* Fix `tab` and `esc` keys handling [#1234](https://github.com/Choices-js/Choices/issues/1234) [#1209](https://github.com/Choices-js/Choices/issues/1209)
* Fix Notice for max item limit is removed permanently if you keep typing [#1201](https://github.com/Choices-js/Choices/issues/1201)
* Fix search was not stopped when leaving focus with esc key [#1240](https://github.com/Choices-js/Choices/issues/1240)
* Fix single-select mode disabling search when `tab` => arrow keys are pressed [#1230](https://github.com/Choices-js/Choices/issues/1230)
* Fix HTML comments were copied from backing `<option>` and were rendered as text [#1231](https://github.com/Choices-js/Choices/issues/1231)

## [11.0.2] (2024-09-05)

### Features (from 11.0.0)
* Pass `getClassNames` as the 3rd argument to `callbackOnCreateTemplates` callback
* `duplicateItemsAllowed` option is now respected by `setChoices()` method [#855](https://github.com/Choices-js/Choices/issues/855)

### Bug Fixes (from 11.0.0)
* Fix choice disable state wasn't considered when showing the "no choices to choose from" notice
* Fix regression where webpack doesn't permit importing scss/css @tagliala [#1193](https://github.com/Choices-js/Choices/issues/1193)
* Fix regression "no choices to choose from"/"no results found" notice did not reliably trigger. [#1185](https://github.com/Choices-js/Choices/issues/1185) [#1191](https://github.com/Choices-js/Choices/issues/1191)
* Fix regression of `UnhighlightItem` event not firing [#1173](https://github.com/Choices-js/Choices/issues/1173)
* Fix `clearChoices()` would remove items, and clear the search flag.
* Fixes for opt-group handling/rendering
* Fix `removeChoice()` did not properly remove a choice which was part of a group

### Chore
* Add e2e tests for "no choices" behavior to match v10

## [11.0.1] (2024-08-30)

### Bug Fixes (from 11.0.0)
* Fix the rendered item list was not cleared when `clearStore` was called. This impacted the on-form-reset and `refresh` features.

### Chore
* Add e2e test for 'form reset' and 'on paste & search'.
* Cleanup adding classes to generated elements.

## [11.0.0] (2024-08-28)

### ⚠ BREAKING CHANGES
* Update polyfills to include `Element.prototype.replaceChildren`
* Number of internal APIs have changed

### Bug Fixes (from 10.2.0)
* Reduce work done for `unhighlightAll` during on-click handler (batching in v11.0.0-rc8 would also have helped) [#522](https://github.com/Choices-js/Choices/issues/522) [#599](https://github.com/Choices-js/Choices/issues/599)
* Improve performance when rendering very large number of items and choices. Stuttering when stopping searching or selecting an item still happens depending on device and number of choices.

## [11.0.0-rc8] (2024-08-23)

### ⚠ BREAKING CHANGES
* Trigger a search event (with empty value and 0 resultCount) when search stops

### Features
* `searchResultLimit` can be set to `-1` for no limit of search results to display.

### Bug Fixes (from 10.2.0)
* Fix edge case where aria-label could be added twice
* Fix the page scrolls when you press 'space' on a single select input #1103
* Update typescript definition for `removeActiveItems` to explicitly mark `excludedId` as optional #1116

### Chore
* Reduce the number of loops over choices when rendering search results, results in more compact code.
* Byte shave bundle sizes down

## [11.0.0-rc7] (2024-08-19)

### ⚠ BREAKING CHANGES
* Improve consistency of the `choice` event firing. `choice` event now occurs after the `addItem` event
* `enter` key now consistently opens/closes the dropdown instead of the behavior varying depending on backing element or internal state of the highlighted choice

### Features
* Add `closeDropdownOnSelect` option, controls how the dropdown is close after selection is made. [#636](https://github.com/Choices-js/Choices/issues/636) [#973](https://github.com/Choices-js/Choices/issues/873) [#1012](https://github.com/Choices-js/Choices/issues/1012)
* Allow choices.js to be imported on nodejs, useful for tests and also server side rendering. As windows.document is by default not defined, the default template rendering will not function. The `callbackOnCreateTemplates` callback must be used. [#861](https://github.com/Choices-js/Choices/issues/861)

### Bug Fixes (from 10.2.0)
* Improve various `[aria-*]` attribute handling for better lighthouse accessibility scores [#1169](https://github.com/Choices-js/Choices/issues/1169)
* Improve contrast on default CSS by darkening primary item selection color [#924](https://github.com/Choices-js/Choices/issues/924)

### Bug Fixes (from 11.0.0RC6)
* Fix destroy&init of `choices.js` would lost track of data from the backing `<input>`/`<select>`
* Update e2e tests

### Bug Fixes (from 11.0.0RC1)
* Fix various `select-one` bugs related to how `<select>` initializes and selected values do not match the configured `choices.js`
* Fix legacy `placeholder` attribute support for `select-one`
* Fix `data-value` attribute on choices may not be correctly rendered into html

### Chore
* Switch e2e tests from `puppeteer`/`selenium`/`cypress` to `playwright`
* Restructure end-to-end tests so html/script blocks are co-located to improve debugability
* Enable `@typescript-eslint/explicit-function-return-type` eslint rule

## [11.0.0-rc6] (2024-08-12)

### ⚠ BREAKING CHANGES
* Mutation APIs `setChoiceByValue`/`setChoices`/`setValue` now throw an error if the Choices instance was not initialized or multiple choices instances where initialized on the same element. Prevents bad internal states from triggering unexpected errors [#1129](https://github.com/Choices-js/Choices/issues/1129)

### Features
* Improve performance of search/filtering with large number of choices.

### Bug Fixes (from 10.2.0)
* Fix Choices does not accept an element from an iframe [#1057](https://github.com/Choices-js/Choices/issues/1057)
* Fix Choices was not disable in a `<fieldset disabled>` [#1132](https://github.com/Choices-js/Choices/issues/1132)
* Fix `silent` option does not silence warnings about unknown options [#1119](https://github.com/Choices-js/Choices/issues/1119)
* Fix documentation that suggests duplicateItemsAllowed works with select-multiple, when it only works for text. [#1123](https://github.com/Choices-js/Choices/issues/1123)
* Fix quadratic algorithm complexity (aka O(N^2) ) when filtering/search choices.
* Fix search results could be unexpectedly unstable, and that `fuseOptions.sortFn` was effectively ignored [#1106](https://github.com/Choices-js/Choices/issues/1106)

### Bug Fixes (from 11.0.0RC1)
* Fix possible empty `aria-label` generation on remove item button
* Fix `clearChoices()` did not remove the actual selection options

## [11.0.0-rc5] (2024-08-08)

### ⚠ BREAKING CHANGES
* Update to using Fuse.js v7.0.0
* Update choices.js package to be an ES module, and use '[subpath exports](https://nodejs.org/api/packages.html#subpath-exports)' to expose multiple versions (UMD, CJS or MTS bundles).
* Provide "fuse full" (default `choices.js`, ~20.36KB), or "fuse basic" (`choices.search-basic.js` ~19.31KB) or "prefix filter" (`choices.search-filter.js` ~15.27KB) based on how much Fuse.js is included.

### Bug Fixes (from 10.2.0)
* Fix `select-one` placeholder could ignore the non-option placeholder configuration
* Remove typescript types for tests from distribution

### Chore
* Reduce bundle size from ~24KB to ~20.36KB
* Switch bundler from `webpack` to `rollup`
* Switch test framework from `mocha` to `vitest`

### Bug Fixes (from 11.0.0RC4)
* Fix `aria-describedby` was being assigned when it shouldn't be
* Fix check to ensure search was fully enabled for multiple select mode, as this functionality is hard-coded enabled elsewhere in the code base.

## [11.0.0 RC3] (2024-08-04)

### ⚠ BREAKING CHANGES
* For `select-one` and `select-multiple`, the placeholder value is pulled from `config.placeholderValue="..."` or `<select data-placeholder="...">` before attempting to extract a placeholder from the options list. [#912](https://github.com/Choices-js/Choices/issues/912) [#567](https://github.com/Choices-js/Choices/issues/567) [#843](https://github.com/Choices-js/Choices/issues/843)

### Bug Fixes (from 10.2.0)
* Fix search did not trigger to copy&paste events [#860](https://github.com/Choices-js/Choices/issues/860) [#174](https://github.com/Choices-js/Choices/issues/174)

### Chore
* Update defaults for classnames to be arrays instead of strings

### Bug Fixes (from 11.0.0 RC1)
* Fix `noResults`/`noChoices` classes could not be set to a list of classes
* Fix failing to add an item would close the dropdown
* Fix invalid css selectors being generated for configurable css class-names with multiple css classes for an element
* Fix "Press Enter to add..." would not render if the dropdown had partially matching search results
* Fix render limit would allow `select-one` to select multiple items

## [11.0.0 RC2] (2024-08-03)

### Bug Fixes (from 10.2.0)
* Avoid pushing a search to fuse.js which is just additional whitespace to the existing search term

### Bug Fixes (from 11.0.0 RC1)
* Fix error when using backspace key after adding an item and then removing it
* Fix adding items for select boxes would not give the max item messages reliably
* Fix `destroy()`/`init()` would not load choices from the underlying `<select>` as expected
* Fix adding user provided choices for `select-one` would not remove the existing item and result in a select-one with multiple items set.

### Chore
* Remove unused code
* Use constant enum instead of repeating strings and type information
* For test html pages, prevent a failing `fetch()` from breaking the rest of the examples
* Tweak `_render()` loop to avoid duplicating has-changed checks

## [11.0.0 RC1] (2024-08-02)

### ⚠ BREAKING CHANGES

* `allowHtml` now defaults to false.
* HTML escaping of choice/item labels should no longer double escape depending on allowHTML mode.
* Templates/text functions now escape `'` characters for display.
* `addItemText`/`uniqueItemText`/`customAddItemText` are now called with the `value` argument already escaped.
* Typescript classes for input data vs internal working data have been adjusted resulting in the `Choice`/`Group`/`Item` typescript classes have been renamed, and aliases left as required.

### Features

* `config.classNames` now accept arrays to support multiple classes. [#1121](https://github.com/Choices-js/Choices/issues/1121) [#1074](https://github.com/Choices-js/Choices/issues/1074) [#907](https://github.com/Choices-js/Choices/issues/907) [#832](https://github.com/Choices-js/Choices/issues/832)
* The original option list for the select is not destroyed, and all loaded choices are serialised to HTML for better compatibility with external javascript. [#1053](https://github.com/Choices-js/Choices/issues/1053) [#1023](https://github.com/Choices-js/Choices/issues/1023)
* New `singleModeForMultiSelect` feature to treat a `select-single` as if it was a `select-multiple` with a max item count of `1`, and still auto-close the dropdown and swap the active item on selection. [#1136](https://github.com/Choices-js/Choices/issues/1136) [#904](https://github.com/Choices-js/Choices/issues/904)
* `Remove item text` can be localized.
* Allow user-created choices for selects. [#1117](https://github.com/Choices-js/Choices/issues/1117) [#1114](https://github.com/Choices-js/Choices/issues/1114)
    * User input is escaped by default. At the risk of XSS attacks this can be disabled by `allowHtmlUserInput`.
* Render options without a group even if groups are present. [#615](https://github.com/Choices-js/Choices/issues/615) [#1110](https://github.com/Choices-js/Choices/issues/1110)
* Read `data-label-class`/`data-label-description` from `<option>` HTML to drive adding a per-choice CSS label and description text when `allowHtml: false`.
* Add `removeItemButtonAlignLeft` option, to control if the remove item button is at the start or the end of the item.
* Add `removeChoice` method. Removes the choice from the `choices.js` object and any backing `<option>` HTML element
* Add `refresh` method. Reloads choices from the backing `<select>`s options.
* Improve rendering performance by batching changes.
* `escapeForTemplate` function is passed to the 2nd method of the `callbackOnCreateTemplates` callback.
* When `allowHtml` is false, default templates now render escaped html to `innerHtml` writing to `innerText`.
    * This provides consistent rendering performance as `innerText` is quirky and slower than escaped html into `innerHtml`
* Shadow DOM support [#938](https://github.com/Choices-js/Choices/pull/938)

### Bug Fixes

* Replace malicious polyfill with cdnjs. [#1161](https://github.com/Choices-js/Choices/issues/1161)
* Maintain groups in search mode. [#1152](https://github.com/Choices-js/Choices/issues/1152)
* Fix various "first press" bugs on single select dropdowns. [#1104](https://github.com/Choices-js/Choices/issues/1104)
* Fix 'esc' would close the dropdown and also apply to the container resulting in an overlay/modal unexpectedly closing. [#1039](https://github.com/Choices-js/Choices/issues/1039)
* Fix form reset would clear the choices list, but not clear the search bar. [#1023](https://github.com/Choices-js/Choices/issues/1023)
* Fix options would be disabled when choices.js was intialized on a disabled `<select>` element. [#1025](https://github.com/Choices-js/Choices/issues/1025)
* Fix a `search_term` element to appear in form submit data. [#1049](https://github.com/Choices-js/Choices/issues/1049)
* Fix 'remove item' button would trigger the change event twice due to placeholder value being used (match html single-select). [#892](https://github.com/Choices-js/Choices/issues/892)
* Fix optgroups are not preserved when Choices is destroyed [#1055](https://github.com/Choices-js/Choices/issues/1055)
* Fix placeholder config option would be ignored for select boxes which have blank entries.
* Fix `data-custom-properties` attribute did not serialize to created elements as a json blob as expected. [#840](https://github.com/Choices-js/Choices/issues/840) [#1155](https://github.com/Choices-js/Choices/issues/1155) [#543](https://github.com/Choices-js/Choices/issues/543)
* Fix multi-select did not correctly resizing when a select option is selected on choices.js initialization.
* Fix clearInput function did not clear the last search.
* Fix `addItemFilter` would allow empty strings as input to be added for items.
* Fix various issues with double escaping when displaying items/choices depending on allowHTML mode.
* Fix `aria-label` for placeholders was set to the string `null`
* Fix `searchEnable` flag was not respected for `select-multiple` [#1042](https://github.com/Choices-js/Choices/issues/1042)
* Fix poor error message when Choices is passed a string selector which fails to find the element for Choices to attach to.

### Chore
* Remove `deepMerge` dependency.


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at josh@joshuajohnson.co.uk. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]

[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/


================================================
FILE: CONTRIBUTING.md
================================================
# Contributions
In lieu of a formal styleguide, take care to maintain the existing coding style ensuring there are no linting errors. Add unit tests for any new or changed functionality. Lint and test your code using the npm scripts below:

### Minified code
For compatibility, `new` and `get` must be pure (side effect free).

### NPM tasks
| Task                      | Usage                                                        |
|---------------------------|--------------------------------------------------------------|
| `npm run start`           | Fire up local server for development                         |
| `npm run test:unit`       | Run sequence of tests once                                   |
| `npm run test:unit:watch` | Fire up test server and re-test on file change               |
| `npm run test:e2e`        | Run sequence of e2e tests (with local server)                |
| `npm run test`            | Run both unit and e2e tests                                  |
| `npm run playwright:gui`  | Run Playwright e2e tests (GUI)                               |
| `npm run playwright:cli`  | Run Playwright e2e tests (CLI)                               |
| `npm run js:build`        | Compile Choices to an uglified JavaScript file               |
| `npm run css:watch`       | Watch SCSS files for changes. On a change, run build process |
| `npm run css:build`       | Compile, minify and prefix SCSS files to CSS                 |

## Passing environmental arguments to rollup

Use `--` followed by normal rollup `--environment` arguments. The last one overrides any previous ones with the same name

An example of changing what js:watch will bind to:
```
npm run js:watch -- --environment WATCH_HOST:0.0.0.0
```

## Build flags

The following build flags are supported via environment variables:

### CHOICES_SEARCH_FUSE
**Values:**: **"full" / "basic" / "null" **
**Usage:** The level of integration with fuse. `full` is the entire fuse.js build, `basic` is fuse.js with just standard fuzzy searching. `null` is a basic prefix string search with no fuse.js
**Example**:
```
npm run js:watch -- --environment CHOICES_SEARCH_FUSE:basic
```

### CHOICES_SEARCH_KMP
**Values:**: **"1" / "0" **
**Usage:** High performance `indexOf`-like search algorithm.
**Example**:
```
npm run js:watch -- --environment CHOICES_SEARCH_KMP:1
```

### CHOICES_CAN_USE_DOM
**Values:**: **"1" / "0" **
**Usage:** Indicates if DOM methods are supported in the global namespace. Useful if importing into DOM or the e2e tests without a DOM implementation available.
**Example**:
```
npm run js:watch -- --environment CHOICES_CAN_USE_DOM:1
```

## Pull requests
When submitting a pull request that resolves a bug, feel free to use the following template:

```md
## This is the problem:

## Steps to reproduce:

## This is my solution:
```


================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2016 Josh Johnson

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
# Choices.js [![Actions Status](https://github.com/Choices-js/Choices/actions/workflows/unit-tests.yml/badge.svg)](https://github.com/Choices-js/Choices/actions) [![Actions Status](https://github.com/Choices-js/Choices/actions/workflows/bundlesize.yml/badge.svg)](https://github.com/Choices-js/Choices/actions) [![npm](https://img.shields.io/npm/v/choices.js.svg)](https://www.npmjs.com/package/choices.js)

A vanilla, lightweight (~20kb gzipped 🎉), configurable select box/text input plugin. Similar to Select2 and Selectize but without the jQuery dependency.

[Demo](https://choices-js.github.io/Choices/)

## TL;DR

- Lightweight
- No jQuery dependency
- Configurable sorting
- Flexible styling
- Fast search/filtering
- Clean API
- Right-to-left support
- Custom templates

---

### Interested in writing your own ES6 JavaScript plugins? Check out [ES6.io](https://ES6.io/friend/JOHNSON) for great tutorials! 💪🏼

### Sponsored by:

<p align="center">
  <a href="https://forums.sufficientvelocity.com/" target="_blank" rel="noopener noreferrer">
    <img src="https://forums.sufficientvelocity.com/data/assets/static_light_logo.svg" alt="Sufficient Velocity" width="310" height="108">
  </a>
</p>

<p align="center">
  <a href="https://wanderermaps.com/" target="_blank" rel="noopener noreferrer">
    <img src="https://cdn.shopify.com/s/files/1/0614/3357/7715/files/Logo_BlackWithBackground_200x.png?v=1644802773" alt="Wanderer Maps logo">
  </a>
</p>

---

## Table of Contents

- [Installation](#installation)
- [Setup](#setup)
- [Terminology](#terminology)
- [Input Types](#input-types)
- [Configuration Options](#configuration-options)
- [Callbacks](#callbacks)
- [Events](#events)
- [Methods](#methods)
- [CSS custom properties](#css-custom-properties)
- [Development](#development)
- [License](#license)

## Installation

With [NPM](https://www.npmjs.com/package/choices.js):

```zsh
npm install choices.js
```

With [Yarn](https://yarnpkg.com/):

```zsh
yarn add choices.js
```

From a [CDN](https://www.jsdelivr.com/package/npm/choices.js):

**Notes:**
* There is sometimes a delay before the latest version of Choices is reflected on the CDN.
* Examples below pin a version (v11.1.0). Check [latest release](https://www.jsdelivr.com/package/npm/choices.js) and update v11.1.0 to the latest tag before using.
```html
<!-- Include base CSS (optional) -->
<link
  rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/choices.js/public/assets/styles/base.min.css"
/>
<!-- Or versioned -->
<link
  rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/choices.js@11.1.0/public/assets/styles/base.min.css"
/>

<!-- Include Choices CSS -->
<link
  rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/choices.js/public/assets/styles/choices.min.css"
/>
<!-- Or versioned -->
<link
  rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/choices.js@11.1.0/public/assets/styles/choices.min.css"
/>

<!-- Include Choices JavaScript (latest) -->
<script src="https://cdn.jsdelivr.net/npm/choices.js/public/assets/scripts/choices.min.js"></script>
<!-- Or versioned -->
<script src="https://cdn.jsdelivr.net/npm/choices.js@11.1.0/public/assets/scripts/choices.min.js"></script>
```

Or include Choices directly:

```html
<!-- Include base CSS (optional) -->
<link rel="stylesheet" href="public/assets/styles/base.min.css" />
<!-- Include Choices CSS -->
<link rel="stylesheet" href="public/assets/styles/choices.min.css" />
<!-- Include Choices JavaScript -->
<script src="/public/assets/scripts/choices.min.js"></script>
```

### CSS/SCSS

The use of `import` of css/scss is supported from webpack.

In .scss:
```scss
@import "choices.js/src/styles/choices";
```

In .js/.ts:
```javascript
import "choices.js/public/assets/styles/choices.css";
```

## Setup

**Note:** If you pass a selector which targets multiple elements, the first matching element will be used. Versions prior to 8.x.x would return multiple Choices instances.

```js
  // Pass single element
  const element = document.querySelector('.js-choice');
  const choices = new Choices(element);

  // Pass reference
  const choices = new Choices('[data-trigger]');
  const choices = new Choices('.js-choice');

  // Pass jQuery element
  const choices = new Choices($('.js-choice')[0]);

  // Passing options (with default options)
  const choices = new Choices(element, {
    silent: false,
    items: [],
    choices: [],
    renderChoiceLimit: -1,
    maxItemCount: -1,
    closeDropdownOnSelect: 'auto',
    singleModeForMultiSelect: false,
    addChoices: false,
    addItems: true,
    addItemFilter: (value) => !!value && value !== '',
    removeItems: true,
    removeItemButton: false,
    removeItemButtonAlignLeft: false,
    editItems: false,
    allowHTML: false,
    allowHtmlUserInput: false,
    duplicateItemsAllowed: true,
    delimiter: ',',
    paste: true,
    searchEnabled: true,
    searchChoices: true,
    searchDisabledChoices: false,
    searchFloor: 1,
    searchResultLimit: 4,
    searchFields: ['label', 'value'],
    position: 'auto',
    resetScrollPosition: true,
    shouldSort: true,
    shouldSortItems: false,
    sorter: (a, b) => sortByAlpha,
    shadowRoot: null,
    placeholder: true,
    placeholderValue: null,
    searchPlaceholderValue: null,
    prependValue: null,
    appendValue: null,
    renderSelectedChoices: 'auto',
    searchRenderSelectedChoices: true,
    loadingText: 'Loading...',
    noResultsText: 'No results found',
    noChoicesText: 'No choices to choose from',
    itemSelectText: 'Press to select',
    uniqueItemText: 'Only unique values can be added',
    customAddItemText: 'Only values matching specific conditions can be added',
    addItemText: (value, rawValue) => {
      return `Press Enter to add <b>"${value}"</b>`;
    },
    removeItemIconText: () => `Remove item`,
    removeItemLabelText: (value, rawValue) => `Remove item: ${value}`,
    maxItemText: (maxItemCount) => {
      return `Only ${maxItemCount} values can be added`;
    },
    valueComparer: (value1, value2) => {
      return value1 === value2;
    },
    classNames: {
      containerOuter: ['choices'],
      containerInner: ['choices__inner'],
      input: ['choices__input'],
      inputCloned: ['choices__input--cloned'],
      list: ['choices__list'],
      listItems: ['choices__list--multiple'],
      listSingle: ['choices__list--single'],
      listDropdown: ['choices__list--dropdown'],
      item: ['choices__item'],
      itemSelectable: ['choices__item--selectable'],
      itemDisabled: ['choices__item--disabled'],
      itemChoice: ['choices__item--choice'],
      description: ['choices__description'],
      placeholder: ['choices__placeholder'],
      group: ['choices__group'],
      groupHeading: ['choices__heading'],
      button: ['choices__button'],
      activeState: ['is-active'],
      focusState: ['is-focused'],
      openState: ['is-open'],
      disabledState: ['is-disabled'],
      highlightedState: ['is-highlighted'],
      selectedState: ['is-selected'],
      flippedState: ['is-flipped'],
      loadingState: ['is-loading'],
      invalidState: ['is-invalid'],
      notice: ['choices__notice'],
      addChoice: ['choices__item--selectable', 'add-choice'],
      noResults: ['has-no-results'],
      noChoices: ['has-no-choices'],
    },
    // Choices uses the great Fuse library for searching. You
    // can find more options here: https://fusejs.io/api/options.html
    fuseOptions: {
      includeScore: true
    },
    labelId: '',
    callbackOnInit: null,
    callbackOnCreateTemplates: null,
    appendGroupInSearch: false,
  });
```

## Terminology

| Word   | Definition                                                                                                                                                                                                                                                                                                              |
| ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Choice | A choice is a value a user can select. A choice would be equivalent to the `<option></option>` element within a select input.                                                                                                                                                                                           |
| Group  | A group is a collection of choices. A group should be seen as equivalent to a `<optgroup></optgroup>` element within a select input.                                                                                                                                                                                    |
| Item   | An item is an inputted value (text input) or a selected choice (select element). In the context of a select element, an item is equivalent to a selected option element: `<option value="Hello" selected></option>` whereas in the context of a text input an item is equivalent to `<input type="text" value="Hello">` |

## Input Types

Choices works with the following input types, referenced in the documentation as noted.

| HTML Element                                                                                           | Documentation "Input Type" |
| -------------------------------------------------------------------------------------------------------| -------------------------- |
| [`<input type="text">`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input)               | `text`                     |
| [`<select>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select)                         | `select-one`               |
| [`<select multiple>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select#attr-multiple)  | `select-multiple`          |

## Configuration Options

### silent

**Type:** `Boolean` **Default:** `false`

**Input types affected:** `text`, `select-one`, `select-multiple`

**Usage:** Optionally suppress console errors and warnings.

### items

**Type:** `Array` **Default:** `[]`

**Input types affected:** `text`

**Usage:** Add pre-selected items (see terminology) to text input.

Pass an array of strings:

`['value 1', 'value 2', 'value 3']`

Pass an array of objects:

```
[{
  value: 'Value 1',
  label: 'Label 1',
  id: 1
},
{
  value: 'Value 2',
  label: 'Label 2',
  id: 2,
  customProperties: {
    random: 'I am a custom property'
  }
}]
```

### choices

**Type:** `Array` **Default:** `[]`

**Input types affected:** `select-one`, `select-multiple`

**Usage:** Add choices (see terminology) to select input.

Pass an array of objects:

```
[{
  value: 'Option 1',
  label: 'Option 1',
  selected: true,
  disabled: false,
},
{
  value: 'Option 2',
  label: 'Option 2',
  selected: false,
  disabled: true,
  customProperties: {
    description: 'Custom description about Option 2',
    random: 'Another random custom property'
  },
},
{
  label: 'Group 1',
  choices: [{
    value: 'Option 3',
    label: 'Option 4',
    selected: true,
    disabled: false,
  },
  {
    value: 'Option 2',
    label: 'Option 2',
    selected: false,
    disabled: true,
    customProperties: {
      description: 'Custom description about Option 2',
      random: 'Another random custom property'
    }
  }]
}]
```

### renderChoiceLimit

**Type:** `Number` **Default:** `-1`

**Input types affected:** `select-one`, `select-multiple`

**Usage:** The amount of choices to be rendered within the dropdown list ("-1" indicates no limit). This is useful if you have a lot of choices where it is easier for a user to use the search area to find a choice.

### maxItemCount

**Type:** `Number` **Default:** `-1`

**Input types affected:** `text`, `select-multiple`

**Usage:** The amount of items a user can input/select ("-1" indicates no limit).

### closeDropdownOnSelect

**Type:** `Boolean` | 'auto' **Default:** `auto`

**Input types affected:** select-one, select-multiple

**Usage:** Control how the dropdown closes after making a selection for select-one or select-multiple.
- 'auto' defaults based on backing-element type:
- select-one: true
- select-multiple: false

### singleModeForMultiSelect

**Type:** `Boolean` **Default:** `false`

**Input types affected:** select-one, select-multiple

**Usage:** Make select-multiple with a max item count of 1 work similar to select-one does. Selecting an item will auto-close the dropdown and swap any existing item for the just selected choice. If applied to a select-one, it functions as above and not the standard select-one.

### addChoices
**Type**: `Boolean` **Default:** `false`

**Input types affected:** `select-multiple`, `select-one`

**Usage:** Whether a user can add choices dynamically.

**Note:** `addItems` must also be `true`

### addItems

**Type:** `Boolean` **Default:** `true`

**Input types affected:** `text`

**Usage:** Whether a user can add items.

### removeItems

**Type:** `Boolean` **Default:** `true`

**Input types affected:** `text`, `select-multiple`

**Usage:** Whether a user can remove items.

### removeItemButton

**Type:** `Boolean` **Default:** `false`

**Input types affected:** `text`, `select-one`, `select-multiple`

**Usage:** Whether each item should have a remove button.

### removeItemButtonAlignLeft

**Type:** `Boolean` **Default:** `false`

**Input types affected:** `text`, `select-one`, `select-multiple`

**Usage:** Align item remove button left vs right

### editItems

**Type:** `Boolean` **Default:** `false`

**Input types affected:** `text`

**Usage:** Whether a user can edit items. An item's value can be edited by pressing the backspace.

### allowHTML

**Type:** `Boolean` **Default:** `false`

**Input types affected:** `text`, `select-one`, `select-multiple`

**Usage:** Whether HTML should be rendered in all Choices elements. If `false`, all elements (placeholder, items, etc.) will be treated as plain text. If `true`, this can be used to perform XSS scripting attacks if you load choices from a remote source.

### allowHtmlUserInput

**Type:** `Boolean` **Default:** `false`

**Input types affected:** `text`, `select-one`, `select-multiple`

**Usage:** Whether HTML should be escaped on input when `addItems` or `addChoices` is true. If `false`, user input will be treated as plain text. If `true`, this can be used to perform XSS scripting attacks if you load choices from a remote source.

### duplicateItemsAllowed

**Type:** `Boolean` **Default:** `true`

**Input types affected:** `text`, `select-multiple`, `select-one`

**Usage:** Whether duplicate inputted/chosen items are allowed

### delimiter

**Type:** `String` **Default:** `,`

**Input types affected:** `text`

**Usage:** What divides each value. The default delimiter separates each value with a comma: `"Value 1, Value 2, Value 3"`.

### paste

**Type:** `Boolean` **Default:** `true`

**Input types affected:** `text`, `select-multiple`

**Usage:** Whether a user can paste into the input.

### searchEnabled

**Type:** `Boolean` **Default:** `true`

**Input types affected:** `select-one`, `select-multiple`

**Usage:** Whether a search area should be shown.

### searchChoices

**Type:** `Boolean` **Default:** `true`

**Input types affected:** `select-one`

**Usage:** Whether choices should be filtered by input or not. If `false`, the search event will still emit, but choices will not be filtered.

### searchDisabledChoices

**Type:** `Boolean` **Default:** `false`

**Input types affected:** `select-one`, `select-multiple`

**Usage:** Whether disabled choices should be included in search results. If `true`, disabled choices will appear in search results but still cannot be selected. This is useful when you want users to see what options exist but are currently unavailable. Placeholders are always excluded from search results regardless of this setting.

### searchFields

**Type:** `Array/String` **Default:** `['label', 'value']`

**Input types affected:**`select-one`, `select-multiple`

**Usage:** Specify which fields should be used when a user is searching. If you have added custom properties to your choices, you can add these values thus: `['label', 'value', 'customProperties.example']`.

### searchFloor

**Type:** `Number` **Default:** `1`

**Input types affected:** `select-one`, `select-multiple`

**Usage:** The minimum length a search value should be before choices are searched.

### searchResultLimit: 4,

**Type:** `Number` **Default:** `4`

**Input types affected:** `select-one`, `select-multiple`

**Usage:** The maximum amount of search results to show  ("-1" indicates no limit).

### shadowRoot

**Type:** Document Element **Default:** null

**Input types affected:** `select-one`, `select-multiple`

**Usage:** You can pass along the shadowRoot from your application like so.

```js
var shadowRoot = document
  .getElementById('wrapper')
  .attachShadow({ mode: 'open' });
...
var el = shadowRoot.querySelector(...);
var choices = new Choices(el, {
  shadowRoot: shadowRoot,
});
```

### position

**Type:** `String` **Default:** `auto`

**Input types affected:** `select-one`, `select-multiple`

**Usage:** Whether the dropdown should appear above (`top`) or below (`bottom`) the input. By default, if there is not enough space within the window the dropdown will appear above the input, otherwise below it.

### resetScrollPosition

**Type:** `Boolean` **Default:** `true`

**Input types affected:** `select-multiple`

**Usage:** Whether the scroll position should reset after adding an item.

### addItemFilter

**Type:** `string | RegExp | Function` **Default:** `null`

**Input types affected:** `text`

**Usage:** A RegExp or string (will be passed to RegExp constructor internally) or filter function that will need to return `true` for a user to successfully add an item.

**Example:**

```js
// Only adds items matching the text test
new Choices(element, {
  addItemFilter: (value) => {
    return ['orange', 'apple', 'banana'].includes(value);
  };
});

// only items ending to `-red`
new Choices(element, {
  addItemFilter: '-red$';
});

```

### shouldSort

**Type:** `Boolean` **Default:** `true`

**Input types affected:** `select-one`, `select-multiple`

**Usage:** Whether choices and groups should be sorted. If false, choices/groups will appear in the order they were given.

### shouldSortItems

**Type:** `Boolean` **Default:** `false`

**Input types affected:** `text`, `select-multiple`

**Usage:** Whether items should be sorted. If false, items will appear in the order they were selected.

### sorter

**Type:** `Function` **Default:** sortByAlpha

**Input types affected:** `select-one`, `select-multiple`

**Usage:** The function that will sort choices and items before they are displayed (unless a user is searching). By default choices and items are sorted by alphabetical order.

**Example:**

```js
// Sorting via length of label from largest to smallest
const example = new Choices(element, {
  sorter: function(a, b) {
    return b.label.length - a.label.length;
  },
});
```

### placeholder

**Type:** `Boolean` **Default:** `true`

**Input types affected:** `text`

**Usage:** Whether the input should show a placeholder. Used in conjunction with `placeholderValue`. If `placeholder` is set to true and no value is passed to `placeholderValue`, the passed input's placeholder attribute will be used as the placeholder value.

**Note:** For select boxes, the recommended way of adding a placeholder is as follows:

```html
<select data-placeholder="This is a placeholder">
  <option>...</option>
  <option>...</option>
  <option>...</option>
</select>
```

For backward compatibility, `<option value="">This is a placeholder</option>` and `<option placeholder>This is a placeholder</option>` are also supported.

### placeholderValue

**Type:** `String` **Default:** `null`

**Input types affected:** `text`

**Usage:** The value of the inputs placeholder.

### searchPlaceholderValue

**Type:** `String` **Default:** `null`

**Input types affected:** `select-one`

**Usage:** The value of the search inputs placeholder.

### prependValue

**Type:** `String` **Default:** `null`

**Input types affected:** `text`, `select-one`, `select-multiple`

**Usage:** Prepend a value to each item added/selected.

### appendValue

**Type:** `String` **Default:** `null`

**Input types affected:** `text`, `select-one`, `select-multiple`

**Usage:** Append a value to each item added/selected.

### renderSelectedChoices

**Type:** `String` **Default:** `auto`

**Input types affected:** `select-multiple`

**Usage:** Whether selected choices should be removed from the list. By default choices are removed when they are selected in multiple select box. To always render choices pass `always`.

### searchRenderSelectedChoices

**Type:** `Boolean` **Default:** `true'`

**Input types affected:** `select-multiple`

**Usage:** Whether selected choices should be removed from the list during search.

**Example:**

```js
// Hide selected choices from search results
const example = new Choices(element, {
  searchRenderSelectedChoices: false,
});
```

### loadingText

**Type:** `String` **Default:** `Loading...`

**Input types affected:** `select-one`, `select-multiple`

**Usage:** The text that is shown whilst choices are being populated via AJAX.

### noResultsText

**Type:** `String/Function` **Default:** `No results found`

**Input types affected:** `select-one`, `select-multiple`

**Usage:** The text that is shown when a user's search has returned no results. Optionally pass a function returning a string.

### noChoicesText

**Type:** `String/Function` **Default:** `No choices to choose from`

**Input types affected:** `select-multiple`, `select-one`

**Usage:** The text that is shown when a user has selected all possible choices, or no choices exist. Optionally pass a function returning a string.

### itemSelectText

**Type:** `String` **Default:** `Press to select`

**Input types affected:** `select-multiple`, `select-one`

**Usage:** The text that is shown when a user hovers over a selectable choice. Set to empty to not reserve space for this text.

### addItemText

**Type:** `String/Function` **Default:** `Press Enter to add "${value}"` **Arguments:** `value`, `valueRaw`

**Input types affected:** `text`, `select-one`, `select-multiple`

**Usage:** The text that is shown when a user has inputted a new item but has not pressed the enter key. To access the current input value, pass a function with a `value` argument (see the [default config](https://github.com/Choices-js/Choices#setup) for an example), otherwise pass a string.

Return type must be safe to insert into HTML (ie use the 1st argument which is sanitised)

### removeItemIconText

**Type:** `String/Function` **Default:** `Remove item"` **Arguments:** `value`, `valueRaw`, `item`

**Input types affected:** `text`, `select-one`, `select-multiple`

**Usage:** The text/icon for the remove button. To access the item's value, pass a function with a `value` argument (see the **default config** [https://github.com/Choices-js/Choices#setup] for an example), otherwise pass a string.
To access the item's label, use the 3rd argument. *Note*; this label is not escaped.

Return type must be safe to insert into HTML (ie use the 1st argument which is sanitised)

### removeItemLabelText

**Type:** `String/Function` **Default:** `Remove item: ${value}"` **Arguments:** `value`, `valueRaw`, `item`

**Input types affected:** `text`, `select-one`, `select-multiple`

**Usage:** The text for the remove button's aria label. To access the item's value, pass a function with a `value` argument (see the **default config** [https://github.com/Choices-js/Choices#setup] for an example), otherwise pass a string.
To access the item's label, use the 3rd argument. *Note*; this label is not escaped.

Return type must be safe to insert into HTML (ie use the 1st argument which is sanitised)

### maxItemText

**Type:** `String/Function` **Default:** `Only ${maxItemCount} values can be added` **Arguments:** `maxItemCount`

**Input types affected:** `text`

**Usage:** The text that is shown when a user has focus on the input but has already reached the [max item count](https://github.com/Choices-js/Choices#maxitemcount). To access the max item count, pass a function with a `maxItemCount` argument (see the [default config](https://github.com/Choices-js/Choices#setup) for an example), otherwise pass a string.

### valueComparer

**Type:** `Function` **Default:** `strict equality` **Arguments:** `value1`, `value2`

**Input types affected:** `select-one`, `select-multiple`

**Usage:** A custom compare function used when finding choices by value (using `setChoiceByValue`).

**Example:**

```js
const example = new Choices(element, {
  valueComparer: (a, b) => value.trim() === b.trim(),
});
```

### labelId

**Type:** `String` **Default:** ``

**Input types affected:** `select-one`, `select-multiple`

**Usage:** The labelId improves accessibility. If set, it will add aria-labelledby to the choices element.

### classNames

**Type:** `Object` **Default:**

```
classNames: {
  containerOuter: ['choices'],
  containerInner: ['choices__inner'],
  input: ['choices__input'],
  inputCloned: ['choices__input--cloned'],
  list: ['choices__list'],
  listItems: ['choices__list--multiple'],
  listSingle: ['choices__list--single'],
  listDropdown: ['choices__list--dropdown'],
  item: ['choices__item'],
  itemSelectable: ['choices__item--selectable'],
  itemDisabled: ['choices__item--disabled'],
  itemChoice: ['choices__item--choice'],
  description: ['choices__description'],
  placeholder: ['choices__placeholder'],
  group: ['choices__group'],
  groupHeading: ['choices__heading'],
  button: ['choices__button'],
  activeState: ['is-active'],
  focusState: ['is-focused'],
  openState: ['is-open'],
  disabledState: ['is-disabled'],
  highlightedState: ['is-highlighted'],
  selectedState: ['is-selected'],
  flippedState: ['is-flipped'],
  loadingState: ['is-loading'],
  invalidState: ['is-invalid'],
  notice: ['choices__notice'],
  addChoice: ['choices__item--selectable', 'add-choice'],
  noResults: ['has-no-results'],
  noChoices: ['has-no-choices'],
}
```

**Input types affected:** `text`, `select-one`, `select-multiple`

**Usage:** Classes added to HTML generated by Choices. By default classnames follow the [BEM](http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/) notation.

## Callbacks

**Note:** For each callback, `this` refers to the current instance of Choices. This can be useful if you need access to methods (`this.disable()`) or the config object (`this.config`).

### callbackOnInit

**Type:** `Function` **Default:** `null`

**Input types affected:** `text`, `select-one`, `select-multiple`

**Usage:** Function to run once Choices initialises.

### callbackOnCreateTemplates(strToEl: (str: string) => HTMLElement, escapeForTemplate: (allowHTML: boolean, s: StringUntrusted | StringPreEscaped | string) => string, getClassNames: (s: Array<string> | string) => string)

**Type:** `Function` **Default:** `null` **Arguments:** `strToEl`, `escapeForTemplate`, `getClassNames`

**Input types affected:** `text`, `select-one`, `select-multiple`

**Usage:** Function to run on template creation. Through this callback it is possible to provide custom templates for the various components of Choices (see terminology). For Choices to work with custom templates, it is important you maintain the various data attributes defined [here](https://github.com/Choices-js/Choices/blob/main/src/scripts/templates.ts).
If you want just extend a little original template then you may use `Choices.defaults.templates` to get access to
original template function.

Templates receive the full Choices config as the first argument to any template, which allows you to conditionally display things based on the options specified.

@note For each callback, `this` refers to the current instance of Choices. This can be useful if you need access to methods `(this.disable())`.

**Example:**

```js
const example = new Choices(element, {
  callbackOnCreateTemplates: (strToEl, escapeForTemplate, getClassNames) => ({
    input: (...args) =>
      Object.assign(Choices.defaults.templates.input.call(this, ...args), {
        type: 'email',
      }),
  }),
});
```

or more complex:

```js
// StrToEl = (str: string) => HTMLElement | HTMLInputElement | HTMLOptionElement;
// EscapeForTemplateFn = (allowHTML: boolean, s: StringUntrusted | StringPreEscaped | string) => string;
// GetClassNamesFn = (s: string | Array<string>) => string;
const example = new Choices(element, {
  callbackOnCreateTemplates: function(strToEl /*:StrToEl*/, escapeForTemplate /*:EscapeForTemplateFn*/, getClassNames /*:GetClassNamesFn*/) {
    return {
      item: ({ classNames }, data) => {
        return strToEl(`
          <div class="${getClassNames(classNames.item).join(' ')} ${
          getClassNames(data.highlighted
            ? classNames.highlightedState
            : classNames.itemSelectable).join(' ')
        } ${
          data.placeholder ? classNames.placeholder : ''
        }" data-item data-id="${data.id}" data-value="${escapeForTemplate(true, data.value)}" ${
          data.active ? 'aria-selected="true"' : ''
        } ${data.disabled ? 'aria-disabled="true"' : ''}>
            <span>&bigstar;</span> ${escapeForTemplate(true, data.label)}
          </div>
        `);
      },
      choice: ({ classNames }, data) => {
        return strToEl(`
          <div class="${getClassNames(classNames.item).join(' ')} ${getClassNames(classNames.itemChoice).join(' ')} ${
          getClassNames(data.disabled ? classNames.itemDisabled : classNames.itemSelectable).join(' ')
        }" data-select-text="${this.config.itemSelectText}" data-choice ${
          data.disabled
            ? 'data-choice-disabled aria-disabled="true"'
            : 'data-choice-selectable'
        } data-id="${data.id}" data-value="${escapeForTemplate(true, data.value)}" ${
          data.groupId > 0 ? 'role="treeitem"' : 'role="option"'
        }>
            <span>&bigstar;</span> ${escapeForTemplate(true, data.label)}
          </div>
        `);
      },
    };
  },
});
```

## Events

**Note:** Events fired by Choices behave the same as standard events. Each event is triggered on the element passed to Choices (accessible via `this.passedElement`. Arguments are accessible within the `event.detail` object.

**Example:**

```js
const element = document.getElementById('example');
const example = new Choices(element);

element.addEventListener(
  'addItem',
  function(event) {
    // do something creative here...
    console.log(event.detail.id);
    console.log(event.detail.value);
    console.log(event.detail.label);
    console.log(event.detail.customProperties);
    console.log(event.detail.groupValue);
  },
  false,
);

// or
const example = new Choices(document.getElementById('example'));

example.passedElement.element.addEventListener(
  'addItem',
  function(event) {
    // do something creative here...
    console.log(event.detail.id);
    console.log(event.detail.value);
    console.log(event.detail.label);
    console.log(event.detail.customProperties);
    console.log(event.detail.groupValue);
  },
  false,
);
```

### addItem

**Payload:** `id, highlighted, labelClass, labelDescription, customProperties, disabled, active, label, placeholder, value, groupValue, element, keyCode`

**Input types affected:** `text`, `select-one`, `select-multiple`

**Usage:** Triggered each time an item is added (programmatically or by the user).

### removeItem

**Payload:** `id, highlighted, labelClass, labelDescription, customProperties, disabled, active, label, placeholder, value, groupValue, element, keyCode`

**Input types affected:** `text`, `select-one`, `select-multiple`

**Usage:** Triggered each time an item is removed (programmatically or by the user).

### highlightItem

**Payload:** `id, highlighted, labelClass, labelDescription, customProperties, disabled, active, label, placeholder, value, groupValue, element, keyCode`

**Input types affected:** `text`, `select-multiple`

**Usage:** Triggered each time an item is highlighted.

### unhighlightItem

**Payload:** `id, highlighted, labelClass, labelDescription, customProperties, disabled, active, label, placeholder, value, groupValue, element, keyCode`

**Input types affected:** `text`, `select-multiple`

**Usage:** Triggered each time an item is unhighlighted.

### choice

**Payload:** `id, highlighted, labelClass, labelDescription, customProperties, disabled, active, label, placeholder, value, groupValue, element, keyCode`

**Input types affected:** `select-one`, `select-multiple`

**Usage:** Triggered each time a choice is selected **by a user**, regardless if it changes the value of the input.
`choice` is a Choice object here (see terminology or typings file)

### change

**Payload:** `value: string`

**Input types affected:** `text`, `select-one`, `select-multiple`

**Usage:** Triggered each time an item is added/removed **by a user**.

### search

**Payload:** `value: string`, `resultCount: number`

**Input types affected:** `select-one`, `select-multiple`

**Usage:** Triggered when a user types into an input to search choices. When a search is ended, a search event with an empty value with no resultCount is triggered.

### showDropdown

**Payload:** -

**Input types affected:** `select-one`, `select-multiple`

**Usage:** Triggered when the dropdown is shown.

### hideDropdown

**Payload:** -

**Input types affected:** `select-one`, `select-multiple`

**Usage:** Triggered when the dropdown is hidden.

### highlightChoice

**Payload:** `el`

**Input types affected:** `select-one`, `select-multiple`

**Usage:** Triggered when a choice from the dropdown is highlighted.
The `el` argument is choices.passedElement object that was affected.

## Methods

Methods can be called either directly or by chaining:

```js
// Calling a method by chaining
const choices = new Choices(element, {
  addItems: false,
  removeItems: false,
})
  .setValue(['Set value 1', 'Set value 2'])
  .disable();

// Calling a method directly
const choices = new Choices(element, {
  addItems: false,
  removeItems: false,
});

choices.setValue(['Set value 1', 'Set value 2']);
choices.disable();
```

### destroy();

**Input types affected:** `text`, `select-multiple`, `select-one`

**Usage:** Kills the instance of Choices, removes all event listeners and returns passed input to its initial state.

### init();

**Input types affected:** `text`, `select-multiple`, `select-one`

**Usage:** Creates a new instance of Choices, adds event listeners, creates templates and renders a Choices element to the DOM.

**Note:** This is called implicitly when a new instance of Choices is created. This would be used after a Choices instance had already been destroyed (using `destroy()`).

### refresh(withEvents: boolean = false, selectFirstOption: boolean = false);

**Input types affected:** `select-multiple`, `select-one`

**Usage:** Reads options from backing `<select>` element, and recreates choices. Existing items are preserved. When `withEvents` is truthy, only `addItem` events are generated.

### highlightAll();

**Input types affected:** `text`, `select-multiple`

**Usage:** Highlight each chosen item (selected items can be removed).

### unhighlightAll();

**Input types affected:** `text`, `select-multiple`

**Usage:** Un-highlight each chosen item.

### removeActiveItemsByValue(value: string);

**Input types affected:** `text`, `select-multiple`

**Usage:** Remove each item by a given value.

### removeActiveItems(excludedId?: number);

**Input types affected:** `text`, `select-multiple`

**Usage:** Remove each selectable item.

## removeChoice(value: string);

**Input types affected:** `text`, `select-multiple`, `select-one`

**Usage:** Remove an option/item by value

### removeHighlightedItems(runEvent?: boolean);

**Input types affected:** `text`, `select-multiple`

**Usage:** Remove each item the user has selected.

### showDropdown(preventInputFocus?: boolean);

**Input types affected:** `select-one`, `select-multiple`

**Usage:** Show choices list dropdown.

### hideDropdown(preventInputFocus?: boolean);

**Input types affected:** ``select-one`, `select-multiple`

**Usage:** Hide choices list dropdown.

### setChoices(choicesArrayOrFetcher?: (InputChoice | InputGroup)[] | ((instance: Choices) => (InputChoice | InputGroup)[] | Promise<(InputChoice | InputGroup)[]>), value?: string | null, label?: string, replaceChoices?: boolean = false, clearSearchFlag?: boolean = false, replaceItems?: boolean = false): this | Promise<this>;

**Input types affected:** `select-one`, `select-multiple`

**Usage:** Set choices of select input via an array of objects (or function that returns array of object or promise of it), a value field name and a label field name.

This behaves the similar as passing items via the `choices` option but can be called after initialising Choices. This can also be used to add groups of choices (see example 3); Optionally pass a true `replaceChoices` value to remove any existing choices. Optionally pass a true `replaceItems` value to remove any items, if false choices for selected items are preserved. Optionally pass a `customProperties` object to add additional data to your choices (useful when searching/filtering etc). Passing an empty array as the first parameter, and a true `replaceChoices` is the same as calling `clearChoices` (see below).

**Example 1:**

```js
const example = new Choices(element);

example.setChoices(
  [
    { value: 'One', label: 'Label One', disabled: true },
    { value: 'Two', label: 'Label Two', selected: true },
    { value: 'Three', label: 'Label Three' },
  ],
  'value',
  'label',
  false,
);
```

**Example 2:**

```js
const example = new Choices(element);

// Passing a function that returns Promise of choices
example.setChoices(async () => {
  try {
    const items = await fetch('/items');
    return items.json();
  } catch (err) {
    console.error(err);
  }
});
```

**Example 3:**

```js
const example = new Choices(element);

example.setChoices(
  [
    {
      label: 'Group one',
      disabled: false,
      choices: [
        { value: 'Child One', label: 'Child One', selected: true },
        { value: 'Child Two', label: 'Child Two', disabled: true },
        { value: 'Child Three', label: 'Child Three' },
      ],
    },
    {
      label: 'Group two',
      disabled: false,
      choices: [
        { value: 'Child Four', label: 'Child Four', disabled: true },
        { value: 'Child Five', label: 'Child Five' },
        {
          value: 'Child Six',
          label: 'Child Six',
          customProperties: {
            description: 'Custom description about child six',
            random: 'Another random custom property',
          },
        },
      ],
    },
  ],
  'value',
  'label',
  false,
);
```

### clearChoices(clearOptions: boolean = true, clearItems: boolean = false);

**Input types affected:** `select-one`, `select-multiple`

**Usage:** Clear all choices from select including any selected items. Does **not** reset the search state.
- `clearOptions` If true, clears the backing options from the `<select>` element
- `clearItems` If false, preserves selected items instead of clearing them

### getValue(valueOnly?: boolean): string[] | EventChoice[] | EventChoice | string;

**Input types affected:** `text`, `select-one`, `select-multiple`

**Usage:** Get value(s) of input (i.e. inputted items (text) or selected choices (select)). Optionally pass an argument of `true` to only return values rather than value objects.

**Example:**

```js
const example = new Choices(element);
const values = example.getValue(true); // returns ['value 1', 'value 2'];
const valueArray = example.getValue(); // returns [{ active: true, choiceId: 1, highlighted: false, id: 1, label: 'Label 1', value: 'Value 1'},  { active: true, choiceId: 2, highlighted: false, id: 2, label: 'Label 2', value: 'Value 2'}];
```

### setValue(items: string[] | InputChoice[]): this;

**Input types affected:** `text`, `select-one`, `select-multiple`

**Usage:** Set value of input based on an array of objects or strings. This behaves exactly the same as passing items via the `items` option but can be called after initialising Choices.

**Example:**

```js
const example = new Choices(element);

// via an array of objects
example.setValue([
  { value: 'One', label: 'Label One' },
  { value: 'Two', label: 'Label Two' },
  { value: 'Three', label: 'Label Three' },
]);

// or via an array of strings
example.setValue(['Four', 'Five', 'Six']);
```

### setChoiceByValue(value: string | string[]);

**Input types affected:** `select-one`, `select-multiple`

**Usage:** Set value of input based on existing Choice. `value` can be either a single string or an array of strings

**Example:**

```js
const example = new Choices(element, {
  choices: [
    { value: 'One', label: 'Label One' },
    { value: 'Two', label: 'Label Two', disabled: true },
    { value: 'Three', label: 'Label Three' },
  ],
});

example.setChoiceByValue('Two'); // Choice with value of 'Two' has now been selected.
```

### clearStore();

**Input types affected:** `text`, `select-one`, `select-multiple`

**Usage:** Removes all items, choices and groups. Resets the search state. Use with caution.

### clearInput();

**Input types affected:** `text`

**Usage:** Clear input of any user inputted text.

### disable();

**Input types affected:** `text`, `select-one`, `select-multiple`

**Usage:** Disables input from accepting new value/selecting further choices.

### enable();

**Input types affected:** `text`, `select-one`, `select-multiple`

**Usage:** Enables input to accept new values/select further choices.

## Browser compatibility

Choices is compiled using [Babel](https://babeljs.io/) targeting browsers [with more than 1% of global usage](https://github.com/Choices-js/Choices/blob/main/.browserslistrc) and expecting that features [listed below](https://github.com/Choices-js/Choices/blob/main/.eslintrc.json#L62) are available or polyfilled in browser.
You may see exact list of target browsers by running `npm exec browserslist` within this repository folder.
If you need to support a browser that does not have one of the features listed below,
I suggest including a polyfill from [cdnjs.cloudflare.com/polyfill](https://cdnjs.cloudflare.com/polyfill):

**Polyfill example used for the demo:**

```html
<script src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?version=4.8.0&features=Array.from%2CArray.prototype.find%2CArray.prototype.includes%2CSymbol%2CSymbol.iterator%2CDOMTokenList%2CObject.assign%2CCustomEvent%2CElement.prototype.classList%2CElement.prototype.closest%2CElement.prototype.dataset%2CElement.prototype.replaceChildren"></script>
```

**Features used in Choices:**

```polyfills
Array.from
Array.prototype.find
Array.prototype.includes
Symbol
Symbol.iterator
DOMTokenList
Object.assign
CustomEvent
Element.prototype.classList
Element.prototype.closest
Element.prototype.dataset
Element.prototype.replaceChildren
```

## CSS custom properties

Since version `11.2`, you are able to customize the behavior and CSS of Choices.js using the following
[custom properties](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_cascading_variables/Using_CSS_custom_properties).

| Property                          | Default                                   | Description                                                                 |
|-----------------------------------|-------------------------------------------|-----------------------------------------------------------------------------|
| `--choices-darken`                | `black`                                   | Darken color used within the color-mix                                      |
| `--choices-lighten`               | `white`                                   | Ligten color used within the color-mix                                      |
| `--choices-bg-color`              | `#f9f9f9`                                 | Background color of the choices element                                     |
| `--choices-bg-color-disabled`     | `#eaeaea`                                 | Background color of a disabled choices element                              |
| `--choices-bg-color-dropdown`     | `#fff`                                    | Background color of the dropdown                                            |
| `--choices-text-color`            | `#333`                                    | Text color of choices                                                       |
| `--choices-keyline-color`         | `#ddd`                                    | Border-colors within choices                                                |
| `--choices-primary-color`         | `#005F75`                                 | Primary color                                                               |
| `--choices-disabled-color`        | `#eaeaea`                                 | Background color of disabled items                                          |
| `--choices-item-disabled-color`   | `#fff`                                    | Text color of disabled items                                                |
| `--choices-invalid-color`         | `#d33141`                                 | Border color of the invalid state                                           |
| `--choices-highlighted-color`     | `#f2f2f2`                                 | Highlight background of the choices items                                   |
| `--choices-highlight-color`       | `#005F75`                                 | Focus color of the choices button                                           |
| `--choices-font-size-lg`          | `16px`                                    | Basic font size for choices                                                 |
| `--choices-font-size-md`          | `14px`                                    | Font size for medium choices items, e.g. the input field                    |
| `--choices-font-size-sm`          | `12px`                                    | Font size for the small choices items, e.g. select multiple or explanations |
| `--choices-guttering`             | `24px`                                    | Margin-Bottom of the choices wrapper                                        |
| `--choices-border-radius`         | `2.5px`                                   | Border-radius of the choices element                                        |
| `--choices-border-radius-item`    | `20px`                                    | Border-radius of the choices items                                          |
| `--choices-z-index`               | `1`                                       | z-index of the active choices dropdown                                      |
| `--choices-input-height`          | `44px`                                    | Height of the choices inner element                                         |
| `--choices-width`                 | `100%`                                    | Width of the choices inner element                                          |
| `--choices-base-border`           | `1px solid var( --choices-keyline-color)` | Bottom-border of the choices inner element                                  |
| `--choices-multiple-item-margin`  | `3.75px`                                  | Margin of the dropdown items (multiple mode)                                |
| `--choices-multiple-item-padding` | `4px 10px`                                | Padding of the dropdown items (multiple mode)                               |
| `--choices-dropdown-item-padding` | `10px`                                    | Padding of the choices dropdown items                                       |
| `--choices-list-single-padding`   | `4px 16px 4px 4px`                        | Padding of the listbox description                                          |
| `--choices-input-margin-bottom`   | `5px`                                     | Margin-bottom of the choices input (text inputs)                            |
| `--choices-input-padding`         | `4px 0 4px 2px`                           | Padding of the choices input                                                |
| `--choices-inner-padding`         | `7.5px 7.5px 3.75px`                      | Padding of the choices inner element                                        |
| `--choices-inner-one-padding`     | `7.5px`                                   | Padding of the choices inner element (Single select input)                  |
| `--choices-arrow-size`            | `5px`                                     | Size of the choices dropdown symbol                                         |
| `--choices-arrow-margin-top`      | `-2.5px`                                  | Top offset of the dropdown symbol                                           |
| `--choices-arrow-margin-top-open` | `-7.5px`                                  | Top offset of the active dropdown symbol                                    |
| `--choices-arrow-right`           | `11.5px`                                  | Right offset of the dropdown symbol                                         |
| `--choices-icon-cross`            | `url("...")`                              | Button image                                                                |
| `--choices-icon-cross-inverse`    | `url("...")`                              | Button image (inversed color)                                               |
| `--choices-button-offset`         | `8px`                                     | Button offset                                                               |
| `--choices-button-dimension`      | `8px`                                     | Button background size                                                      |
| `--choices-button-line-height`    | `1`                                       | Button line height                                                          |
| `--choices-button-border-radius`  | `0`                                       | Button border-radius                                                        |
| `--choices-button-opacity`        | `0.75`                                    | Button opacity                                                              |
| `--choices-button-opacity-hover`  | `1`                                       | Button opacity on hover                                                     |
| `--choices-placeholder-opacity`   | `0.5`                                     | Placeholder opacity                                                         |

### Dark mode example

The current demo page uses the following variables for its dark mode

```css
@media (prefers-color-scheme: dark) {
  :root {
    --choices-primary-color: #38daff;
    --choices-item-color: black;
    --choices-bg-color: #101010;
    --choices-bg-color-dropdown: #101010;
    --choices-keyline-color: #3b3e40;
    --choices-bg-color-disabled: #181a1b;
    --choices-item-disabled-color: #eee;
    --choices-disabled-color: #2d2d2d;
    --choices-highlighted-color: #16292d;
    --choices-icon-cross: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjEiIHZpZXdCb3g9IjAgMCAyMSAyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yLjU5Mi4wNDRsMTguMzY0IDE4LjM2NC0yLjU0OCAyLjU0OEwuMDQ0IDIuNTkyeiIvPjxwYXRoIGQ9Ik0wIDE4LjM2NEwxOC4zNjQgMGwyLjU0OCAyLjU0OEwyLjU0OCAyMC45MTJ6Ii8+PC9nPjwvc3ZnPg==");
    --choices-icon-cross-inverse: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjEiIHZpZXdCb3g9IjAgMCAyMSAyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjRkZGIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yLjU5Mi4wNDRsMTguMzY0IDE4LjM2NC0yLjU0OCAyLjU0OEwuMDQ0IDIuNTkyeiIvPjxwYXRoIGQ9Ik0wIDE4LjM2NEwxOC4zNjQgMGwyLjU0OCAyLjU0OEwyLjU0OCAyMC45MTJ6Ii8+PC9nPjwvc3ZnPg==");
  }
}
```

## Development

To setup a local environment: clone this repo, navigate into its directory in a terminal window and run the following command:

`npm install`

### playwright

e2e (End-to-end) tests are implemented using playwright, which requires installing likely with OS support.

`npx playwright install`
`npx playwright install-deps `

For JetBrain IDE's the `Test automation` plugin is recommended:
https://plugins.jetbrains.com/plugin/20175-test-automation
For usage see:
https://www.jetbrains.com/help/phpstorm/playwright.html

### NPM tasks

| Task                      | Usage                                                        |
|---------------------------|--------------------------------------------------------------|
| `npm run start`           | Fire up local server for development                         |
| `npm run test:unit`       | Run sequence of tests once                                   |
| `npm run test:unit:watch` | Fire up test server and re-test on file change               |
| `npm run test:e2e`        | Run sequence of e2e tests (with local server)                |
| `npm run test`            | Run both unit and e2e tests                                  |
| `npm run playwright:gui`  | Run Playwright e2e tests (GUI)                               |
| `npm run playwright:cli`  | Run Playwright e2e tests (CLI)                               |
| `npm run js:build`        | Compile Choices to an uglified JavaScript file               |
| `npm run css:watch`       | Watch SCSS files for changes. On a change, run build process |
| `npm run css:build`       | Compile, minify and prefix SCSS files to CSS                 |


### Build flags

Choices supports various environment variables as build-flags to enable/disable features.
The pre-built bundles these features set, and tree shaking uses the non-used parts.

#### CHOICES_SEARCH_FUSE
**Values:** `full` / `basic` / `null`
**Default:** `full`

Fuse.js support a `full`/`basic` profile. `full` adds additional logic operations, which aren't used by default with Choices. The `null` option drops Fuse.js as a dependency and instead uses a simple prefix only search feature.

#### CHOICES_SEARCH_KMP
**Values:** `1` / `0`
**Default:** `0`

If `CHOICES_SEARCH_FUSE` is `null`, this enables an `indexOf`-like [Knuth–Morris–Pratt algorithm](https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm). Useful for very large data sets, without fuzzy searching.

#### CHOICES_CAN_USE_DOM
**Values:** `1` / `0`
**Default:** `1`

Allows loading Choices into a non-browser environment.

### Interested in contributing?

We're always interested in having more active maintainers.  Please get in touch if you're interested 👍

## License

MIT License

## Web component

Want to use Choices as a web component? You're in luck. Adidas have built one for their design system which can be found [here](https://github.com/adidas/choicesjs-stencil).

## Misc

Thanks to [@mikefrancis](https://github.com/mikefrancis/) for [sending me on a hunt](https://twitter.com/_mikefrancis/status/701797835826667520) for a non-jQuery solution for select boxes that eventually led to this being built!


================================================
FILE: babel.config.json
================================================
{
  "presets": ["@babel/preset-env", "@babel/preset-typescript"],
  "plugins": [
    "@babel/plugin-transform-object-rest-spread"
  ]
}


================================================
FILE: jsconfig.json
================================================
{
  "compilerOptions": {
    "checkJs": true,
    "target": "es2020",
    "lib": ["esnext", "dom"],
    "types": [],
    "strict": true,
    "moduleResolution": "node",
    /* Additional Checks */
    "noImplicitAny": false,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "strictNullChecks": false
  }
}


================================================
FILE: package.json
================================================
{
  "name": "choices.js",
  "version": "11.2.1",
  "description": "A vanilla JS customisable text input/select box plugin",
  "main": "./public/assets/scripts/choices.js",
  "module": "./public/assets/scripts/choices.mjs",
  "unpkg": "./public/assets/scripts/choices.js",
  "jsdelivr": "./public/assets/scripts/choices.js",
  "types": "./public/types/src/index.d.ts",
  "exports": {
    ".": {
      "types": "./public/types/src/index.d.ts",
      "import": "./public/assets/scripts/choices.mjs",
      "require": "./public/assets/scripts/choices.js",
      "style": "./public/assets/styles/choices.css",
      "sass": "./src/styles/choices.scss"
    },
    "./search-basic": {
      "types": "./public/types/src/index.d.ts",
      "import": "./public/assets/scripts/choices.search-basic.mjs",
      "require": "./public/assets/scripts/choices.search-basic.min.js"
    },
    "./search-prefix": {
      "types": "./public/types/src/index.d.ts",
      "import": "./public/assets/scripts/choices.search-prefix.mjs",
      "require": "./public/assets/scripts/choices.search-prefix.min.js"
    },
    "./search-kmp": {
      "types": "./public/types/src/index.d.ts",
      "import": "./public/assets/scripts/choices.search-kmp.mjs",
      "require": "./public/assets/scripts/choices.search-kmp.min.js"
    },
    "./search-none": {
      "types": "./public/types/src/index.d.ts",
      "import": "./public/assets/scripts/choices.search-none.mjs",
      "require": "./public/assets/scripts/choices.search-none.min.js"
    },
    "./public/assets/styles/*.css": "./public/assets/styles/*.css",
    "./src/styles/*.scss": "./src/styles/*.scss",
    "./src/styles/*": "./src/styles/*.scss"
  },
  "sideEffects": [
    "*.scss",
    "*.css"
  ],
  "scripts": {
    "start": "run-p js:watch css:watch",
    "build": "run-p js:build css:build",
    "lint": "run-p lint:js lint:scss",
    "lint:js": "eslint src/scripts test/scripts test-e2e",
    "lint:scss": "stylelint src/**/*.scss",
    "bundlesize": "bundlesize",
    "playwright:cli": "playwright test --project=chromium",
    "playwright:gui": "playwright test --ui  --project=chromium",
    "test": "run-s test:unit test:e2e:all",
    "test:unit": "vitest run",
    "test:unit:watch": "npm run test:unit -- --watch --inspect=5556",
    "test:unit:coverage": "vitest run --coverage",
    "test:e2e": "run-s playwright:cli",
    "test:e2e:all": "playwright test",
    "js:watch": "rollup -w --bundleConfigAsCjs -c scripts/rollup.config.mjs --environment TARGET:. --environment OUTPUT_TYPES:umd --environment WATCH_HOST:localhost",
    "js:build": "rollup --bundleConfigAsCjs -c scripts/rollup.config.mjs --environment WITH_D_TS_FILES:1 && mv public/assets/scripts/src public/types/",
    "js:build-dev": "rollup --bundleConfigAsCjs -c scripts/rollup.config.mjs --environment TARGET:. --environment OUTPUT_TYPES:umd",
    "js:build-dev:esm": "rollup --bundleConfigAsCjs -c scripts/rollup.config.mjs --environment TARGET:. --environment OUTPUT_TYPES:mjs",
    "css:watch": "nodemon -e scss -x \"npm run css:build\"",
    "css:build": "run-s css:sass css:prefix css:min",
    "css:sass": "sass -I scss src/styles/base.scss public/assets/styles/base.css && sass -I scss src/styles/choices.scss public/assets/styles/choices.css",
    "css:prefix": "postcss public/assets/styles/*.css --use autoprefixer --no-map --env prod --dir public/assets/styles",
    "css:min": "csso public/assets/styles/base.css --output public/assets/styles/base.min.css && csso public/assets/styles/choices.css --output public/assets/styles/choices.min.css",
    "prepublishOnly": "npm run build"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/Choices-js/Choices.git"
  },
  "author": "Josh Johnson",
  "license": "MIT",
  "files": [
    "public/assets/scripts",
    "public/assets/styles",
    "public/types",
    "src"
  ],
  "bugs": {
    "url": "https://github.com/Choices-js/Choices/issues"
  },
  "homepage": "https://github.com/Choices-js/Choices#readme",
  "keywords": [
    "customisable",
    "input",
    "select",
    "vanilla",
    "plugin",
    "js"
  ],
  "devDependencies": {
    "@babel/cli": "^7.24.8",
    "@babel/core": "^7.25.2",
    "@babel/plugin-transform-object-rest-spread": "^7.24.7",
    "@babel/preset-env": "^7.25.3",
    "@babel/preset-typescript": "^7.24.7",
    "@playwright/test": "^1.46.0",
    "@rollup/plugin-babel": "^6.0.4",
    "@rollup/plugin-node-resolve": "^15.2.3",
    "@rollup/plugin-replace": "^5.0.7",
    "@rollup/plugin-terser": "^1.0.0",
    "@rollup/plugin-typescript": "^11.1.6",
    "@types/chai": "^4.3.17",
    "@types/node": "^22.12.0",
    "@types/sinon": "^17.0.3",
    "@types/sinon-chai": "^3.2.12",
    "@vitest/coverage-v8": "^3.2.4",
    "autoprefixer": "^10.4.20",
    "bundlesize2": "^0.0.35",
    "chai": "^5.1.1",
    "cross-process-lock": "^2.1.1",
    "csso-cli": "^4.0.2",
    "eslint": "^8.57.0",
    "eslint-config-airbnb-base": "^15.0.0",
    "eslint-config-airbnb-typescript": "^18.0.0",
    "eslint-config-prettier": "^9.1.0",
    "eslint-plugin-compat": "6.0.0",
    "eslint-plugin-import": "^2.29.1",
    "eslint-plugin-prettier": "^5.2.1",
    "eslint-plugin-sort-class-members": "^1.20.0",
    "eslint-plugin-tree-shaking": "^1.12.2",
    "jsdom": "^24.1.1",
    "nodemon": "^3.1.4",
    "npm-run-all": "^4.1.5",
    "postcss": "^8.4.41",
    "postcss-cli": "^11.0.0",
    "prettier": "^3.3.3",
    "rollup": "^4.20.0",
    "rollup-plugin-dev": "^2.0.5",
    "sass": "^1.77.8",
    "sinon": "^18.0.0",
    "sinon-chai": "^4.0.0",
    "stylelint": "^16.7.0",
    "stylelint-config-standard": "^36.0.1",
    "stylelint-config-standard-scss": "^13.1.0",
    "tslib": "^2.6.3",
    "typescript": "5.5.x",
    "typescript-eslint": "^8.0.1",
    "vitest": "^3.2.4"
  },
  "dependencies": {
    "fuse.js": "^7.0.0"
  },
  "npmName": "choices.js",
  "npmFileMap": [
    {
      "files": [
        "public/assets/scripts/*",
        "public/assets/styles/*",
        "public/types/*",
        "src/icons/*"
      ]
    }
  ],
  "bundlesize": [
    {
      "path": "public/assets/scripts/choices*.min.js",
      "maxSize": "25 kB"
    },
    {
      "path": "public/assets/styles/choices.min.css",
      "maxSize": "2.5 kB"
    }
  ]
}


================================================
FILE: playwright.config.ts
================================================
import { defineConfig, devices } from '@playwright/test';
import { PlaywrightTestConfig } from 'playwright/types/test';
import { BundleTest } from './test-e2e/bundle-test';

/**
 * Read environment variables from file.
 * https://github.com/motdotla/dotenv
 */
// import dotenv from 'dotenv';
// dotenv.config({ path: path.resolve(__dirname, '.env') });

/**
 * See https://playwright.dev/docs/test-configuration.
 */
const config: PlaywrightTestConfig = {
  testDir: './test-e2e',
  snapshotPathTemplate: '{testDir}/__screenshots__/{projectName}-{platform}{ext}',
  /* Run tests in files in parallel */
  fullyParallel: true,
  /* Fail the build on CI if you accidentally left test.only in the source code. */
  forbidOnly: !!process.env.CI,
  /* Retry on CI only */
  retries: 0,
  /* Opt out of parallel tests on CI. */
  workers: process.env.CI ? 1 : undefined,
  /* Reporter to use. See https://playwright.dev/docs/test-reporters */
  reporter: process.env.CI ? [['github'], ['html', { open: 'never' }]] : 'line',
  timeout: process.env.CI ? 5000 : 1000,
  expect : {
    timeout: process.env.CI ? 1000 : 500,
  },
  /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
  use: {
    /* Base URL to use in actions like `await page.goto('/')`. */
    baseURL: 'http://localhost:3001/',

    /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
    trace: 'on-first-retry',

    testIdAttribute: 'data-test-hook',
  },

  /* Configure projects for major browsers */
  projects: [
    {
      name: 'chromium',
      use: {
        ...devices['Desktop Chrome'],
        contextOptions: {
          // chromium-specific permissions
          permissions: ['clipboard-read', 'clipboard-write'],
        },
      },
    },
    {
      name: 'firefox',
      use: { ...devices['Desktop Firefox'] },
    },
    {
      name: 'webkit',
      use: { ...devices['Desktop Safari'] },
    },

    /* Test against mobile viewports. */
    // {
    //   name: 'Mobile Chrome',
    //   use: { ...devices['Pixel 5'] },
    // },
    // {
    //   name: 'Mobile Safari',
    //   use: { ...devices['iPhone 12'] },
    // },

    /* Test against branded browsers. */
    // {
    //   name: 'Microsoft Edge',
    //   use: { ...devices['Desktop Edge'], channel: 'msedge' },
    // },
    // {
    //   name: 'Google Chrome',
    //   use: { ...devices['Desktop Chrome'], channel: 'chrome' },
    // },
  ],

  /* Run your local dev server before starting the tests */
  webServer: {
    command: 'npm run start',
    url: 'http://localhost:3001',
    reuseExistingServer: !process.env.CI,
  },
};

const bundles = [
  {
    name: '',
    bundle: process.env.CI ? '/assets/scripts/choices.min.js' : '/assets/scripts/choices.js',
    enabled: true,
  },
];
const projects = config.projects;
if (config.use.baseURL) {
  config.projects = [];

  projects.forEach((project) => {
    bundles.forEach(({ name, bundle, enabled }) => {
      if (!enabled) {
        return;
      }
      const projectBundle = {
        ...project,
        name: project.name + name,
        use: {
          ...project.use,
          bundle: config.use.baseURL + bundle,
        }
      };
      config.projects.push(projectBundle);
    });
  });
}

export default defineConfig<BundleTest>(config);

================================================
FILE: public/assets/images/browserconfig.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
  <msapplication>
    <tile>
      <square150x150logo src="/assets/images/mstile-150x150.png"/>
      <TileColor>#ffffff</TileColor>
    </tile>
  </msapplication>
</browserconfig>


================================================
FILE: public/assets/images/manifest.json
================================================
{
	"name": "Choices.js",
	"icons": [
		{
			"src": "\/assets\/images\/android-chrome-192x192.png",
			"sizes": "192x192",
			"type": "image\/png"
		}
	],
	"theme_color": "#ffffff",
	"display": "standalone"
}


================================================
FILE: public/assets/scripts/choices.js
================================================
/*! choices.js v11.2.1 | © 2026 Josh Johnson | https://github.com/Choices-js/Choices#readme */

(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
    typeof define === 'function' && define.amd ? define(factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Choices = factory());
})(this, (function () { 'use strict';

    /******************************************************************************
    Copyright (c) Microsoft Corporation.

    Permission to use, copy, modify, and/or distribute this software for any
    purpose with or without fee is hereby granted.

    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
    REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
    AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
    INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
    LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
    OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
    PERFORMANCE OF THIS SOFTWARE.
    ***************************************************************************** */
    /* global Reflect, Promise, SuppressedError, Symbol */

    var extendStatics = function (d, b) {
      extendStatics = Object.setPrototypeOf || {
        __proto__: []
      } instanceof Array && function (d, b) {
        d.__proto__ = b;
      } || function (d, b) {
        for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];
      };
      return extendStatics(d, b);
    };
    function __extends(d, b) {
      if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
      extendStatics(d, b);
      function __() {
        this.constructor = d;
      }
      d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    }
    var __assign = function () {
      __assign = Object.assign || function __assign(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
          s = arguments[i];
          for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
        }
        return t;
      };
      return __assign.apply(this, arguments);
    };
    function __spreadArray(to, from, pack) {
      if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
          if (!ar) ar = Array.prototype.slice.call(from, 0, i);
          ar[i] = from[i];
        }
      }
      return to.concat(ar || Array.prototype.slice.call(from));
    }
    typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
      var e = new Error(message);
      return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
    };

    var ActionType = {
        ADD_CHOICE: 'ADD_CHOICE',
        REMOVE_CHOICE: 'REMOVE_CHOICE',
        FILTER_CHOICES: 'FILTER_CHOICES',
        ACTIVATE_CHOICES: 'ACTIVATE_CHOICES',
        CLEAR_CHOICES: 'CLEAR_CHOICES',
        ADD_GROUP: 'ADD_GROUP',
        ADD_ITEM: 'ADD_ITEM',
        REMOVE_ITEM: 'REMOVE_ITEM',
        HIGHLIGHT_ITEM: 'HIGHLIGHT_ITEM',
    };

    var EventType = {
        showDropdown: 'showDropdown',
        hideDropdown: 'hideDropdown',
        change: 'change',
        choice: 'choice',
        search: 'search',
        addItem: 'addItem',
        removeItem: 'removeItem',
        highlightItem: 'highlightItem',
        highlightChoice: 'highlightChoice',
        unhighlightItem: 'unhighlightItem',
    };

    var KeyCodeMap = {
        TAB_KEY: 9,
        SHIFT_KEY: 16,
        BACK_KEY: 46,
        DELETE_KEY: 8,
        ENTER_KEY: 13,
        A_KEY: 65,
        ESC_KEY: 27,
        UP_KEY: 38,
        DOWN_KEY: 40,
        PAGE_UP_KEY: 33,
        PAGE_DOWN_KEY: 34,
    };

    var ObjectsInConfig = ['fuseOptions', 'classNames'];

    var PassedElementTypes = {
        Text: 'text',
        SelectOne: 'select-one',
        SelectMultiple: 'select-multiple',
    };

    var addChoice = function (choice) { return ({
        type: ActionType.ADD_CHOICE,
        choice: choice,
    }); };
    var removeChoice = function (choice) { return ({
        type: ActionType.REMOVE_CHOICE,
        choice: choice,
    }); };
    var filterChoices = function (results) { return ({
        type: ActionType.FILTER_CHOICES,
        results: results,
    }); };
    var activateChoices = function (active) {
        return ({
            type: ActionType.ACTIVATE_CHOICES,
            active: active,
        });
    };

    var addGroup = function (group) { return ({
        type: ActionType.ADD_GROUP,
        group: group,
    }); };

    var addItem = function (item) { return ({
        type: ActionType.ADD_ITEM,
        item: item,
    }); };
    var removeItem$1 = function (item) { return ({
        type: ActionType.REMOVE_ITEM,
        item: item,
    }); };
    var highlightItem = function (item, highlighted) { return ({
        type: ActionType.HIGHLIGHT_ITEM,
        item: item,
        highlighted: highlighted,
    }); };

    var getRandomNumber = function (min, max) { return Math.floor(Math.random() * (max - min) + min); };
    var generateChars = function (length) {
        return Array.from({ length: length }, function () { return getRandomNumber(0, 36).toString(36); }).join('');
    };
    var generateId = function (element, prefix) {
        var id = element.id || (element.name && "".concat(element.name, "-").concat(generateChars(2))) || generateChars(4);
        id = id.replace(/(:|\.|\[|\]|,)/g, '');
        id = "".concat(prefix, "-").concat(id);
        return id;
    };
    var getAdjacentEl = function (startEl, selector, direction) {
        if (direction === void 0) { direction = 1; }
        var prop = "".concat(direction > 0 ? 'next' : 'previous', "ElementSibling");
        var sibling = startEl[prop];
        while (sibling) {
            if (sibling.matches(selector)) {
                return sibling;
            }
            sibling = sibling[prop];
        }
        return null;
    };
    var isScrolledIntoView = function (element, parent, direction) {
        if (direction === void 0) { direction = 1; }
        var isVisible;
        if (direction > 0) {
            // In view from bottom
            isVisible = parent.scrollTop + parent.offsetHeight >= element.offsetTop + element.offsetHeight;
        }
        else {
            // In view from top
            isVisible = element.offsetTop >= parent.scrollTop;
        }
        return isVisible;
    };
    var sanitise = function (value) {
        if (typeof value !== 'string') {
            if (value === null || value === undefined) {
                return '';
            }
            if (typeof value === 'object') {
                if ('raw' in value) {
                    return sanitise(value.raw);
                }
                if ('trusted' in value) {
                    return value.trusted;
                }
            }
            return value;
        }
        return value
            .replace(/&/g, '&amp;')
            .replace(/>/g, '&gt;')
            .replace(/</g, '&lt;')
            .replace(/'/g, '&#039;')
            .replace(/"/g, '&quot;');
    };
    var strToEl = (function () {
        var tmpEl = document.createElement('div');
        return function (str) {
            tmpEl.innerHTML = str.trim();
            var firstChild = tmpEl.children[0];
            while (tmpEl.firstChild) {
                tmpEl.removeChild(tmpEl.firstChild);
            }
            return firstChild;
        };
    })();
    var resolveStringFunction = function (fn) {
        return typeof fn === 'function' ? fn() : fn;
    };
    var unwrapStringForRaw = function (s) {
        if (typeof s === 'string') {
            return s;
        }
        if (typeof s === 'object') {
            if ('trusted' in s) {
                return s.trusted;
            }
            if ('raw' in s) {
                return s.raw;
            }
        }
        return '';
    };
    var unwrapStringForEscaped = function (s) {
        if (typeof s === 'string') {
            return s;
        }
        if (typeof s === 'object') {
            if ('escaped' in s) {
                return s.escaped;
            }
            if ('trusted' in s) {
                return s.trusted;
            }
        }
        return '';
    };
    var getChoiceForOutput = function (choice, keyCode) {
        return {
            id: choice.id,
            highlighted: choice.highlighted,
            labelClass: choice.labelClass,
            labelDescription: unwrapStringForRaw(choice.labelDescription),
            customProperties: choice.customProperties,
            disabled: choice.disabled,
            active: choice.active,
            label: choice.label,
            placeholder: choice.placeholder,
            value: choice.value,
            groupValue: choice.group ? choice.group.label : undefined,
            element: choice.element,
            keyCode: keyCode,
        };
    };
    var resolveNoticeFunction = function (fn, value, item) {
        return typeof fn === 'function' ? fn(sanitise(value), unwrapStringForRaw(value), item) : fn;
    };
    var escapeForTemplate = function (allowHTML, s) {
        return allowHTML ? unwrapStringForEscaped(s) : sanitise(s);
    };
    var setElementHtml = function (el, allowHtml, html) {
        el.innerHTML = escapeForTemplate(allowHtml, html);
    };
    var sortByAlpha = function (_a, _b) {
        var value = _a.value, _c = _a.label, label = _c === void 0 ? value : _c;
        var value2 = _b.value, _d = _b.label, label2 = _d === void 0 ? value2 : _d;
        return unwrapStringForRaw(label).localeCompare(unwrapStringForRaw(label2), [], {
            sensitivity: 'base',
            ignorePunctuation: true,
            numeric: true,
        });
    };
    var sortByRank = function (a, b) {
        return a.rank - b.rank;
    };
    var dispatchEvent = function (element, type, customArgs) {
        if (customArgs === void 0) { customArgs = null; }
        var event = new CustomEvent(type, {
            detail: customArgs,
            bubbles: true,
            cancelable: true,
        });
        return element.dispatchEvent(event);
    };
    /**
     * Returns an array of keys present on the first but missing on the second object
     */
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    var diff = function (a, b) {
        var aKeys = Object.keys(a).sort();
        var bKeys = Object.keys(b).sort();
        return aKeys.filter(function (i) { return bKeys.indexOf(i) < 0; });
    };
    var getClassNames = function (ClassNames) {
        return Array.isArray(ClassNames) ? ClassNames : [ClassNames];
    };
    var getClassNamesSelector = function (option) {
        if (option && Array.isArray(option)) {
            return option
                .map(function (item) {
                return ".".concat(item);
            })
                .join('');
        }
        return ".".concat(option);
    };
    var addClassesToElement = function (element, className) {
        var _a;
        (_a = element.classList).add.apply(_a, getClassNames(className));
    };
    var removeClassesFromElement = function (element, className) {
        var _a;
        (_a = element.classList).remove.apply(_a, getClassNames(className));
    };
    var parseCustomProperties = function (customProperties) {
        if (typeof customProperties !== 'undefined') {
            try {
                return JSON.parse(customProperties);
            }
            catch (e) {
                return customProperties;
            }
        }
        return {};
    };
    var updateClassList = function (item, add, remove) {
        var itemEl = item.itemEl;
        if (itemEl) {
            removeClassesFromElement(itemEl, remove);
            addClassesToElement(itemEl, add);
        }
    };

    var Dropdown = /** @class */ (function () {
        function Dropdown(_a) {
            var element = _a.element, type = _a.type, classNames = _a.classNames;
            this.element = element;
            this.classNames = classNames;
            this.type = type;
            this.isActive = false;
        }
        /**
         * Show dropdown to user by adding active state class
         */
        Dropdown.prototype.show = function () {
            addClassesToElement(this.element, this.classNames.activeState);
            this.element.setAttribute('aria-expanded', 'true');
            this.isActive = true;
            return this;
        };
        /**
         * Hide dropdown from user
         */
        Dropdown.prototype.hide = function () {
            removeClassesFromElement(this.element, this.classNames.activeState);
            this.element.setAttribute('aria-expanded', 'false');
            this.isActive = false;
            return this;
        };
        return Dropdown;
    }());

    var Container = /** @class */ (function () {
        function Container(_a) {
            var element = _a.element, type = _a.type, classNames = _a.classNames, position = _a.position;
            this.element = element;
            this.classNames = classNames;
            this.type = type;
            this.position = position;
            this.isOpen = false;
            this.isFlipped = false;
            this.isDisabled = false;
            this.isLoading = false;
        }
        /**
         * Determine whether container should be flipped based on passed
         * dropdown position
         */
        Container.prototype.shouldFlip = function (dropdownPos, dropdownHeight) {
            // If flip is enabled and the dropdown bottom position is
            // greater than the window height flip the dropdown.
            var shouldFlip = false;
            if (this.position === 'auto') {
                shouldFlip =
                    this.element.getBoundingClientRect().top - dropdownHeight >= 0 &&
                        !window.matchMedia("(min-height: ".concat(dropdownPos + 1, "px)")).matches;
            }
            else if (this.position === 'top') {
                shouldFlip = true;
            }
            return shouldFlip;
        };
        Container.prototype.setActiveDescendant = function (activeDescendantID) {
            this.element.setAttribute('aria-activedescendant', activeDescendantID);
        };
        Container.prototype.removeActiveDescendant = function () {
            this.element.removeAttribute('aria-activedescendant');
        };
        Container.prototype.open = function (dropdownPos, dropdownHeight) {
            addClassesToElement(this.element, this.classNames.openState);
            this.element.setAttribute('aria-expanded', 'true');
            this.isOpen = true;
            if (this.shouldFlip(dropdownPos, dropdownHeight)) {
                addClassesToElement(this.element, this.classNames.flippedState);
                this.isFlipped = true;
            }
        };
        Container.prototype.close = function () {
            removeClassesFromElement(this.element, this.classNames.openState);
            this.element.setAttribute('aria-expanded', 'false');
            this.removeActiveDescendant();
            this.isOpen = false;
            // A dropdown flips if it does not have space within the page
            if (this.isFlipped) {
                removeClassesFromElement(this.element, this.classNames.flippedState);
                this.isFlipped = false;
            }
        };
        Container.prototype.addFocusState = function () {
            addClassesToElement(this.element, this.classNames.focusState);
        };
        Container.prototype.removeFocusState = function () {
            removeClassesFromElement(this.element, this.classNames.focusState);
        };
        Container.prototype.addInvalidState = function () {
            addClassesToElement(this.element, this.classNames.invalidState);
        };
        Container.prototype.removeInvalidState = function () {
            removeClassesFromElement(this.element, this.classNames.invalidState);
        };
        Container.prototype.enable = function () {
            removeClassesFromElement(this.element, this.classNames.disabledState);
            this.element.removeAttribute('aria-disabled');
            if (this.type === PassedElementTypes.SelectOne) {
                this.element.setAttribute('tabindex', '0');
            }
            this.isDisabled = false;
        };
        Container.prototype.disable = function () {
            addClassesToElement(this.element, this.classNames.disabledState);
            this.element.setAttribute('aria-disabled', 'true');
            if (this.type === PassedElementTypes.SelectOne) {
                this.element.setAttribute('tabindex', '-1');
            }
            this.isDisabled = true;
        };
        Container.prototype.wrap = function (element) {
            var el = this.element;
            var parentNode = element.parentNode;
            if (parentNode) {
                if (element.nextSibling) {
                    parentNode.insertBefore(el, element.nextSibling);
                }
                else {
                    parentNode.appendChild(el);
                }
            }
            el.appendChild(element);
        };
        Container.prototype.unwrap = function (element) {
            var el = this.element;
            var parentNode = el.parentNode;
            if (parentNode) {
                // Move passed element outside this element
                parentNode.insertBefore(element, el);
                // Remove this element
                parentNode.removeChild(el);
            }
        };
        Container.prototype.addLoadingState = function () {
            addClassesToElement(this.element, this.classNames.loadingState);
            this.element.setAttribute('aria-busy', 'true');
            this.isLoading = true;
        };
        Container.prototype.removeLoadingState = function () {
            removeClassesFromElement(this.element, this.classNames.loadingState);
            this.element.removeAttribute('aria-busy');
            this.isLoading = false;
        };
        return Container;
    }());

    var Input = /** @class */ (function () {
        function Input(_a) {
            var element = _a.element, type = _a.type, classNames = _a.classNames, preventPaste = _a.preventPaste;
            this.element = element;
            this.type = type;
            this.classNames = classNames;
            this.preventPaste = preventPaste;
            this.isFocussed = this.element.isEqualNode(document.activeElement);
            this.isDisabled = element.disabled;
            this._onPaste = this._onPaste.bind(this);
            this._onInput = this._onInput.bind(this);
            this._onFocus = this._onFocus.bind(this);
            this._onBlur = this._onBlur.bind(this);
        }
        Object.defineProperty(Input.prototype, "placeholder", {
            set: function (placeholder) {
                this.element.placeholder = placeholder;
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(Input.prototype, "value", {
            get: function () {
                return this.element.value;
            },
            set: function (value) {
                this.element.value = value;
            },
            enumerable: false,
            configurable: true
        });
        Input.prototype.addEventListeners = function () {
            var el = this.element;
            el.addEventListener('paste', this._onPaste);
            el.addEventListener('input', this._onInput, {
                passive: true,
            });
            el.addEventListener('focus', this._onFocus, {
                passive: true,
            });
            el.addEventListener('blur', this._onBlur, {
                passive: true,
            });
        };
        Input.prototype.removeEventListeners = function () {
            var el = this.element;
            el.removeEventListener('input', this._onInput);
            el.removeEventListener('paste', this._onPaste);
            el.removeEventListener('focus', this._onFocus);
            el.removeEventListener('blur', this._onBlur);
        };
        Input.prototype.enable = function () {
            var el = this.element;
            el.removeAttribute('disabled');
            this.isDisabled = false;
        };
        Input.prototype.disable = function () {
            var el = this.element;
            el.setAttribute('disabled', '');
            this.isDisabled = true;
        };
        Input.prototype.focus = function () {
            if (!this.isFocussed) {
                this.element.focus();
            }
        };
        Input.prototype.blur = function () {
            if (this.isFocussed) {
                this.element.blur();
            }
        };
        Input.prototype.clear = function (setWidth) {
            if (setWidth === void 0) { setWidth = true; }
            this.element.value = '';
            if (setWidth) {
                this.setWidth();
            }
            return this;
        };
        /**
         * Set the correct input width based on placeholder
         * value or input value
         */
        Input.prototype.setWidth = function () {
            // Resize input to contents or placeholder
            var element = this.element;
            element.style.minWidth = "".concat(element.placeholder.length + 1, "ch");
            element.style.width = "".concat(element.value.length + 1, "ch");
        };
        Input.prototype.setActiveDescendant = function (activeDescendantID) {
            this.element.setAttribute('aria-activedescendant', activeDescendantID);
        };
        Input.prototype.removeActiveDescendant = function () {
            this.element.removeAttribute('aria-activedescendant');
        };
        Input.prototype._onInput = function () {
            if (this.type !== PassedElementTypes.SelectOne) {
                this.setWidth();
            }
        };
        Input.prototype._onPaste = function (event) {
            if (this.preventPaste) {
                event.preventDefault();
            }
        };
        Input.prototype._onFocus = function () {
            this.isFocussed = true;
        };
        Input.prototype._onBlur = function () {
            this.isFocussed = false;
        };
        return Input;
    }());

    var SCROLLING_SPEED = 4;

    var List = /** @class */ (function () {
        function List(_a) {
            var element = _a.element;
            this.element = element;
            this.scrollPos = this.element.scrollTop;
            this.height = this.element.offsetHeight;
        }
        List.prototype.prepend = function (node) {
            var child = this.element.firstElementChild;
            if (child) {
                this.element.insertBefore(node, child);
            }
            else {
                this.element.append(node);
            }
        };
        List.prototype.scrollToTop = function () {
            this.element.scrollTop = 0;
        };
        List.prototype.scrollToChildElement = function (element, direction) {
            var _this = this;
            if (!element) {
                return;
            }
            var listHeight = this.element.offsetHeight;
            // Scroll position of dropdown
            var listScrollPosition = this.element.scrollTop + listHeight;
            var elementHeight = element.offsetHeight;
            // Distance from bottom of element to top of parent
            var elementPos = element.offsetTop + elementHeight;
            // Difference between the element and scroll position
            var destination = direction > 0 ? this.element.scrollTop + elementPos - listScrollPosition : element.offsetTop;
            requestAnimationFrame(function () {
                _this._animateScroll(destination, direction);
            });
        };
        List.prototype._scrollDown = function (scrollPos, strength, destination) {
            var easing = (destination - scrollPos) / strength;
            var distance = easing > 1 ? easing : 1;
            this.element.scrollTop = scrollPos + distance;
        };
        List.prototype._scrollUp = function (scrollPos, strength, destination) {
            var easing = (scrollPos - destination) / strength;
            var distance = easing > 1 ? easing : 1;
            this.element.scrollTop = scrollPos - distance;
        };
        List.prototype._animateScroll = function (destination, direction) {
            var _this = this;
            var strength = SCROLLING_SPEED;
            var choiceListScrollTop = this.element.scrollTop;
            var continueAnimation = false;
            if (direction > 0) {
                this._scrollDown(choiceListScrollTop, strength, destination);
                if (choiceListScrollTop < destination) {
                    continueAnimation = true;
                }
            }
            else {
                this._scrollUp(choiceListScrollTop, strength, destination);
                if (choiceListScrollTop > destination) {
                    continueAnimation = true;
                }
            }
            if (continueAnimation) {
                requestAnimationFrame(function () {
                    _this._animateScroll(destination, direction);
                });
            }
        };
        return List;
    }());

    var WrappedElement = /** @class */ (function () {
        function WrappedElement(_a) {
            var element = _a.element, classNames = _a.classNames;
            this.element = element;
            this.classNames = classNames;
            this.isDisabled = false;
        }
        Object.defineProperty(WrappedElement.prototype, "isActive", {
            get: function () {
                return this.element.dataset.choice === 'active';
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(WrappedElement.prototype, "dir", {
            get: function () {
                return this.element.dir;
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(WrappedElement.prototype, "value", {
            get: function () {
                return this.element.value;
            },
            set: function (value) {
                this.element.setAttribute('value', value);
                this.element.value = value;
            },
            enumerable: false,
            configurable: true
        });
        WrappedElement.prototype.conceal = function () {
            var el = this.element;
            // Hide passed input
            addClassesToElement(el, this.classNames.input);
            el.hidden = true;
            // Remove element from tab index
            el.tabIndex = -1;
            // Backup original styles if any
            var origStyle = el.getAttribute('style');
            if (origStyle) {
                el.setAttribute('data-choice-orig-style', origStyle);
            }
            el.setAttribute('data-choice', 'active');
        };
        WrappedElement.prototype.reveal = function () {
            var el = this.element;
            // Reinstate passed element
            removeClassesFromElement(el, this.classNames.input);
            el.hidden = false;
            el.removeAttribute('tabindex');
            // Recover original styles if any
            var origStyle = el.getAttribute('data-choice-orig-style');
            if (origStyle) {
                el.removeAttribute('data-choice-orig-style');
                el.setAttribute('style', origStyle);
            }
            else {
                el.removeAttribute('style');
            }
            el.removeAttribute('data-choice');
        };
        WrappedElement.prototype.enable = function () {
            this.element.removeAttribute('disabled');
            this.element.disabled = false;
            this.isDisabled = false;
        };
        WrappedElement.prototype.disable = function () {
            this.element.setAttribute('disabled', '');
            this.element.disabled = true;
            this.isDisabled = true;
        };
        WrappedElement.prototype.triggerEvent = function (eventType, data) {
            dispatchEvent(this.element, eventType, data || {});
        };
        return WrappedElement;
    }());

    var WrappedInput = /** @class */ (function (_super) {
        __extends(WrappedInput, _super);
        function WrappedInput() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        return WrappedInput;
    }(WrappedElement));

    var coerceBool = function (arg, defaultValue) {
        if (defaultValue === void 0) { defaultValue = true; }
        return typeof arg === 'undefined' ? defaultValue : !!arg;
    };
    var stringToHtmlClass = function (input) {
        if (typeof input === 'string') {
            // eslint-disable-next-line no-param-reassign
            input = input.split(' ').filter(function (s) { return s.length; });
        }
        if (Array.isArray(input) && input.length) {
            return input;
        }
        return undefined;
    };
    var mapInputToChoice = function (value, allowGroup, allowRawString) {
        if (allowRawString === void 0) { allowRawString = true; }
        if (typeof value === 'string') {
            var sanitisedValue = sanitise(value);
            var userValue = allowRawString || sanitisedValue === value ? value : { escaped: sanitisedValue, raw: value };
            var result_1 = mapInputToChoice({
                value: value,
                label: userValue,
                selected: true,
            }, false);
            return result_1;
        }
        var groupOrChoice = value;
        if ('choices' in groupOrChoice) {
            if (!allowGroup) {
                // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/optgroup
                throw new TypeError("optGroup is not allowed");
            }
            var group = groupOrChoice;
            var choices = group.choices.map(function (e) { return mapInputToChoice(e, false); });
            var result_2 = {
                id: 0, // actual ID will be assigned during _addGroup
                label: unwrapStringForRaw(group.label) || group.value,
                active: !!choices.length,
                disabled: !!group.disabled,
                choices: choices,
            };
            return result_2;
        }
        var choice = groupOrChoice;
        var result = {
            id: 0, // actual ID will be assigned during _addChoice
            group: null, // actual group will be assigned during _addGroup but before _addChoice
            score: 0, // used in search
            rank: 0, // used in search, stable sort order
            value: choice.value,
            label: choice.label || choice.value,
            active: coerceBool(choice.active),
            selected: coerceBool(choice.selected, false),
            disabled: coerceBool(choice.disabled, false),
            placeholder: coerceBool(choice.placeholder, false),
            highlighted: false,
            labelClass: stringToHtmlClass(choice.labelClass),
            labelDescription: choice.labelDescription,
            customProperties: choice.customProperties,
        };
        return result;
    };

    var isHtmlInputElement = function (e) { return e.tagName === 'INPUT'; };
    var isHtmlSelectElement = function (e) { return e.tagName === 'SELECT'; };
    var isHtmlOption = function (e) { return e.tagName === 'OPTION'; };
    var isHtmlOptgroup = function (e) { return e.tagName === 'OPTGROUP'; };

    var WrappedSelect = /** @class */ (function (_super) {
        __extends(WrappedSelect, _super);
        function WrappedSelect(_a) {
            var element = _a.element, classNames = _a.classNames, template = _a.template, extractPlaceholder = _a.extractPlaceholder;
            var _this = _super.call(this, { element: element, classNames: classNames }) || this;
            _this.template = template;
            _this.extractPlaceholder = extractPlaceholder;
            return _this;
        }
        Object.defineProperty(WrappedSelect.prototype, "placeholderOption", {
            get: function () {
                return (this.element.querySelector('option[value=""]') ||
                    // Backward compatibility layer for the non-standard placeholder attribute supported in older versions.
                    this.element.querySelector('option[placeholder]'));
            },
            enumerable: false,
            configurable: true
        });
        WrappedSelect.prototype.addOptions = function (choices) {
            var _this = this;
            var fragment = document.createDocumentFragment();
            choices.forEach(function (obj) {
                var choice = obj;
                if (choice.element) {
                    return;
                }
                var option = _this.template(choice);
                fragment.appendChild(option);
                choice.element = option;
            });
            this.element.appendChild(fragment);
        };
        WrappedSelect.prototype.optionsAsChoices = function () {
            var _this = this;
            var choices = [];
            this.element.querySelectorAll(':scope > option, :scope > optgroup').forEach(function (e) {
                if (isHtmlOption(e)) {
                    choices.push(_this._optionToChoice(e));
                }
                else if (isHtmlOptgroup(e)) {
                    choices.push(_this._optgroupToChoice(e));
                }
                // todo: hr as empty optgroup, requires displaying empty opt-groups to be useful
            });
            return choices;
        };
        // eslint-disable-next-line class-methods-use-this
        WrappedSelect.prototype._optionToChoice = function (option) {
            // option.value returns the label if there is no value attribute, which can break legacy placeholder attribute support
            if (!option.hasAttribute('value') && option.hasAttribute('placeholder')) {
                option.setAttribute('value', '');
                option.value = '';
            }
            return {
                id: 0,
                group: null,
                score: 0,
                rank: 0,
                value: option.value,
                // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option
                // This attribute is text for the label indicating the meaning of the option. If the `label` attribute isn't defined, its value is that of the element text content (ie `innerText`).
                label: option.label,
                element: option,
                active: true,
                // this returns true if nothing is selected on initial load, which will break placeholder support
                selected: this.extractPlaceholder ? option.selected : option.hasAttribute('selected'),
                disabled: option.disabled,
                highlighted: false,
                placeholder: this.extractPlaceholder && (!option.value || option.hasAttribute('placeholder')),
                labelClass: typeof option.dataset.labelClass !== 'undefined' ? stringToHtmlClass(option.dataset.labelClass) : undefined,
                labelDescription: typeof option.dataset.labelDescription !== 'undefined'
                    ? { trusted: option.dataset.labelDescription }
                    : undefined,
                customProperties: parseCustomProperties(option.dataset.customProperties),
            };
        };
        WrappedSelect.prototype._optgroupToChoice = function (optgroup) {
            var _this = this;
            var options = optgroup.querySelectorAll('option');
            var choices = Array.from(options).map(function (option) { return _this._optionToChoice(option); });
            return {
                id: 0,
                label: optgroup.label || '',
                element: optgroup,
                active: !!choices.length,
                disabled: optgroup.disabled,
                choices: choices,
            };
        };
        return WrappedSelect;
    }(WrappedElement));

    var DEFAULT_CLASSNAMES = {
        containerOuter: ['choices'],
        containerInner: ['choices__inner'],
        input: ['choices__input'],
        inputCloned: ['choices__input--cloned'],
        list: ['choices__list'],
        listItems: ['choices__list--multiple'],
        listSingle: ['choices__list--single'],
        listDropdown: ['choices__list--dropdown'],
        item: ['choices__item'],
        itemSelectable: ['choices__item--selectable'],
        itemDisabled: ['choices__item--disabled'],
        itemChoice: ['choices__item--choice'],
        description: ['choices__description'],
        placeholder: ['choices__placeholder'],
        group: ['choices__group'],
        groupHeading: ['choices__heading'],
        button: ['choices__button'],
        activeState: ['is-active'],
        focusState: ['is-focused'],
        openState: ['is-open'],
        disabledState: ['is-disabled'],
        highlightedState: ['is-highlighted'],
        selectedState: ['is-selected'],
        flippedState: ['is-flipped'],
        loadingState: ['is-loading'],
        invalidState: ['is-invalid'],
        notice: ['choices__notice'],
        addChoice: ['choices__item--selectable', 'add-choice'],
        noResults: ['has-no-results'],
        noChoices: ['has-no-choices'],
    };
    var DEFAULT_CONFIG = {
        items: [],
        choices: [],
        silent: false,
        renderChoiceLimit: -1,
        maxItemCount: -1,
        closeDropdownOnSelect: 'auto',
        singleModeForMultiSelect: false,
        addChoices: false,
        addItems: true,
        addItemFilter: function (value) { return !!value && value !== ''; },
        removeItems: true,
        removeItemButton: false,
        removeItemButtonAlignLeft: false,
        editItems: false,
        allowHTML: false,
        allowHtmlUserInput: false,
        duplicateItemsAllowed: true,
        delimiter: ',',
        paste: true,
        searchEnabled: true,
        searchChoices: true,
        searchDisabledChoices: false,
        searchFloor: 1,
        searchResultLimit: 4,
        searchFields: ['label', 'value'],
        position: 'auto',
        resetScrollPosition: true,
        shouldSort: true,
        shouldSortItems: false,
        sorter: sortByAlpha,
        shadowRoot: null,
        placeholder: true,
        placeholderValue: null,
        searchPlaceholderValue: null,
        prependValue: null,
        appendValue: null,
        renderSelectedChoices: 'auto',
        searchRenderSelectedChoices: true,
        loadingText: 'Loading...',
        noResultsText: 'No results found',
        noChoicesText: 'No choices to choose from',
        itemSelectText: 'Press to select',
        uniqueItemText: 'Only unique values can be added',
        customAddItemText: 'Only values matching specific conditions can be added',
        addItemText: function (value) { return "Press Enter to add <b>\"".concat(value, "\"</b>"); },
        removeItemIconText: function () { return "Remove item"; },
        removeItemLabelText: function (value, _valueRaw, i) {
            return "Remove item: ".concat(i ? sanitise(i.label) : value);
        },
        maxItemText: function (maxItemCount) { return "Only ".concat(maxItemCount, " values can be added"); },
        valueComparer: function (value1, value2) { return value1 === value2; },
        fuseOptions: {
            includeScore: true,
        },
        labelId: '',
        callbackOnInit: null,
        callbackOnCreateTemplates: null,
        classNames: DEFAULT_CLASSNAMES,
        appendGroupInSearch: false,
    };

    var removeItem = function (item) {
        var itemEl = item.itemEl;
        if (itemEl) {
            itemEl.remove();
            item.itemEl = undefined;
        }
    };
    function items(s, action, context) {
        var state = s;
        var update = true;
        switch (action.type) {
            case ActionType.ADD_ITEM: {
                action.item.selected = true;
                var el = action.item.element;
                if (el) {
                    el.selected = true;
                    el.setAttribute('selected', '');
                }
                state.push(action.item);
                break;
            }
            case ActionType.REMOVE_ITEM: {
                action.item.selected = false;
                var el = action.item.element;
                if (el) {
                    el.selected = false;
                    el.removeAttribute('selected');
                    // For a select-one, if all options are deselected, the first item is selected. To set a black value, select.value needs to be set
                    var select = el.parentElement;
                    if (select && isHtmlSelectElement(select) && select.type === PassedElementTypes.SelectOne) {
                        select.value = '';
                    }
                }
                // this is mixing concerns, but this is *so much faster*
                removeItem(action.item);
                state = state.filter(function (choice) { return choice.id !== action.item.id; });
                break;
            }
            case ActionType.REMOVE_CHOICE: {
                removeItem(action.choice);
                state = state.filter(function (item) { return item.id !== action.choice.id; });
                break;
            }
            case ActionType.HIGHLIGHT_ITEM: {
                var highlighted = action.highlighted;
                var item = state.find(function (obj) { return obj.id === action.item.id; });
                if (item && item.highlighted !== highlighted) {
                    item.highlighted = highlighted;
                    if (context) {
                        updateClassList(item, highlighted ? context.classNames.highlightedState : context.classNames.selectedState, highlighted ? context.classNames.selectedState : context.classNames.highlightedState);
                    }
                }
                break;
            }
            default: {
                update = false;
                break;
            }
        }
        return { state: state, update: update };
    }

    function groups(s, action) {
        var state = s;
        var update = true;
        switch (action.type) {
            case ActionType.ADD_GROUP: {
                state.push(action.group);
                break;
            }
            case ActionType.CLEAR_CHOICES: {
                state = [];
                break;
            }
            default: {
                update = false;
                break;
            }
        }
        return { state: state, update: update };
    }

    /* eslint-disable */
    function choices(s, action, context) {
        var state = s;
        var update = true;
        switch (action.type) {
            case ActionType.ADD_CHOICE: {
                state.push(action.choice);
                break;
            }
            case ActionType.REMOVE_CHOICE: {
                action.choice.choiceEl = undefined;
                if (action.choice.group) {
                    action.choice.group.choices = action.choice.group.choices.filter(function (obj) { return obj.id !== action.choice.id; });
                }
                state = state.filter(function (obj) { return obj.id !== action.choice.id; });
                break;
            }
            case ActionType.ADD_ITEM:
            case ActionType.REMOVE_ITEM: {
                action.item.choiceEl = undefined;
                break;
            }
            case ActionType.FILTER_CHOICES: {
                // avoid O(n^2) algorithm complexity when searching/filtering choices
                var scoreLookup_1 = [];
                action.results.forEach(function (result) {
                    scoreLookup_1[result.item.id] = result;
                });
                state.forEach(function (choice) {
                    var result = scoreLookup_1[choice.id];
                    if (result !== undefined) {
                        choice.score = result.score;
                        choice.rank = result.rank;
                        choice.active = true;
                    }
                    else {
                        choice.score = 0;
                        choice.rank = 0;
                        choice.active = false;
                    }
                    if (context && context.appendGroupInSearch) {
                        choice.choiceEl = undefined;
                    }
                });
                break;
            }
            case ActionType.ACTIVATE_CHOICES: {
                state.forEach(function (choice) {
                    choice.active = action.active;
                    if (context && context.appendGroupInSearch) {
                        choice.choiceEl = undefined;
                    }
                });
                break;
            }
            case ActionType.CLEAR_CHOICES: {
                state = [];
                break;
            }
            default: {
                update = false;
                break;
            }
        }
        return { state: state, update: update };
    }

    var reducers = {
        groups: groups,
        items: items,
        choices: choices,
    };
    var Store = /** @class */ (function () {
        function Store(context) {
            this._state = this.defaultState;
            this._listeners = [];
            this._txn = 0;
            this._context = context;
        }
        Object.defineProperty(Store.prototype, "defaultState", {
            // eslint-disable-next-line class-methods-use-this
            get: function () {
                return {
                    groups: [],
                    items: [],
                    choices: [],
                };
            },
            enumerable: false,
            configurable: true
        });
        // eslint-disable-next-line class-methods-use-this
        Store.prototype.changeSet = function (init) {
            return {
                groups: init,
                items: init,
                choices: init,
            };
        };
        Store.prototype.reset = function () {
            this._state = this.defaultState;
            var changes = this.changeSet(true);
            if (this._txn) {
                this._changeSet = changes;
            }
            else {
                this._listeners.forEach(function (l) { return l(changes); });
            }
        };
        Store.prototype.subscribe = function (onChange) {
            this._listeners.push(onChange);
            return this;
        };
        Store.prototype.dispatch = function (action) {
            var _this = this;
            var state = this._state;
            var hasChanges = false;
            var changes = this._changeSet || this.changeSet(false);
            Object.keys(reducers).forEach(function (key) {
                var stateUpdate = reducers[key](state[key], action, _this._context);
                if (stateUpdate.update) {
                    hasChanges = true;
                    changes[key] = true;
                    state[key] = stateUpdate.state;
                }
            });
            if (hasChanges) {
                if (this._txn) {
                    this._changeSet = changes;
                }
                else {
                    this._listeners.forEach(function (l) { return l(changes); });
                }
            }
        };
        Store.prototype.withTxn = function (func) {
            this._txn++;
            try {
                func();
            }
            finally {
                this._txn = Math.max(0, this._txn - 1);
                if (!this._txn) {
                    var changeSet_1 = this._changeSet;
                    if (changeSet_1) {
                        this._changeSet = undefined;
                        this._listeners.forEach(function (l) { return l(changeSet_1); });
                    }
                }
            }
        };
        Object.defineProperty(Store.prototype, "state", {
            /**
             * Get store object
             */
            get: function () {
                return this._state;
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(Store.prototype, "items", {
            /**
             * Get items from store
             */
            get: function () {
                return this.state.items;
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(Store.prototype, "highlightedActiveItems", {
            /**
             * Get highlighted items from store
             */
            get: function () {
                return this.items.filter(function (item) { return item.active && item.highlighted; });
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(Store.prototype, "choices", {
            /**
             * Get choices from store
             */
            get: function () {
                return this.state.choices;
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(Store.prototype, "activeChoices", {
            /**
             * Get active choices from store
             */
            get: function () {
                return this.choices.filter(function (choice) { return choice.active; });
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(Store.prototype, "searchableChoices", {
            /**
             * Get choices that can be searched (excluding placeholders or disabled choices)
             */
            get: function () {
                var context = this._context;
                return this.choices.filter(function (choice) { return !choice.placeholder && (context.searchDisabledChoices || !choice.disabled); });
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(Store.prototype, "groups", {
            /**
             * Get groups from store
             */
            get: function () {
                return this.state.groups;
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(Store.prototype, "activeGroups", {
            /**
             * Get active groups from store
             */
            get: function () {
                var _this = this;
                return this.state.groups.filter(function (group) {
                    var isActive = group.active && !group.disabled;
                    var hasActiveOptions = _this.state.choices.some(function (choice) { return choice.active && !choice.disabled; });
                    return isActive && hasActiveOptions;
                }, []);
            },
            enumerable: false,
            configurable: true
        });
        Store.prototype.inTxn = function () {
            return this._txn > 0;
        };
        /**
         * Get single choice by it's ID
         */
        Store.prototype.getChoiceById = function (id) {
            return this.activeChoices.find(function (choice) { return choice.id === id; });
        };
        /**
         * Get group by group id
         */
        Store.prototype.getGroupById = function (id) {
            return this.groups.find(function (group) { return group.id === id; });
        };
        return Store;
    }());

    var NoticeTypes = {
        noChoices: 'no-choices',
        noResults: 'no-results',
        addChoice: 'add-choice',
        generic: '',
    };

    function _defineProperty(e, r, t) {
      return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
        value: t,
        enumerable: true,
        configurable: true,
        writable: true
      }) : e[r] = t, e;
    }
    function ownKeys(e, r) {
      var t = Object.keys(e);
      if (Object.getOwnPropertySymbols) {
        var o = Object.getOwnPropertySymbols(e);
        r && (o = o.filter(function (r) {
          return Object.getOwnPropertyDescriptor(e, r).enumerable;
        })), t.push.apply(t, o);
      }
      return t;
    }
    function _objectSpread2(e) {
      for (var r = 1; r < arguments.length; r++) {
        var t = null != arguments[r] ? arguments[r] : {};
        r % 2 ? ownKeys(Object(t), true).forEach(function (r) {
          _defineProperty(e, r, t[r]);
        }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
          Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
        });
      }
      return e;
    }
    function _toPrimitive(t, r) {
      if ("object" != typeof t || !t) return t;
      var e = t[Symbol.toPrimitive];
      if (void 0 !== e) {
        var i = e.call(t, r);
        if ("object" != typeof i) return i;
        throw new TypeError("@@toPrimitive must return a primitive value.");
      }
      return ("string" === r ? String : Number)(t);
    }
    function _toPropertyKey(t) {
      var i = _toPrimitive(t, "string");
      return "symbol" == typeof i ? i : i + "";
    }

    /**
     * Fuse.js v7.0.0 - Lightweight fuzzy-search (http://fusejs.io)
     *
     * Copyright (c) 2023 Kiro Risk (http://kiro.me)
     * All Rights Reserved. Apache Software License 2.0
     *
     * http://www.apache.org/licenses/LICENSE-2.0
     */

    function isArray(value) {
      return !Array.isArray ? getTag(value) === '[object Array]' : Array.isArray(value);
    }
    function baseToString(value) {
      // Exit early for strings to avoid a performance hit in some environments.
      if (typeof value == 'string') {
        return value;
      }
      let result = value + '';
      return result == '0' && 1 / value == -Infinity ? '-0' : result;
    }
    function toString(value) {
      return value == null ? '' : baseToString(value);
    }
    function isString(value) {
      return typeof value === 'string';
    }
    function isNumber(value) {
      return typeof value === 'number';
    }

    // Adapted from: https://github.com/lodash/lodash/blob/master/isBoolean.js
    function isBoolean(value) {
      return value === true || value === false || isObjectLike(value) && getTag(value) == '[object Boolean]';
    }
    function isObject(value) {
      return typeof value === 'object';
    }

    // Checks if `value` is object-like.
    function isObjectLike(value) {
      return isObject(value) && value !== null;
    }
    function isDefined(value) {
      return value !== undefined && value !== null;
    }
    function isBlank(value) {
      return !value.trim().length;
    }

    // Gets the `toStringTag` of `value`.
    // Adapted from: https://github.com/lodash/lodash/blob/master/.internal/getTag.js
    function getTag(value) {
      return value == null ? value === undefined ? '[object Undefined]' : '[object Null]' : Object.prototype.toString.call(value);
    }
    const INCORRECT_INDEX_TYPE = "Incorrect 'index' type";
    const LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY = key => `Invalid value for key ${key}`;
    const PATTERN_LENGTH_TOO_LARGE = max => `Pattern length exceeds max of ${max}.`;
    const MISSING_KEY_PROPERTY = name => `Missing ${name} property in key`;
    const INVALID_KEY_WEIGHT_VALUE = key => `Property 'weight' in key '${key}' must be a positive integer`;
    const hasOwn = Object.prototype.hasOwnProperty;
    class KeyStore {
      constructor(keys) {
        this._keys = [];
        this._keyMap = {};
        let totalWeight = 0;
        keys.forEach(key => {
          let obj = createKey(key);
          this._keys.push(obj);
          this._keyMap[obj.id] = obj;
          totalWeight += obj.weight;
        });

        // Normalize weights so that their sum is equal to 1
        this._keys.forEach(key => {
          key.weight /= totalWeight;
        });
      }
      get(keyId) {
        return this._keyMap[keyId];
      }
      keys() {
        return this._keys;
      }
      toJSON() {
        return JSON.stringify(this._keys);
      }
    }
    function createKey(key) {
      let path = null;
      let id = null;
      let src = null;
      let weight = 1;
      let getFn = null;
      if (isString(key) || isArray(key)) {
        src = key;
        path = createKeyPath(key);
        id = createKeyId(key);
      } else {
        if (!hasOwn.call(key, 'name')) {
          throw new Error(MISSING_KEY_PROPERTY('name'));
        }
        const name = key.name;
        src = name;
        if (hasOwn.call(key, 'weight')) {
          weight = key.weight;
          if (weight <= 0) {
            throw new Error(INVALID_KEY_WEIGHT_VALUE(name));
          }
        }
        path = createKeyPath(name);
        id = createKeyId(name);
        getFn = key.getFn;
      }
      return {
        path,
        id,
        weight,
        src,
        getFn
      };
    }
    function createKeyPath(key) {
      return isArray(key) ? key : key.split('.');
    }
    function createKeyId(key) {
      return isArray(key) ? key.join('.') : key;
    }
    function get(obj, path) {
      let list = [];
      let arr = false;
      const deepGet = (obj, path, index) => {
        if (!isDefined(obj)) {
          return;
        }
        if (!path[index]) {
          // If there's no path left, we've arrived at the object we care about.
          list.push(obj);
        } else {
          let key = path[index];
          const value = obj[key];
          if (!isDefined(value)) {
            return;
          }

          // If we're at the last value in the path, and if it's a string/number/bool,
          // add it to the list
          if (index === path.length - 1 && (isString(value) || isNumber(value) || isBoolean(value))) {
            list.push(toString(value));
          } else if (isArray(value)) {
            arr = true;
            // Search each item in the array.
            for (let i = 0, len = value.length; i < len; i += 1) {
              deepGet(value[i], path, index + 1);
            }
          } else if (path.length) {
            // An object. Recurse further.
            deepGet(value, path, index + 1);
          }
        }
      };

      // Backwards compatibility (since path used to be a string)
      deepGet(obj, isString(path) ? path.split('.') : path, 0);
      return arr ? list : list[0];
    }
    const MatchOptions = {
      // Whether the matches should be included in the result set. When `true`, each record in the result
      // set will include the indices of the matched characters.
      // These can consequently be used for highlighting purposes.
      includeMatches: false,
      // When `true`, the matching function will continue to the end of a search pattern even if
      // a perfect match has already been located in the string.
      findAllMatches: false,
      // Minimum number of characters that must be matched before a result is considered a match
      minMatchCharLength: 1
    };
    const BasicOptions = {
      // When `true`, the algorithm continues searching to the end of the input even if a perfect
      // match is found before the end of the same input.
      isCaseSensitive: false,
      // When true, the matching function will continue to the end of a search pattern even if
      includeScore: false,
      // List of properties that will be searched. This also supports nested properties.
      keys: [],
      // Whether to sort the result list, by score
      shouldSort: true,
      // Default sort function: sort by ascending score, ascending index
      sortFn: (a, b) => a.score === b.score ? a.idx < b.idx ? -1 : 1 : a.score < b.score ? -1 : 1
    };
    const FuzzyOptions = {
      // Approximately where in the text is the pattern expected to be found?
      location: 0,
      // At what point does the match algorithm give up. A threshold of '0.0' requires a perfect match
      // (of both letters and location), a threshold of '1.0' would match anything.
      threshold: 0.6,
      // Determines how close the match must be to the fuzzy location (specified above).
      // An exact letter match which is 'distance' characters away from the fuzzy location
      // would score as a complete mismatch. A distance of '0' requires the match be at
      // the exact location specified, a threshold of '1000' would require a perfect match
      // to be within 800 characters of the fuzzy location to be found using a 0.8 threshold.
      distance: 100
    };
    const AdvancedOptions = {
      // When `true`, it enables the use of unix-like search commands
      useExtendedSearch: false,
      // The get function to use when fetching an object's properties.
      // The default will search nested paths *ie foo.bar.baz*
      getFn: get,
      // When `true`, search will ignore `location` and `distance`, so it won't matter
      // where in the string the pattern appears.
      // More info: https://fusejs.io/concepts/scoring-theory.html#fuzziness-score
      ignoreLocation: false,
      // When `true`, the calculation for the relevance score (used for sorting) will
      // ignore the field-length norm.
      // More info: https://fusejs.io/concepts/scoring-theory.html#field-length-norm
      ignoreFieldNorm: false,
      // The weight to determine how much field length norm effects scoring.
      fieldNormWeight: 1
    };
    var Config = _objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({}, BasicOptions), MatchOptions), FuzzyOptions), AdvancedOptions);
    const SPACE = /[^ ]+/g;

    // Field-length norm: the shorter the field, the higher the weight.
    // Set to 3 decimals to reduce index size.
    function norm(weight = 1, mantissa = 3) {
      const cache = new Map();
      const m = Math.pow(10, mantissa);
      return {
        get(value) {
          const numTokens = value.match(SPACE).length;
          if (cache.has(numTokens)) {
            return cache.get(numTokens);
          }

          // Default function is 1/sqrt(x), weight makes that variable
          const norm = 1 / Math.pow(numTokens, 0.5 * weight);

          // In place of `toFixed(mantissa)`, for faster computation
          const n = parseFloat(Math.round(norm * m) / m);
          cache.set(numTokens, n);
          return n;
        },
        clear() {
          cache.clear();
        }
      };
    }
    class FuseIndex {
      constructor({
        getFn = Config.getFn,
        fieldNormWeight = Config.fieldNormWeight
      } = {}) {
        this.norm = norm(fieldNormWeight, 3);
        this.getFn = getFn;
        this.isCreated = false;
        this.setIndexRecords();
      }
      setSources(docs = []) {
        this.docs = docs;
      }
      setIndexRecords(records = []) {
        this.records = records;
      }
      setKeys(keys = []) {
        this.keys = keys;
        this._keysMap = {};
        keys.forEach((key, idx) => {
          this._keysMap[key.id] = idx;
        });
      }
      create() {
        if (this.isCreated || !this.docs.length) {
          return;
        }
        this.isCreated = true;

        // List is Array<String>
        if (isString(this.docs[0])) {
          this.docs.forEach((doc, docIndex) => {
            this._addString(doc, docIndex);
          });
        } else {
          // List is Array<Object>
          this.docs.forEach((doc, docIndex) => {
            this._addObject(doc, docIndex);
          });
        }
        this.norm.clear();
      }
      // Adds a doc to the end of the index
      add(doc) {
        const idx = this.size();
        if (isString(doc)) {
          this._addString(doc, idx);
        } else {
          this._addObject(doc, idx);
        }
      }
      // Removes the doc at the specified index of the index
      removeAt(idx) {
        this.records.splice(idx, 1);

        // Change ref index of every subsquent doc
        for (let i = idx, len = this.size(); i < len; i += 1) {
          this.records[i].i -= 1;
        }
      }
      getValueForItemAtKeyId(item, keyId) {
        return item[this._keysMap[keyId]];
      }
      size() {
        return this.records.length;
      }
      _addString(doc, docIndex) {
        if (!isDefined(doc) || isBlank(doc)) {
          return;
        }
        let record = {
          v: doc,
          i: docIndex,
          n: this.norm.get(doc)
        };
        this.records.push(record);
      }
      _addObject(doc, docIndex) {
        let record = {
          i: docIndex,
          $: {}
        };

        // Iterate over every key (i.e, path), and fetch the value at that key
        this.keys.forEach((key, keyIndex) => {
          let value = key.getFn ? key.getFn(doc) : this.getFn(doc, key.path);
          if (!isDefined(value)) {
            return;
          }
          if (isArray(value)) {
            let subRecords = [];
            const stack = [{
              nestedArrIndex: -1,
              value
            }];
            while (stack.length) {
              const {
                nestedArrIndex,
                value
              } = stack.pop();
              if (!isDefined(value)) {
                continue;
              }
              if (isString(value) && !isBlank(value)) {
                let subRecord = {
                  v: value,
                  i: nestedArrIndex,
                  n: this.norm.get(value)
                };
                subRecords.push(subRecord);
              } else if (isArray(value)) {
                value.forEach((item, k) => {
                  stack.push({
                    nestedArrIndex: k,
                    value: item
                  });
                });
              } else ;
            }
            record.$[keyIndex] = subRecords;
          } else if (isString(value) && !isBlank(value)) {
            let subRecord = {
              v: value,
              n: this.norm.get(value)
            };
            record.$[keyIndex] = subRecord;
          }
        });
        this.records.push(record);
      }
      toJSON() {
        return {
          keys: this.keys,
          records: this.records
        };
      }
    }
    function createIndex(keys, docs, {
      getFn = Config.getFn,
      fieldNormWeight = Config.fieldNormWeight
    } = {}) {
      const myIndex = new FuseIndex({
        getFn,
        fieldNormWeight
      });
      myIndex.setKeys(keys.map(createKey));
      myIndex.setSources(docs);
      myIndex.create();
      return myIndex;
    }
    function parseIndex(data, {
      getFn = Config.getFn,
      fieldNormWeight = Config.fieldNormWeight
    } = {}) {
      const {
        keys,
        records
      } = data;
      const myIndex = new FuseIndex({
        getFn,
        fieldNormWeight
      });
      myIndex.setKeys(keys);
      myIndex.setIndexRecords(records);
      return myIndex;
    }
    function computeScore$1(pattern, {
      errors = 0,
      currentLocation = 0,
      expectedLocation = 0,
      distance = Config.distance,
      ignoreLocation = Config.ignoreLocation
    } = {}) {
      const accuracy = errors / pattern.length;
      if (ignoreLocation) {
        return accuracy;
      }
      const proximity = Math.abs(expectedLocation - currentLocation);
      if (!distance) {
        // Dodge divide by zero error.
        return proximity ? 1.0 : accuracy;
      }
      return accuracy + proximity / distance;
    }
    function convertMaskToIndices(matchmask = [], minMatchCharLength = Config.minMatchCharLength) {
      let indices = [];
      let start = -1;
      let end = -1;
      let i = 0;
      for (let len = matchmask.length; i < len; i += 1) {
        let match = matchmask[i];
        if (match && start === -1) {
          start = i;
        } else if (!match && start !== -1) {
          end = i - 1;
          if (end - start + 1 >= minMatchCharLength) {
            indices.push([start, end]);
          }
          start = -1;
        }
      }

      // (i-1 - start) + 1 => i - start
      if (matchmask[i - 1] && i - start >= minMatchCharLength) {
        indices.push([start, i - 1]);
      }
      return indices;
    }

    // Machine word size
    const MAX_BITS = 32;
    function search(text, pattern, patternAlphabet, {
      location = Config.location,
      distance = Config.distance,
      threshold = Config.threshold,
      findAllMatches = Config.findAllMatches,
      minMatchCharLength = Config.minMatchCharLength,
      includeMatches = Config.includeMatches,
      ignoreLocation = Config.ignoreLocation
    } = {}) {
      if (pattern.length > MAX_BITS) {
        throw new Error(PATTERN_LENGTH_TOO_LARGE(MAX_BITS));
      }
      const patternLen = pattern.length;
      // Set starting location at beginning text and initialize the alphabet.
      const textLen = text.length;
      // Handle the case when location > text.length
      const expectedLocation = Math.max(0, Math.min(location, textLen));
      // Highest score beyond which we give up.
      let currentThreshold = threshold;
      // Is there a nearby exact match? (speedup)
      let bestLocation = expectedLocation;

      // Performance: only computer matches when the minMatchCharLength > 1
      // OR if `includeMatches` is true.
      const computeMatches = minMatchCharLength > 1 || includeMatches;
      // A mask of the matches, used for building the indices
      const matchMask = computeMatches ? Array(textLen) : [];
      let index;

      // Get all exact matches, here for speed up
      while ((index = text.indexOf(pattern, bestLocation)) > -1) {
        let score = computeScore$1(pattern, {
          currentLocation: index,
          expectedLocation,
          distance,
          ignoreLocation
        });
        currentThreshold = Math.min(score, currentThreshold);
        bestLocation = index + patternLen;
        if (computeMatches) {
          let i = 0;
          while (i < patternLen) {
            matchMask[index + i] = 1;
            i += 1;
          }
        }
      }

      // Reset the best location
      bestLocation = -1;
      let lastBitArr = [];
      let finalScore = 1;
      let binMax = patternLen + textLen;
      const mask = 1 << patternLen - 1;
      for (let i = 0; i < patternLen; i += 1) {
        // Scan for the best match; each iteration allows for one more error.
        // Run a binary search to determine how far from the match location we can stray
        // at this error level.
        let binMin = 0;
        let binMid = binMax;
        while (binMin < binMid) {
          const score = computeScore$1(pattern, {
            errors: i,
            currentLocation: expectedLocation + binMid,
            expectedLocation,
            distance,
            ignoreLocation
          });
          if (score <= currentThreshold) {
            binMin = binMid;
          } else {
            binMax = binMid;
          }
          binMid = Math.floor((binMax - binMin) / 2 + binMin);
        }

        // Use the result from this iteration as the maximum for the next.
        binMax = binMid;
        let start = Math.max(1, expectedLocation - binMid + 1);
        let finish = findAllMatches ? textLen : Math.min(expectedLocation + binMid, textLen) + patternLen;

        // Initialize the bit array
        let bitArr = Array(finish + 2);
        bitArr[finish + 1] = (1 << i) - 1;
        for (let j = finish; j >= start; j -= 1) {
          let currentLocation = j - 1;
          let charMatch = patternAlphabet[text.charAt(currentLocation)];
          if (computeMatches) {
            // Speed up: quick bool to int conversion (i.e, `charMatch ? 1 : 0`)
            matchMask[currentLocation] = +!!charMatch;
          }

          // First pass: exact match
          bitArr[j] = (bitArr[j + 1] << 1 | 1) & charMatch;

          // Subsequent passes: fuzzy match
          if (i) {
            bitArr[j] |= (lastBitArr[j + 1] | lastBitArr[j]) << 1 | 1 | lastBitArr[j + 1];
          }
          if (bitArr[j] & mask) {
            finalScore = computeScore$1(pattern, {
              errors: i,
              currentLocation,
              expectedLocation,
              distance,
              ignoreLocation
            });

            // This match will almost certainly be better than any existing match.
            // But check anyway.
            if (finalScore <= currentThreshold) {
              // Indeed it is
              currentThreshold = finalScore;
              bestLocation = currentLocation;

              // Already passed `loc`, downhill from here on in.
              if (bestLocation <= expectedLocation) {
                break;
              }

              // When passing `bestLocation`, don't exceed our current distance from `expectedLocation`.
              start = Math.max(1, 2 * expectedLocation - bestLocation);
            }
          }
        }

        // No hope for a (better) match at greater error levels.
        const score = computeScore$1(pattern, {
          errors: i + 1,
          currentLocation: expectedLocation,
          expectedLocation,
          distance,
          ignoreLocation
        });
        if (score > currentThreshold) {
          break;
        }
        lastBitArr = bitArr;
      }
      const result = {
        isMatch: bestLocation >= 0,
        // Count exact matches (those with a score of 0) to be "almost" exact
        score: Math.max(0.001, finalScore)
      };
      if (computeMatches) {
        const indices = convertMaskToIndices(matchMask, minMatchCharLength);
        if (!indices.length) {
          result.isMatch = false;
        } else if (includeMatches) {
          result.indices = indices;
        }
      }
      return result;
    }
    function createPatternAlphabet(pattern) {
      let mask = {};
      for (let i = 0, len = pattern.length; i < len; i += 1) {
        const char = pattern.charAt(i);
        mask[char] = (mask[char] || 0) | 1 << len - i - 1;
      }
      return mask;
    }
    class BitapSearch {
      constructor(pattern, {
        location = Config.location,
        threshold = Config.threshold,
        distance = Config.distance,
        includeMatches = Config.includeMatches,
        findAllMatches = Config.findAllMatches,
        minMatchCharLength = Config.minMatchCharLength,
        isCaseSensitive = Config.isCaseSensitive,
        ignoreLocation = Config.ignoreLocation
      } = {}) {
        this.options = {
          location,
          threshold,
          distance,
          includeMatches,
          findAllMatches,
          minMatchCharLength,
          isCaseSensitive,
          ignoreLocation
        };
        this.pattern = isCaseSensitive ? pattern : pattern.toLowerCase();
        this.chunks = [];
        if (!this.pattern.length) {
          return;
        }
        const addChunk = (pattern, startIndex) => {
          this.chunks.push({
            pattern,
            alphabet: createPatternAlphabet(pattern),
            startIndex
          });
        };
        const len = this.pattern.length;
        if (len > MAX_BITS) {
          let i = 0;
          const remainder = len % MAX_BITS;
          const end = len - remainder;
          while (i < end) {
            addChunk(this.pattern.substr(i, MAX_BITS), i);
            i += MAX_BITS;
          }
          if (remainder) {
            const startIndex = len - MAX_BITS;
            addChunk(this.pattern.substr(startIndex), startIndex);
          }
        } else {
          addChunk(this.pattern, 0);
        }
      }
      searchIn(text) {
        const {
          isCaseSensitive,
          includeMatches
        } = this.options;
        if (!isCaseSensitive) {
          text = text.toLowerCase();
        }

        // Exact match
        if (this.pattern === text) {
          let result = {
            isMatch: true,
            score: 0
          };
          if (includeMatches) {
            result.indices = [[0, text.length - 1]];
          }
          return result;
        }

        // Otherwise, use Bitap algorithm
        const {
          location,
          distance,
          threshold,
          findAllMatches,
          minMatchCharLength,
          ignoreLocation
        } = this.options;
        let allIndices = [];
        let totalScore = 0;
        let hasMatches = false;
        this.chunks.forEach(({
          pattern,
          alphabet,
          startIndex
        }) => {
          const {
            isMatch,
            score,
            indices
          } = search(text, pattern, alphabet, {
            location: location + startIndex,
            distance,
            threshold,
            findAllMatches,
            minMatchCharLength,
            includeMatches,
            ignoreLocation
          });
          if (isMatch) {
            hasMatches = true;
          }
          totalScore += score;
          if (isMatch && indices) {
            allIndices = [...allIndices, ...indices];
          }
        });
        let result = {
          isMatch: hasMatches,
          score: hasMatches ? totalScore / this.chunks.length : 1
        };
        if (hasMatches && includeMatches) {
          result.indices = allIndices;
        }
        return result;
      }
    }
    class BaseMatch {
      constructor(pattern) {
        this.pattern = pattern;
      }
      static isMultiMatch(pattern) {
        return getMatch(pattern, this.multiRegex);
      }
      static isSingleMatch(pattern) {
        return getMatch(pattern, this.singleRegex);
      }
      search( /*
Download .txt
gitextract_040cemen/

├── .browserslistrc
├── .codebeatignore
├── .codecov.yml
├── .editorconfig
├── .eslintrc.json
├── .git-blame-ignore-revs
├── .gitattributes
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   ├── PULL_REQUEST_TEMPLATE.md
│   ├── actions-scripts/
│   │   └── polyfills-sync.cjs
│   ├── release-drafter.yml
│   └── workflows/
│       ├── browsers.yml
│       ├── bundlesize.yml
│       ├── deploy-pages.yml
│       ├── deployment.yml
│       ├── lint.yml
│       ├── polyfills-sync.yml
│       ├── release-drafter.yml
│       └── unit-tests.yml
├── .gitignore
├── .nvmrc
├── .prettierrc.json
├── .stylelintrc.json
├── .vscode/
│   ├── extensions.json
│   ├── launch.json
│   ├── settings.json
│   └── tasks.json
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── babel.config.json
├── jsconfig.json
├── package.json
├── playwright.config.ts
├── public/
│   ├── assets/
│   │   ├── images/
│   │   │   ├── browserconfig.xml
│   │   │   └── manifest.json
│   │   ├── scripts/
│   │   │   ├── choices.js
│   │   │   ├── choices.mjs
│   │   │   ├── choices.search-basic.js
│   │   │   ├── choices.search-basic.mjs
│   │   │   ├── choices.search-kmp.js
│   │   │   ├── choices.search-kmp.mjs
│   │   │   ├── choices.search-prefix.js
│   │   │   └── choices.search-prefix.mjs
│   │   └── styles/
│   │       ├── base.css
│   │       └── choices.css
│   ├── index.html
│   ├── robots.txt
│   ├── test/
│   │   ├── data.json
│   │   ├── disabled-data.json
│   │   ├── select-multiple/
│   │   │   ├── index-performance.html
│   │   │   └── index.html
│   │   ├── select-one/
│   │   │   └── index.html
│   │   └── text/
│   │       └── index.html
│   └── types/
│       └── src/
│           ├── index.d.ts
│           └── scripts/
│               ├── actions/
│               │   ├── choices.d.ts
│               │   ├── groups.d.ts
│               │   └── items.d.ts
│               ├── choices.d.ts
│               ├── components/
│               │   ├── container.d.ts
│               │   ├── dropdown.d.ts
│               │   ├── index.d.ts
│               │   ├── input.d.ts
│               │   ├── list.d.ts
│               │   ├── wrapped-element.d.ts
│               │   ├── wrapped-input.d.ts
│               │   └── wrapped-select.d.ts
│               ├── constants.d.ts
│               ├── defaults.d.ts
│               ├── interfaces/
│               │   ├── action-type.d.ts
│               │   ├── build-flags.d.ts
│               │   ├── choice-full.d.ts
│               │   ├── class-names.d.ts
│               │   ├── event-choice.d.ts
│               │   ├── event-type.d.ts
│               │   ├── group-full.d.ts
│               │   ├── index.d.ts
│               │   ├── input-choice.d.ts
│               │   ├── input-group.d.ts
│               │   ├── item.d.ts
│               │   ├── keycode-map.d.ts
│               │   ├── options.d.ts
│               │   ├── passed-element-type.d.ts
│               │   ├── passed-element.d.ts
│               │   ├── position-options-type.d.ts
│               │   ├── search.d.ts
│               │   ├── state.d.ts
│               │   ├── store.d.ts
│               │   ├── string-pre-escaped.d.ts
│               │   ├── string-untrusted.d.ts
│               │   ├── templates.d.ts
│               │   └── types.d.ts
│               ├── lib/
│               │   ├── choice-input.d.ts
│               │   ├── html-guard-statements.d.ts
│               │   └── utils.d.ts
│               ├── reducers/
│               │   ├── choices.d.ts
│               │   ├── groups.d.ts
│               │   └── items.d.ts
│               ├── search/
│               │   ├── fuse.d.ts
│               │   ├── index.d.ts
│               │   ├── kmp.d.ts
│               │   └── prefix-filter.d.ts
│               ├── store/
│               │   └── store.d.ts
│               └── templates.d.ts
├── scripts/
│   ├── lint-staged.config.js
│   ├── rollup.config.mjs
│   └── server.mjs
├── src/
│   ├── entry.js
│   ├── index.ts
│   ├── scripts/
│   │   ├── actions/
│   │   │   ├── choices.ts
│   │   │   ├── groups.ts
│   │   │   └── items.ts
│   │   ├── choices.ts
│   │   ├── components/
│   │   │   ├── container.ts
│   │   │   ├── dropdown.ts
│   │   │   ├── index.ts
│   │   │   ├── input.ts
│   │   │   ├── list.ts
│   │   │   ├── wrapped-element.ts
│   │   │   ├── wrapped-input.ts
│   │   │   └── wrapped-select.ts
│   │   ├── constants.ts
│   │   ├── defaults.ts
│   │   ├── interfaces/
│   │   │   ├── action-type.ts
│   │   │   ├── build-flags.ts
│   │   │   ├── choice-full.ts
│   │   │   ├── class-names.ts
│   │   │   ├── event-choice.ts
│   │   │   ├── event-type.ts
│   │   │   ├── group-full.ts
│   │   │   ├── index.ts
│   │   │   ├── input-choice.ts
│   │   │   ├── input-group.ts
│   │   │   ├── item.ts
│   │   │   ├── keycode-map.ts
│   │   │   ├── options.ts
│   │   │   ├── passed-element-type.ts
│   │   │   ├── passed-element.ts
│   │   │   ├── position-options-type.ts
│   │   │   ├── search.ts
│   │   │   ├── state.ts
│   │   │   ├── store.ts
│   │   │   ├── string-pre-escaped.ts
│   │   │   ├── string-untrusted.ts
│   │   │   ├── templates.ts
│   │   │   └── types.ts
│   │   ├── lib/
│   │   │   ├── choice-input.ts
│   │   │   ├── html-guard-statements.ts
│   │   │   └── utils.ts
│   │   ├── reducers/
│   │   │   ├── choices.ts
│   │   │   ├── groups.ts
│   │   │   └── items.ts
│   │   ├── search/
│   │   │   ├── fuse.ts
│   │   │   ├── index.ts
│   │   │   ├── kmp.ts
│   │   │   └── prefix-filter.ts
│   │   ├── store/
│   │   │   └── store.ts
│   │   └── templates.ts
│   ├── styles/
│   │   ├── base.scss
│   │   └── choices.scss
│   └── tsconfig.json
├── test/
│   ├── scripts/
│   │   ├── actions/
│   │   │   ├── choices.test.ts
│   │   │   ├── groups.test.ts
│   │   │   └── items.test.ts
│   │   ├── choices.test.ts
│   │   ├── components/
│   │   │   ├── container.test.ts
│   │   │   ├── dropdown.test.ts
│   │   │   ├── input.test.ts
│   │   │   ├── list.test.ts
│   │   │   ├── wrapped-element.test.ts
│   │   │   ├── wrapped-input.test.ts
│   │   │   └── wrapped-select.test.ts
│   │   ├── lib/
│   │   │   └── utils.test.ts
│   │   ├── reducers/
│   │   │   ├── choices.test.ts
│   │   │   ├── groups.test.ts
│   │   │   └── items.test.ts
│   │   ├── search/
│   │   │   └── index.test.ts
│   │   ├── store/
│   │   │   └── store.test.ts
│   │   └── templates.test.ts
│   ├── setupFiles/
│   │   └── window-matchMedia.ts
│   └── tsconfig.json
├── test-e2e/
│   ├── bundle-test.ts
│   ├── hars/
│   │   ├── 0432285dab6a62ab5e6efaf4cb1272720e0c3f1b.json
│   │   ├── 69c6136c671f1173ee6d6596d125e821dea44a4f.json
│   │   ├── a8763b95c9f6c98156a9100e8bed82cb17b93ecd.json
│   │   └── discogs.har
│   ├── select-test-suit.ts
│   ├── test-suit.ts
│   ├── tests/
│   │   ├── demo-page.spec.ts
│   │   ├── select-multiple-performance.spec.ts
│   │   ├── select-multiple.spec.ts
│   │   ├── select-one.spec.ts
│   │   └── text.spec.ts
│   ├── text-test-suit.ts
│   └── tsconfig.json
└── vitest.config.ts
Download .txt
SYMBOL INDEX (936 symbols across 99 files)

FILE: public/assets/scripts/choices.js
  function __extends (line 35) | function __extends(d, b) {
  function __spreadArray (line 53) | function __spreadArray(to, from, pack) {
  function Dropdown (line 348) | function Dropdown(_a) {
  function Container (line 377) | function Container(_a) {
  function Input (line 497) | function Input(_a) {
  function List (line 613) | function List(_a) {
  function WrappedElement (line 685) | function WrappedElement(_a) {
  function WrappedInput (line 765) | function WrappedInput() {
  function WrappedSelect (line 841) | function WrappedSelect(_a) {
  function items (line 1032) | function items(s, action, context) {
  function groups (line 1087) | function groups(s, action) {
  function choices (line 1108) | function choices(s, action, context) {
  function Store (line 1180) | function Store(context) {
  function _defineProperty (line 1369) | function _defineProperty(e, r, t) {
  function ownKeys (line 1377) | function ownKeys(e, r) {
  function _objectSpread2 (line 1387) | function _objectSpread2(e) {
  function _toPrimitive (line 1398) | function _toPrimitive(t, r) {
  function _toPropertyKey (line 1408) | function _toPropertyKey(t) {
  function isArray (line 1422) | function isArray(value) {
  function baseToString (line 1425) | function baseToString(value) {
  function toString (line 1433) | function toString(value) {
  function isString (line 1436) | function isString(value) {
  function isNumber (line 1439) | function isNumber(value) {
  function isBoolean (line 1444) | function isBoolean(value) {
  function isObject (line 1447) | function isObject(value) {
  function isObjectLike (line 1452) | function isObjectLike(value) {
  function isDefined (line 1455) | function isDefined(value) {
  function isBlank (line 1458) | function isBlank(value) {
  function getTag (line 1464) | function getTag(value) {
  class KeyStore (line 1473) | class KeyStore {
    method constructor (line 1474) | constructor(keys) {
    method get (line 1490) | get(keyId) {
    method keys (line 1493) | keys() {
    method toJSON (line 1496) | toJSON() {
  function createKey (line 1500) | function createKey(key) {
  function createKeyPath (line 1534) | function createKeyPath(key) {
  function createKeyId (line 1537) | function createKeyId(key) {
  function get (line 1540) | function get(obj, path) {
  function norm (line 1637) | function norm(weight = 1, mantissa = 3) {
  class FuseIndex (line 1660) | class FuseIndex {
    method constructor (line 1661) | constructor({
    method setSources (line 1670) | setSources(docs = []) {
    method setIndexRecords (line 1673) | setIndexRecords(records = []) {
    method setKeys (line 1676) | setKeys(keys = []) {
    method create (line 1683) | create() {
    method add (line 1703) | add(doc) {
    method removeAt (line 1712) | removeAt(idx) {
    method getValueForItemAtKeyId (line 1720) | getValueForItemAtKeyId(item, keyId) {
    method size (line 1723) | size() {
    method _addString (line 1726) | _addString(doc, docIndex) {
    method _addObject (line 1737) | _addObject(doc, docIndex) {
    method toJSON (line 1790) | toJSON() {
  function createIndex (line 1797) | function createIndex(keys, docs, {
  function parseIndex (line 1810) | function parseIndex(data, {
  function computeScore$1 (line 1826) | function computeScore$1(pattern, {
  function convertMaskToIndices (line 1844) | function convertMaskToIndices(matchmask = [], minMatchCharLength = Confi...
  function search (line 1871) | function search(text, pattern, patternAlphabet, {
  function createPatternAlphabet (line 2025) | function createPatternAlphabet(pattern) {
  class BitapSearch (line 2033) | class BitapSearch {
    method constructor (line 2034) | constructor(pattern, {
    method searchIn (line 2083) | searchIn(text) {
  class BaseMatch (line 2152) | class BaseMatch {
    method constructor (line 2153) | constructor(pattern) {
    method isMultiMatch (line 2156) | static isMultiMatch(pattern) {
    method isSingleMatch (line 2159) | static isSingleMatch(pattern) {
    method search (line 2162) | search( /*text*/) {}
  function getMatch (line 2164) | function getMatch(pattern, exp) {
  class ExactMatch (line 2171) | class ExactMatch extends BaseMatch {
    method constructor (line 2172) | constructor(pattern) {
    method type (line 2175) | static get type() {
    method multiRegex (line 2178) | static get multiRegex() {
    method singleRegex (line 2181) | static get singleRegex() {
    method search (line 2184) | search(text) {
  class InverseExactMatch (line 2196) | class InverseExactMatch extends BaseMatch {
    method constructor (line 2197) | constructor(pattern) {
    method type (line 2200) | static get type() {
    method multiRegex (line 2203) | static get multiRegex() {
    method singleRegex (line 2206) | static get singleRegex() {
    method search (line 2209) | search(text) {
  class PrefixExactMatch (line 2222) | class PrefixExactMatch extends BaseMatch {
    method constructor (line 2223) | constructor(pattern) {
    method type (line 2226) | static get type() {
    method multiRegex (line 2229) | static get multiRegex() {
    method singleRegex (line 2232) | static get singleRegex() {
    method search (line 2235) | search(text) {
  class InversePrefixExactMatch (line 2247) | class InversePrefixExactMatch extends BaseMatch {
    method constructor (line 2248) | constructor(pattern) {
    method type (line 2251) | static get type() {
    method multiRegex (line 2254) | static get multiRegex() {
    method singleRegex (line 2257) | static get singleRegex() {
    method search (line 2260) | search(text) {
  class SuffixExactMatch (line 2272) | class SuffixExactMatch extends BaseMatch {
    method constructor (line 2273) | constructor(pattern) {
    method type (line 2276) | static get type() {
    method multiRegex (line 2279) | static get multiRegex() {
    method singleRegex (line 2282) | static get singleRegex() {
    method search (line 2285) | search(text) {
  class InverseSuffixExactMatch (line 2297) | class InverseSuffixExactMatch extends BaseMatch {
    method constructor (line 2298) | constructor(pattern) {
    method type (line 2301) | static get type() {
    method multiRegex (line 2304) | static get multiRegex() {
    method singleRegex (line 2307) | static get singleRegex() {
    method search (line 2310) | search(text) {
  class FuzzyMatch (line 2319) | class FuzzyMatch extends BaseMatch {
    method constructor (line 2320) | constructor(pattern, {
    method type (line 2342) | static get type() {
    method multiRegex (line 2345) | static get multiRegex() {
    method singleRegex (line 2348) | static get singleRegex() {
    method search (line 2351) | search(text) {
  class IncludeMatch (line 2358) | class IncludeMatch extends BaseMatch {
    method constructor (line 2359) | constructor(pattern) {
    method type (line 2362) | static get type() {
    method multiRegex (line 2365) | static get multiRegex() {
    method singleRegex (line 2368) | static get singleRegex() {
    method search (line 2371) | search(text) {
  function parseQuery (line 2402) | function parseQuery(pattern, options = {}) {
  class ExtendedSearch (line 2471) | class ExtendedSearch {
    method constructor (line 2472) | constructor(pattern, {
    method condition (line 2496) | static condition(_, options) {
    method searchIn (line 2499) | searchIn(text) {
  function register (line 2572) | function register(...args) {
  function createSearcher (line 2575) | function createSearcher(pattern, options) {
  function parse (line 2603) | function parse(query, options, {
  function computeScore (line 2648) | function computeScore(results, {
  function transformMatches (line 2664) | function transformMatches(result, data) {
  function transformScore (line 2691) | function transformScore(result, data) {
  function format (line 2694) | function format(results, docs, {
  class Fuse (line 2717) | class Fuse {
    method constructor (line 2718) | constructor(docs, options = {}, index) {
    method setCollection (line 2724) | setCollection(docs, index) {
    method add (line 2734) | add(doc) {
    method remove (line 2741) | remove(predicate = ( /* doc, idx */) => false) {
    method removeAt (line 2754) | removeAt(idx) {
    method getIndex (line 2758) | getIndex() {
    method search (line 2761) | search(query, {
    method _searchStringList (line 2786) | _searchStringList(query) {
    method _searchLogical (line 2822) | _searchLogical(query) {
    method _searchObjectList (line 2885) | _searchObjectList(query) {
    method _findMatches (line 2921) | _findMatches({
  function SearchByFuse (line 2990) | function SearchByFuse(config) {
  function getSearcher (line 3025) | function getSearcher(config) {
  function Choices (line 3351) | function Choices(element, userConfig) {
  method options (line 3495) | get options() {
  method allOptions (line 3498) | get allOptions() {
  method templates (line 3501) | get templates() {

FILE: public/assets/scripts/choices.mjs
  function __extends (line 29) | function __extends(d, b) {
  function __spreadArray (line 47) | function __spreadArray(to, from, pack) {
  function Dropdown (line 342) | function Dropdown(_a) {
  function Container (line 371) | function Container(_a) {
  function Input (line 491) | function Input(_a) {
  function List (line 607) | function List(_a) {
  function WrappedElement (line 679) | function WrappedElement(_a) {
  function WrappedInput (line 759) | function WrappedInput() {
  function WrappedSelect (line 835) | function WrappedSelect(_a) {
  function items (line 1026) | function items(s, action, context) {
  function groups (line 1081) | function groups(s, action) {
  function choices (line 1102) | function choices(s, action, context) {
  function Store (line 1174) | function Store(context) {
  function _defineProperty (line 1363) | function _defineProperty(e, r, t) {
  function ownKeys (line 1371) | function ownKeys(e, r) {
  function _objectSpread2 (line 1381) | function _objectSpread2(e) {
  function _toPrimitive (line 1392) | function _toPrimitive(t, r) {
  function _toPropertyKey (line 1402) | function _toPropertyKey(t) {
  function isArray (line 1416) | function isArray(value) {
  function baseToString (line 1419) | function baseToString(value) {
  function toString (line 1427) | function toString(value) {
  function isString (line 1430) | function isString(value) {
  function isNumber (line 1433) | function isNumber(value) {
  function isBoolean (line 1438) | function isBoolean(value) {
  function isObject (line 1441) | function isObject(value) {
  function isObjectLike (line 1446) | function isObjectLike(value) {
  function isDefined (line 1449) | function isDefined(value) {
  function isBlank (line 1452) | function isBlank(value) {
  function getTag (line 1458) | function getTag(value) {
  constant INCORRECT_INDEX_TYPE (line 1461) | const INCORRECT_INDEX_TYPE = "Incorrect 'index' type";
  class KeyStore (line 1467) | class KeyStore {
    method constructor (line 1468) | constructor(keys) {
    method get (line 1484) | get(keyId) {
    method keys (line 1487) | keys() {
    method toJSON (line 1490) | toJSON() {
  function createKey (line 1494) | function createKey(key) {
  function createKeyPath (line 1528) | function createKeyPath(key) {
  function createKeyId (line 1531) | function createKeyId(key) {
  function get (line 1534) | function get(obj, path) {
  constant SPACE (line 1627) | const SPACE = /[^ ]+/g;
  function norm (line 1631) | function norm(weight = 1, mantissa = 3) {
  class FuseIndex (line 1654) | class FuseIndex {
    method constructor (line 1655) | constructor({
    method setSources (line 1664) | setSources(docs = []) {
    method setIndexRecords (line 1667) | setIndexRecords(records = []) {
    method setKeys (line 1670) | setKeys(keys = []) {
    method create (line 1677) | create() {
    method add (line 1697) | add(doc) {
    method removeAt (line 1706) | removeAt(idx) {
    method getValueForItemAtKeyId (line 1714) | getValueForItemAtKeyId(item, keyId) {
    method size (line 1717) | size() {
    method _addString (line 1720) | _addString(doc, docIndex) {
    method _addObject (line 1731) | _addObject(doc, docIndex) {
    method toJSON (line 1784) | toJSON() {
  function createIndex (line 1791) | function createIndex(keys, docs, {
  function parseIndex (line 1804) | function parseIndex(data, {
  function computeScore$1 (line 1820) | function computeScore$1(pattern, {
  function convertMaskToIndices (line 1838) | function convertMaskToIndices(matchmask = [], minMatchCharLength = Confi...
  constant MAX_BITS (line 1864) | const MAX_BITS = 32;
  function search (line 1865) | function search(text, pattern, patternAlphabet, {
  function createPatternAlphabet (line 2019) | function createPatternAlphabet(pattern) {
  class BitapSearch (line 2027) | class BitapSearch {
    method constructor (line 2028) | constructor(pattern, {
    method searchIn (line 2077) | searchIn(text) {
  class BaseMatch (line 2146) | class BaseMatch {
    method constructor (line 2147) | constructor(pattern) {
    method isMultiMatch (line 2150) | static isMultiMatch(pattern) {
    method isSingleMatch (line 2153) | static isSingleMatch(pattern) {
    method search (line 2156) | search( /*text*/) {}
  function getMatch (line 2158) | function getMatch(pattern, exp) {
  class ExactMatch (line 2165) | class ExactMatch extends BaseMatch {
    method constructor (line 2166) | constructor(pattern) {
    method type (line 2169) | static get type() {
    method multiRegex (line 2172) | static get multiRegex() {
    method singleRegex (line 2175) | static get singleRegex() {
    method search (line 2178) | search(text) {
  class InverseExactMatch (line 2190) | class InverseExactMatch extends BaseMatch {
    method constructor (line 2191) | constructor(pattern) {
    method type (line 2194) | static get type() {
    method multiRegex (line 2197) | static get multiRegex() {
    method singleRegex (line 2200) | static get singleRegex() {
    method search (line 2203) | search(text) {
  class PrefixExactMatch (line 2216) | class PrefixExactMatch extends BaseMatch {
    method constructor (line 2217) | constructor(pattern) {
    method type (line 2220) | static get type() {
    method multiRegex (line 2223) | static get multiRegex() {
    method singleRegex (line 2226) | static get singleRegex() {
    method search (line 2229) | search(text) {
  class InversePrefixExactMatch (line 2241) | class InversePrefixExactMatch extends BaseMatch {
    method constructor (line 2242) | constructor(pattern) {
    method type (line 2245) | static get type() {
    method multiRegex (line 2248) | static get multiRegex() {
    method singleRegex (line 2251) | static get singleRegex() {
    method search (line 2254) | search(text) {
  class SuffixExactMatch (line 2266) | class SuffixExactMatch extends BaseMatch {
    method constructor (line 2267) | constructor(pattern) {
    method type (line 2270) | static get type() {
    method multiRegex (line 2273) | static get multiRegex() {
    method singleRegex (line 2276) | static get singleRegex() {
    method search (line 2279) | search(text) {
  class InverseSuffixExactMatch (line 2291) | class InverseSuffixExactMatch extends BaseMatch {
    method constructor (line 2292) | constructor(pattern) {
    method type (line 2295) | static get type() {
    method multiRegex (line 2298) | static get multiRegex() {
    method singleRegex (line 2301) | static get singleRegex() {
    method search (line 2304) | search(text) {
  class FuzzyMatch (line 2313) | class FuzzyMatch extends BaseMatch {
    method constructor (line 2314) | constructor(pattern, {
    method type (line 2336) | static get type() {
    method multiRegex (line 2339) | static get multiRegex() {
    method singleRegex (line 2342) | static get singleRegex() {
    method search (line 2345) | search(text) {
  class IncludeMatch (line 2352) | class IncludeMatch extends BaseMatch {
    method constructor (line 2353) | constructor(pattern) {
    method type (line 2356) | static get type() {
    method multiRegex (line 2359) | static get multiRegex() {
    method singleRegex (line 2362) | static get singleRegex() {
    method search (line 2365) | search(text) {
  constant SPACE_RE (line 2390) | const SPACE_RE = / +(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/;
  constant OR_TOKEN (line 2391) | const OR_TOKEN = '|';
  function parseQuery (line 2396) | function parseQuery(pattern, options = {}) {
  class ExtendedSearch (line 2465) | class ExtendedSearch {
    method constructor (line 2466) | constructor(pattern, {
    method condition (line 2490) | static condition(_, options) {
    method searchIn (line 2493) | searchIn(text) {
  function register (line 2566) | function register(...args) {
  function createSearcher (line 2569) | function createSearcher(pattern, options) {
  function parse (line 2597) | function parse(query, options, {
  function computeScore (line 2642) | function computeScore(results, {
  function transformMatches (line 2658) | function transformMatches(result, data) {
  function transformScore (line 2685) | function transformScore(result, data) {
  function format (line 2688) | function format(results, docs, {
  class Fuse (line 2711) | class Fuse {
    method constructor (line 2712) | constructor(docs, options = {}, index) {
    method setCollection (line 2718) | setCollection(docs, index) {
    method add (line 2728) | add(doc) {
    method remove (line 2735) | remove(predicate = ( /* doc, idx */) => false) {
    method removeAt (line 2748) | removeAt(idx) {
    method getIndex (line 2752) | getIndex() {
    method search (line 2755) | search(query, {
    method _searchStringList (line 2780) | _searchStringList(query) {
    method _searchLogical (line 2816) | _searchLogical(query) {
    method _searchObjectList (line 2879) | _searchObjectList(query) {
    method _findMatches (line 2915) | _findMatches({
  function SearchByFuse (line 2984) | function SearchByFuse(config) {
  function getSearcher (line 3019) | function getSearcher(config) {
  function Choices (line 3345) | function Choices(element, userConfig) {
  method options (line 3489) | get options() {
  method allOptions (line 3492) | get allOptions() {
  method templates (line 3495) | get templates() {

FILE: public/assets/scripts/choices.search-basic.js
  function __extends (line 35) | function __extends(d, b) {
  function __spreadArray (line 53) | function __spreadArray(to, from, pack) {
  function Dropdown (line 348) | function Dropdown(_a) {
  function Container (line 377) | function Container(_a) {
  function Input (line 497) | function Input(_a) {
  function List (line 613) | function List(_a) {
  function WrappedElement (line 685) | function WrappedElement(_a) {
  function WrappedInput (line 765) | function WrappedInput() {
  function WrappedSelect (line 841) | function WrappedSelect(_a) {
  function items (line 1032) | function items(s, action, context) {
  function groups (line 1087) | function groups(s, action) {
  function choices (line 1108) | function choices(s, action, context) {
  function Store (line 1180) | function Store(context) {
  function _defineProperty (line 1369) | function _defineProperty(e, r, t) {
  function ownKeys (line 1377) | function ownKeys(e, r) {
  function _objectSpread2 (line 1387) | function _objectSpread2(e) {
  function _toPrimitive (line 1398) | function _toPrimitive(t, r) {
  function _toPropertyKey (line 1408) | function _toPropertyKey(t) {
  function isArray (line 1422) | function isArray(value) {
  function baseToString (line 1425) | function baseToString(value) {
  function toString (line 1433) | function toString(value) {
  function isString (line 1436) | function isString(value) {
  function isNumber (line 1439) | function isNumber(value) {
  function isBoolean (line 1444) | function isBoolean(value) {
  function isObject (line 1447) | function isObject(value) {
  function isObjectLike (line 1452) | function isObjectLike(value) {
  function isDefined (line 1455) | function isDefined(value) {
  function isBlank (line 1458) | function isBlank(value) {
  function getTag (line 1464) | function getTag(value) {
  class KeyStore (line 1475) | class KeyStore {
    method constructor (line 1476) | constructor(keys) {
    method get (line 1492) | get(keyId) {
    method keys (line 1495) | keys() {
    method toJSON (line 1498) | toJSON() {
  function createKey (line 1502) | function createKey(key) {
  function createKeyPath (line 1536) | function createKeyPath(key) {
  function createKeyId (line 1539) | function createKeyId(key) {
  function get (line 1542) | function get(obj, path) {
  function norm (line 1639) | function norm(weight = 1, mantissa = 3) {
  class FuseIndex (line 1662) | class FuseIndex {
    method constructor (line 1663) | constructor({
    method setSources (line 1672) | setSources(docs = []) {
    method setIndexRecords (line 1675) | setIndexRecords(records = []) {
    method setKeys (line 1678) | setKeys(keys = []) {
    method create (line 1685) | create() {
    method add (line 1705) | add(doc) {
    method removeAt (line 1714) | removeAt(idx) {
    method getValueForItemAtKeyId (line 1722) | getValueForItemAtKeyId(item, keyId) {
    method size (line 1725) | size() {
    method _addString (line 1728) | _addString(doc, docIndex) {
    method _addObject (line 1739) | _addObject(doc, docIndex) {
    method toJSON (line 1792) | toJSON() {
  function createIndex (line 1799) | function createIndex(keys, docs, {
  function parseIndex (line 1812) | function parseIndex(data, {
  function computeScore$1 (line 1828) | function computeScore$1(pattern, {
  function convertMaskToIndices (line 1846) | function convertMaskToIndices(matchmask = [], minMatchCharLength = Confi...
  function search (line 1873) | function search(text, pattern, patternAlphabet, {
  function createPatternAlphabet (line 2027) | function createPatternAlphabet(pattern) {
  class BitapSearch (line 2035) | class BitapSearch {
    method constructor (line 2036) | constructor(pattern, {
    method searchIn (line 2085) | searchIn(text) {
  function createSearcher (line 2155) | function createSearcher(pattern, options) {
  function parse (line 2183) | function parse(query, options, {
  function computeScore (line 2228) | function computeScore(results, {
  function transformMatches (line 2244) | function transformMatches(result, data) {
  function transformScore (line 2271) | function transformScore(result, data) {
  function format (line 2274) | function format(results, docs, {
  class Fuse (line 2297) | class Fuse {
    method constructor (line 2298) | constructor(docs, options = {}, index) {
    method setCollection (line 2306) | setCollection(docs, index) {
    method add (line 2316) | add(doc) {
    method remove (line 2323) | remove(predicate = ( /* doc, idx */) => false) {
    method removeAt (line 2336) | removeAt(idx) {
    method getIndex (line 2340) | getIndex() {
    method search (line 2343) | search(query, {
    method _searchStringList (line 2368) | _searchStringList(query) {
    method _searchLogical (line 2404) | _searchLogical(query) {
    method _searchObjectList (line 2409) | _searchObjectList(query) {
    method _findMatches (line 2445) | _findMatches({
  function SearchByFuse (line 2511) | function SearchByFuse(config) {
  function getSearcher (line 2546) | function getSearcher(config) {
  function Choices (line 2872) | function Choices(element, userConfig) {
  method options (line 3016) | get options() {
  method allOptions (line 3019) | get allOptions() {
  method templates (line 3022) | get templates() {

FILE: public/assets/scripts/choices.search-basic.mjs
  function __extends (line 29) | function __extends(d, b) {
  function __spreadArray (line 47) | function __spreadArray(to, from, pack) {
  function Dropdown (line 342) | function Dropdown(_a) {
  function Container (line 371) | function Container(_a) {
  function Input (line 491) | function Input(_a) {
  function List (line 607) | function List(_a) {
  function WrappedElement (line 679) | function WrappedElement(_a) {
  function WrappedInput (line 759) | function WrappedInput() {
  function WrappedSelect (line 835) | function WrappedSelect(_a) {
  function items (line 1026) | function items(s, action, context) {
  function groups (line 1081) | function groups(s, action) {
  function choices (line 1102) | function choices(s, action, context) {
  function Store (line 1174) | function Store(context) {
  function _defineProperty (line 1363) | function _defineProperty(e, r, t) {
  function ownKeys (line 1371) | function ownKeys(e, r) {
  function _objectSpread2 (line 1381) | function _objectSpread2(e) {
  function _toPrimitive (line 1392) | function _toPrimitive(t, r) {
  function _toPropertyKey (line 1402) | function _toPropertyKey(t) {
  function isArray (line 1416) | function isArray(value) {
  function baseToString (line 1419) | function baseToString(value) {
  function toString (line 1427) | function toString(value) {
  function isString (line 1430) | function isString(value) {
  function isNumber (line 1433) | function isNumber(value) {
  function isBoolean (line 1438) | function isBoolean(value) {
  function isObject (line 1441) | function isObject(value) {
  function isObjectLike (line 1446) | function isObjectLike(value) {
  function isDefined (line 1449) | function isDefined(value) {
  function isBlank (line 1452) | function isBlank(value) {
  function getTag (line 1458) | function getTag(value) {
  constant EXTENDED_SEARCH_UNAVAILABLE (line 1461) | const EXTENDED_SEARCH_UNAVAILABLE = 'Extended search is not available';
  constant LOGICAL_SEARCH_UNAVAILABLE (line 1462) | const LOGICAL_SEARCH_UNAVAILABLE = 'Logical search is not available';
  constant INCORRECT_INDEX_TYPE (line 1463) | const INCORRECT_INDEX_TYPE = "Incorrect 'index' type";
  class KeyStore (line 1469) | class KeyStore {
    method constructor (line 1470) | constructor(keys) {
    method get (line 1486) | get(keyId) {
    method keys (line 1489) | keys() {
    method toJSON (line 1492) | toJSON() {
  function createKey (line 1496) | function createKey(key) {
  function createKeyPath (line 1530) | function createKeyPath(key) {
  function createKeyId (line 1533) | function createKeyId(key) {
  function get (line 1536) | function get(obj, path) {
  constant SPACE (line 1629) | const SPACE = /[^ ]+/g;
  function norm (line 1633) | function norm(weight = 1, mantissa = 3) {
  class FuseIndex (line 1656) | class FuseIndex {
    method constructor (line 1657) | constructor({
    method setSources (line 1666) | setSources(docs = []) {
    method setIndexRecords (line 1669) | setIndexRecords(records = []) {
    method setKeys (line 1672) | setKeys(keys = []) {
    method create (line 1679) | create() {
    method add (line 1699) | add(doc) {
    method removeAt (line 1708) | removeAt(idx) {
    method getValueForItemAtKeyId (line 1716) | getValueForItemAtKeyId(item, keyId) {
    method size (line 1719) | size() {
    method _addString (line 1722) | _addString(doc, docIndex) {
    method _addObject (line 1733) | _addObject(doc, docIndex) {
    method toJSON (line 1786) | toJSON() {
  function createIndex (line 1793) | function createIndex(keys, docs, {
  function parseIndex (line 1806) | function parseIndex(data, {
  function computeScore$1 (line 1822) | function computeScore$1(pattern, {
  function convertMaskToIndices (line 1840) | function convertMaskToIndices(matchmask = [], minMatchCharLength = Confi...
  constant MAX_BITS (line 1866) | const MAX_BITS = 32;
  function search (line 1867) | function search(text, pattern, patternAlphabet, {
  function createPatternAlphabet (line 2021) | function createPatternAlphabet(pattern) {
  class BitapSearch (line 2029) | class BitapSearch {
    method constructor (line 2030) | constructor(pattern, {
    method searchIn (line 2079) | searchIn(text) {
  function createSearcher (line 2149) | function createSearcher(pattern, options) {
  function parse (line 2177) | function parse(query, options, {
  function computeScore (line 2222) | function computeScore(results, {
  function transformMatches (line 2238) | function transformMatches(result, data) {
  function transformScore (line 2265) | function transformScore(result, data) {
  function format (line 2268) | function format(results, docs, {
  class Fuse (line 2291) | class Fuse {
    method constructor (line 2292) | constructor(docs, options = {}, index) {
    method setCollection (line 2300) | setCollection(docs, index) {
    method add (line 2310) | add(doc) {
    method remove (line 2317) | remove(predicate = ( /* doc, idx */) => false) {
    method removeAt (line 2330) | removeAt(idx) {
    method getIndex (line 2334) | getIndex() {
    method search (line 2337) | search(query, {
    method _searchStringList (line 2362) | _searchStringList(query) {
    method _searchLogical (line 2398) | _searchLogical(query) {
    method _searchObjectList (line 2403) | _searchObjectList(query) {
    method _findMatches (line 2439) | _findMatches({
  function SearchByFuse (line 2505) | function SearchByFuse(config) {
  function getSearcher (line 2540) | function getSearcher(config) {
  function Choices (line 2866) | function Choices(element, userConfig) {
  method options (line 3010) | get options() {
  method allOptions (line 3013) | get allOptions() {
  method templates (line 3016) | get templates() {

FILE: public/assets/scripts/choices.search-kmp.js
  function __extends (line 35) | function __extends(d, b) {
  function Dropdown (line 339) | function Dropdown(_a) {
  function Container (line 368) | function Container(_a) {
  function Input (line 488) | function Input(_a) {
  function List (line 604) | function List(_a) {
  function WrappedElement (line 676) | function WrappedElement(_a) {
  function WrappedInput (line 756) | function WrappedInput() {
  function WrappedSelect (line 832) | function WrappedSelect(_a) {
  function items (line 1023) | function items(s, action, context) {
  function groups (line 1078) | function groups(s, action) {
  function choices (line 1099) | function choices(s, action, context) {
  function Store (line 1171) | function Store(context) {
  function kmpSearch (line 1360) | function kmpSearch(pattern, text) {
  function SearchByKMP (line 1392) | function SearchByKMP(config) {
  function getSearcher (line 1433) | function getSearcher(config) {
  function Choices (line 1759) | function Choices(element, userConfig) {
  method options (line 1903) | get options() {
  method allOptions (line 1906) | get allOptions() {
  method templates (line 1909) | get templates() {

FILE: public/assets/scripts/choices.search-kmp.mjs
  function __extends (line 29) | function __extends(d, b) {
  function Dropdown (line 333) | function Dropdown(_a) {
  function Container (line 362) | function Container(_a) {
  function Input (line 482) | function Input(_a) {
  function List (line 598) | function List(_a) {
  function WrappedElement (line 670) | function WrappedElement(_a) {
  function WrappedInput (line 750) | function WrappedInput() {
  function WrappedSelect (line 826) | function WrappedSelect(_a) {
  function items (line 1017) | function items(s, action, context) {
  function groups (line 1072) | function groups(s, action) {
  function choices (line 1093) | function choices(s, action, context) {
  function Store (line 1165) | function Store(context) {
  function kmpSearch (line 1354) | function kmpSearch(pattern, text) {
  function SearchByKMP (line 1386) | function SearchByKMP(config) {
  function getSearcher (line 1427) | function getSearcher(config) {
  function Choices (line 1753) | function Choices(element, userConfig) {
  method options (line 1897) | get options() {
  method allOptions (line 1900) | get allOptions() {
  method templates (line 1903) | get templates() {

FILE: public/assets/scripts/choices.search-prefix.js
  function __extends (line 35) | function __extends(d, b) {
  function Dropdown (line 339) | function Dropdown(_a) {
  function Container (line 368) | function Container(_a) {
  function Input (line 488) | function Input(_a) {
  function List (line 604) | function List(_a) {
  function WrappedElement (line 676) | function WrappedElement(_a) {
  function WrappedInput (line 756) | function WrappedInput() {
  function WrappedSelect (line 832) | function WrappedSelect(_a) {
  function items (line 1023) | function items(s, action, context) {
  function groups (line 1078) | function groups(s, action) {
  function choices (line 1099) | function choices(s, action, context) {
  function Store (line 1171) | function Store(context) {
  function SearchByPrefixFilter (line 1361) | function SearchByPrefixFilter(config) {
  function getSearcher (line 1393) | function getSearcher(config) {
  function Choices (line 1717) | function Choices(element, userConfig) {
  method options (line 1861) | get options() {
  method allOptions (line 1864) | get allOptions() {
  method templates (line 1867) | get templates() {

FILE: public/assets/scripts/choices.search-prefix.mjs
  function __extends (line 29) | function __extends(d, b) {
  function Dropdown (line 333) | function Dropdown(_a) {
  function Container (line 362) | function Container(_a) {
  function Input (line 482) | function Input(_a) {
  function List (line 598) | function List(_a) {
  function WrappedElement (line 670) | function WrappedElement(_a) {
  function WrappedInput (line 750) | function WrappedInput() {
  function WrappedSelect (line 826) | function WrappedSelect(_a) {
  function items (line 1017) | function items(s, action, context) {
  function groups (line 1072) | function groups(s, action) {
  function choices (line 1093) | function choices(s, action, context) {
  function Store (line 1165) | function Store(context) {
  function SearchByPrefixFilter (line 1355) | function SearchByPrefixFilter(config) {
  function getSearcher (line 1387) | function getSearcher(config) {
  function Choices (line 1711) | function Choices(element, userConfig) {
  method options (line 1855) | get options() {
  method allOptions (line 1858) | get allOptions() {
  method templates (line 1861) | get templates() {

FILE: public/types/src/scripts/actions/choices.d.ts
  type ChoiceActions (line 5) | type ChoiceActions = AddChoiceAction | RemoveChoiceAction | FilterChoice...
  type AddChoiceAction (line 6) | interface AddChoiceAction extends AnyAction<typeof ActionType.ADD_CHOICE> {
  type RemoveChoiceAction (line 9) | interface RemoveChoiceAction extends AnyAction<typeof ActionType.REMOVE_...
  type FilterChoicesAction (line 12) | interface FilterChoicesAction extends AnyAction<typeof ActionType.FILTER...
  type ActivateChoicesAction (line 15) | interface ActivateChoicesAction extends AnyAction<typeof ActionType.ACTI...
  type ClearChoicesAction (line 21) | interface ClearChoicesAction extends AnyAction<typeof ActionType.CLEAR_C...

FILE: public/types/src/scripts/actions/groups.d.ts
  type GroupActions (line 4) | type GroupActions = AddGroupAction;
  type AddGroupAction (line 5) | interface AddGroupAction extends AnyAction<typeof ActionType.ADD_GROUP> {

FILE: public/types/src/scripts/actions/items.d.ts
  type ItemActions (line 4) | type ItemActions = AddItemAction | RemoveItemAction | HighlightItemAction;
  type AddItemAction (line 5) | interface AddItemAction extends AnyAction<typeof ActionType.ADD_ITEM> {
  type RemoveItemAction (line 8) | interface RemoveItemAction extends AnyAction<typeof ActionType.REMOVE_IT...
  type HighlightItemAction (line 11) | interface HighlightItemAction extends AnyAction<typeof ActionType.HIGHLI...

FILE: public/types/src/scripts/choices.d.ts
  class Choices (line 17) | class Choices {

FILE: public/types/src/scripts/components/container.d.ts
  class Container (line 4) | class Container {

FILE: public/types/src/scripts/components/dropdown.d.ts
  class Dropdown (line 3) | class Dropdown {

FILE: public/types/src/scripts/components/input.d.ts
  class Input (line 3) | class Input {

FILE: public/types/src/scripts/components/list.d.ts
  class List (line 1) | class List {

FILE: public/types/src/scripts/components/wrapped-element.d.ts
  class WrappedElement (line 4) | class WrappedElement<T extends HTMLInputElement | HTMLSelectElement> {

FILE: public/types/src/scripts/components/wrapped-input.d.ts
  class WrappedInput (line 2) | class WrappedInput extends WrappedElement<HTMLInputElement> {

FILE: public/types/src/scripts/components/wrapped-select.d.ts
  class WrappedSelect (line 5) | class WrappedSelect extends WrappedElement<HTMLSelectElement> {

FILE: public/types/src/scripts/interfaces/action-type.d.ts
  type ActionTypes (line 13) | type ActionTypes = Types.ValueOf<typeof ActionType>;

FILE: public/types/src/scripts/interfaces/choice-full.d.ts
  type ChoiceFull (line 5) | interface ChoiceFull {

FILE: public/types/src/scripts/interfaces/class-names.d.ts
  type ClassNames (line 2) | interface ClassNames {

FILE: public/types/src/scripts/interfaces/event-choice.d.ts
  type EventChoiceValueType (line 2) | type EventChoiceValueType<B extends boolean> = B extends true ? string :...
  type EventChoice (line 3) | interface EventChoice extends InputChoice {

FILE: public/types/src/scripts/interfaces/event-type.d.ts
  type EventTypes (line 14) | type EventTypes = Types.ValueOf<typeof EventType>;

FILE: public/types/src/scripts/interfaces/group-full.d.ts
  type GroupFull (line 2) | interface GroupFull {

FILE: public/types/src/scripts/interfaces/input-choice.d.ts
  type InputChoice (line 4) | interface InputChoice {

FILE: public/types/src/scripts/interfaces/input-group.d.ts
  type InputGroup (line 3) | interface InputGroup {

FILE: public/types/src/scripts/interfaces/item.d.ts
  type Item (line 6) | interface Item extends InputChoice {
  type Choice (line 11) | interface Choice extends InputChoice {
  type Group (line 16) | interface Group extends InputGroup {

FILE: public/types/src/scripts/interfaces/options.d.ts
  type Options (line 17) | interface Options {

FILE: public/types/src/scripts/interfaces/passed-element-type.d.ts
  type PassedElementType (line 7) | type PassedElementType = Types.ValueOf<typeof PassedElementTypes>;

FILE: public/types/src/scripts/interfaces/passed-element.d.ts
  type EventMap (line 6) | interface EventMap {

FILE: public/types/src/scripts/interfaces/position-options-type.d.ts
  type PositionOptionsType (line 1) | type PositionOptionsType = 'auto' | 'top' | 'bottom';

FILE: public/types/src/scripts/interfaces/search.d.ts
  type SearchResult (line 1) | interface SearchResult<T extends object> {
  type Searcher (line 6) | interface Searcher<T extends object> {

FILE: public/types/src/scripts/interfaces/state.d.ts
  type State (line 3) | interface State {
  type StateChangeSet (line 8) | type StateChangeSet = {

FILE: public/types/src/scripts/interfaces/store.d.ts
  type AnyAction (line 5) | interface AnyAction<A extends ActionTypes = ActionTypes> {
  type StateUpdate (line 8) | interface StateUpdate<T> {
  type Reducer (line 12) | type Reducer<T> = (state: T, action: AnyAction, context?: unknown) => St...
  type StoreListener (line 13) | type StoreListener = (changes: StateChangeSet) => void;
  type Store (line 14) | interface Store {

FILE: public/types/src/scripts/interfaces/string-pre-escaped.d.ts
  type StringPreEscaped (line 1) | interface StringPreEscaped {

FILE: public/types/src/scripts/interfaces/string-untrusted.d.ts
  type StringUntrusted (line 1) | interface StringUntrusted {

FILE: public/types/src/scripts/interfaces/templates.d.ts
  type TemplateOptions (line 7) | type TemplateOptions = Pick<Options, 'classNames' | 'allowHTML' | 'remov...
  type NoticeType (line 14) | type NoticeType = Types.ValueOf<typeof NoticeTypes>;
  type CallbackOnCreateTemplatesFn (line 15) | type CallbackOnCreateTemplatesFn = (template: Types.StrToEl, escapeForTe...
  type Templates (line 16) | interface Templates {

FILE: public/types/src/scripts/interfaces/types.d.ts
  type StrToEl (line 5) | type StrToEl = (str: string) => HTMLElement | HTMLInputElement | HTMLOpt...
  type EscapeForTemplateFn (line 6) | type EscapeForTemplateFn = (allowHTML: boolean, s: StringUntrusted | Str...
  type GetClassNamesFn (line 7) | type GetClassNamesFn = (s: string | Array<string>) => string;
  type StringFunction (line 8) | type StringFunction = () => string;
  type NoticeStringFunction (line 9) | type NoticeStringFunction = (value: string, valueRaw: string, item?: Eve...
  type NoticeLimitFunction (line 10) | type NoticeLimitFunction = (maxItemCount: number) => string;
  type FilterFunction (line 11) | type FilterFunction = (value: string) => boolean;
  type ValueCompareFunction (line 12) | type ValueCompareFunction = (value1: string, value2: string) => boolean;
  type RecordToCompare (line 13) | interface RecordToCompare {
  type ValueOf (line 17) | type ValueOf<T extends object> = T[keyof T];
  type CustomProperties (line 18) | type CustomProperties = Record<string, any> | string;

FILE: public/types/src/scripts/lib/choice-input.d.ts
  type MappedInputTypeToChoiceType (line 5) | type MappedInputTypeToChoiceType<T extends string | InputChoice | InputG...

FILE: public/types/src/scripts/reducers/choices.d.ts
  type ActionTypes (line 5) | type ActionTypes = ChoiceActions | ItemActions;
  type StateType (line 6) | type StateType = State['choices'];

FILE: public/types/src/scripts/reducers/groups.d.ts
  type ActionTypes (line 5) | type ActionTypes = ChoiceActions | GroupActions;
  type StateType (line 6) | type StateType = State['groups'];

FILE: public/types/src/scripts/reducers/items.d.ts
  type ActionTypes (line 6) | type ActionTypes = ChoiceActions | ItemActions;
  type StateType (line 7) | type StateType = State['items'];

FILE: public/types/src/scripts/search/fuse.d.ts
  class SearchByFuse (line 5) | class SearchByFuse<T extends object> implements Searcher<T> {

FILE: public/types/src/scripts/search/kmp.d.ts
  class SearchByKMP (line 3) | class SearchByKMP<T extends object> implements Searcher<T> {

FILE: public/types/src/scripts/search/prefix-filter.d.ts
  class SearchByPrefixFilter (line 3) | class SearchByPrefixFilter<T extends object> implements Searcher<T> {

FILE: public/types/src/scripts/store/store.d.ts
  class Store (line 5) | class Store<T> implements IStore {

FILE: scripts/rollup.config.mjs
  constant OUTPUT_TYPES (line 77) | const OUTPUT_TYPES = (process.env.OUTPUT_TYPES || Object.keys(outputType...
  constant FILENAME (line 79) | const FILENAME = 'choices'
  constant VERSION (line 80) | const VERSION = process.env.VERSION || pckg.version
  constant AUTHOR (line 81) | const AUTHOR = pckg.author
  constant HOMEPAGE (line 82) | const HOMEPAGE = pckg.homepage
  function genConfig (line 107) | function genConfig(buildConfig) {

FILE: scripts/server.mjs
  function server (line 3) | function server() {

FILE: src/scripts/actions/choices.ts
  type ChoiceActions (line 6) | type ChoiceActions =
  type AddChoiceAction (line 13) | interface AddChoiceAction extends AnyAction<typeof ActionType.ADD_CHOICE> {
  type RemoveChoiceAction (line 17) | interface RemoveChoiceAction extends AnyAction<typeof ActionType.REMOVE_...
  type FilterChoicesAction (line 21) | interface FilterChoicesAction extends AnyAction<typeof ActionType.FILTER...
  type ActivateChoicesAction (line 25) | interface ActivateChoicesAction extends AnyAction<typeof ActionType.ACTI...
  type ClearChoicesAction (line 32) | interface ClearChoicesAction extends AnyAction<typeof ActionType.CLEAR_C...

FILE: src/scripts/actions/groups.ts
  type GroupActions (line 5) | type GroupActions = AddGroupAction;
  type AddGroupAction (line 7) | interface AddGroupAction extends AnyAction<typeof ActionType.ADD_GROUP> {

FILE: src/scripts/actions/items.ts
  type ItemActions (line 5) | type ItemActions = AddItemAction | RemoveItemAction | HighlightItemAction;
  type AddItemAction (line 7) | interface AddItemAction extends AnyAction<typeof ActionType.ADD_ITEM> {
  type RemoveItemAction (line 11) | interface RemoveItemAction extends AnyAction<typeof ActionType.REMOVE_IT...
  type HighlightItemAction (line 15) | interface HighlightItemAction extends AnyAction<typeof ActionType.HIGHLI...

FILE: src/scripts/choices.ts
  constant IS_IE11 (line 42) | const IS_IE11 =
  constant USER_DEFAULTS (line 47) | const USER_DEFAULTS: Partial<Options> = {};
  class Choices (line 63) | class Choices {
    method defaults (line 66) | static get defaults(): {
    method constructor (line 161) | constructor(
    method init (line 328) | init(): void {
    method destroy (line 363) | destroy(): void {
    method enable (line 381) | enable(): this {
    method disable (line 395) | disable(): this {
    method highlightItem (line 409) | highlightItem(item: InputChoice, runEvent = true): this {
    method unhighlightItem (line 427) | unhighlightItem(item: InputChoice, runEvent = true): this {
    method highlightAll (line 445) | highlightAll(): this {
    method unhighlightAll (line 459) | unhighlightAll(): this {
    method removeActiveItemsByValue (line 473) | removeActiveItemsByValue(value: string): this {
    method removeActiveItems (line 481) | removeActiveItems(excludedId?: number): this {
    method removeHighlightedItems (line 489) | removeHighlightedItems(runEvent = false): this {
    method showDropdown (line 504) | showDropdown(preventInputFocus?: boolean): this {
    method hideDropdown (line 538) | hideDropdown(preventInputBlur?: boolean): this {
    method getValue (line 560) | getValue<B extends boolean = false>(valueOnly?: B): EventChoiceValueTy...
    method setValue (line 568) | setValue(items: string[] | InputChoice[]): this {
    method setChoiceByValue (line 589) | setChoiceByValue(value: string | string[]): this {
    method setChoices (line 676) | setChoices(
    method refresh (line 788) | refresh(withEvents: boolean = false, selectFirstOption: boolean = fals...
    method removeChoice (line 854) | removeChoice(value: string): this {
    method clearChoices (line 871) | clearChoices(clearOptions: boolean = true, clearItems: boolean = false...
    method clearStore (line 898) | clearStore(clearOptions: boolean = true): this {
    method clearInput (line 907) | clearInput(): this {
    method _validateConfig (line 915) | _validateConfig(): void {
    method _render (line 936) | _render(changes: StateChangeSet = { choices: true, groups: true, items...
    method _renderChoices (line 952) | _renderChoices(): void {
    method _renderItems (line 1075) | _renderItems(): void {
    method _displayNotice (line 1146) | _displayNotice(text: string, type: NoticeType, openDropdown: boolean =...
    method _clearNotice (line 1177) | _clearNotice(): void {
    method _renderNotice (line 1192) | _renderNotice(fragment?: DocumentFragment): void {
    method _getChoiceForOutput (line 1208) | _getChoiceForOutput(choice: ChoiceFull, keyCode?: number): EventChoice {
    method _triggerChange (line 1212) | _triggerChange(value): void {
    method _handleButtonAction (line 1222) | _handleButtonAction(element: HTMLElement): void {
    method _handleItemAction (line 1254) | _handleItemAction(element: HTMLElement, hasShiftKey = false): void {
    method _handleChoiceAction (line 1281) | _handleChoiceAction(element: HTMLElement): boolean {
    method _handleBackspace (line 1315) | _handleBackspace(items: ChoiceFull[]): void {
    method _loadChoices (line 1340) | _loadChoices(): void {
    method _handleLoadingState (line 1366) | _handleLoadingState(setLoading = true): void {
    method _handleSearch (line 1389) | _handleSearch(value?: string): void {
    method _canAddItems (line 1409) | _canAddItems(): boolean {
    method _canCreateItem (line 1431) | _canCreateItem(value: string): boolean {
    method _searchChoices (line 1468) | _searchChoices(value: string): number | null {
    method _stopSearch (line 1502) | _stopSearch(): void {
    method _addEventListeners (line 1516) | _addEventListeners(): void {
    method _removeEventListeners (line 1578) | _removeEventListeners(): void {
    method _onKeyDown (line 1614) | _onKeyDown(event: KeyboardEvent): void {
    method _onKeyUp (line 1696) | _onKeyUp(/* event: KeyboardEvent */): void {
    method _onInput (line 1700) | _onInput(/* event: InputEvent */): void {
    method _onSelectKey (line 1733) | _onSelectKey(event: KeyboardEvent, hasItems: boolean): void {
    method _onEnterKey (line 1747) | _onEnterKey(event: KeyboardEvent, hasActiveDropdown: boolean): void {
    method _onEscapeKey (line 1815) | _onEscapeKey(event: KeyboardEvent, hasActiveDropdown: boolean): void {
    method _onDirectionKey (line 1824) | _onDirectionKey(event: KeyboardEvent, hasActiveDropdown: boolean): void {
    method _onDeleteKey (line 1868) | _onDeleteKey(event: KeyboardEvent, items: ChoiceFull[], hasFocusedInpu...
    method _onTouchMove (line 1876) | _onTouchMove(): void {
    method _onTouchEnd (line 1882) | _onTouchEnd(event: TouchEvent): void {
    method _onMouseDown (line 1907) | _onMouseDown(event: MouseEvent): void {
    method _onMouseOver (line 1944) | _onMouseOver({ target }: Pick<MouseEvent, 'target'>): void {
    method _onClick (line 1950) | _onClick({ target }: Pick<MouseEvent, 'target'>): void {
    method _onFocus (line 1978) | _onFocus({ target }: Pick<FocusEvent, 'target'>): void {
    method _onBlur (line 2005) | _onBlur({ target }: Pick<FocusEvent, 'target'>): void {
    method _onFormReset (line 2034) | _onFormReset(): void {
    method _onChange (line 2045) | _onChange(event: Event & { target: HTMLInputElement | HTMLSelectElemen...
    method _onInvalid (line 2053) | _onInvalid(): void {
    method _removeHighlightedChoices (line 2060) | _removeHighlightedChoices(): void {
    method _highlightChoice (line 2073) | _highlightChoice(el: HTMLElement | null = null): void {
    method _addItem (line 2116) | _addItem(item: ChoiceFull, withEvents: boolean = true, userTriggered =...
    method _removeItem (line 2137) | _removeItem(item: ChoiceFull): void {
    method _addChoice (line 2151) | _addChoice(choice: ChoiceFull, withEvents: boolean = true, userTrigger...
    method _addGroup (line 2185) | _addGroup(group: GroupFull, withEvents: boolean = true): void {
    method _createTemplates (line 2210) | _createTemplates(): void {
    method _createElements (line 2230) | _createElements(): void {
    method _createStructure (line 2280) | _createStructure(): void {
    method _initStore (line 2315) | _initStore(): void {
    method _addPredefinedChoices (line 2329) | _addPredefinedChoices(
    method _findAndSelectChoiceByValue (line 2366) | _findAndSelectChoiceByValue(value: string, userTriggered: boolean = fa...
    method _generatePlaceholderValue (line 2379) | _generatePlaceholderValue(): string | null {
    method _warnChoicesInitFailed (line 2398) | _warnChoicesInitFailed(caller: string): void {

FILE: src/scripts/components/container.ts
  class Container (line 6) | class Container {
    method constructor (line 23) | constructor({
    method shouldFlip (line 48) | shouldFlip(dropdownPos: number, dropdownHeight: number): boolean {
    method setActiveDescendant (line 63) | setActiveDescendant(activeDescendantID: string): void {
    method removeActiveDescendant (line 67) | removeActiveDescendant(): void {
    method open (line 71) | open(dropdownPos: number, dropdownHeight: number): void {
    method close (line 82) | close(): void {
    method addFocusState (line 95) | addFocusState(): void {
    method removeFocusState (line 99) | removeFocusState(): void {
    method addInvalidState (line 103) | addInvalidState(): void {
    method removeInvalidState (line 107) | removeInvalidState(): void {
    method enable (line 111) | enable(): void {
    method disable (line 120) | disable(): void {
    method wrap (line 129) | wrap(element: HTMLElement): void {
    method unwrap (line 143) | unwrap(element: HTMLElement): void {
    method addLoadingState (line 154) | addLoadingState(): void {
    method removeLoadingState (line 160) | removeLoadingState(): void {

FILE: src/scripts/components/dropdown.ts
  class Dropdown (line 5) | class Dropdown {
    method constructor (line 14) | constructor({
    method show (line 32) | show(): this {
    method hide (line 43) | hide(): this {

FILE: src/scripts/components/input.ts
  class Input (line 4) | class Input {
    method constructor (line 17) | constructor({
    method placeholder (line 41) | set placeholder(placeholder: string) {
    method value (line 45) | get value(): string {
    method value (line 49) | set value(value: string) {
    method addEventListeners (line 53) | addEventListeners(): void {
    method removeEventListeners (line 67) | removeEventListeners(): void {
    method enable (line 75) | enable(): void {
    method disable (line 81) | disable(): void {
    method focus (line 87) | focus(): void {
    method blur (line 93) | blur(): void {
    method clear (line 99) | clear(setWidth = true): this {
    method setWidth (line 112) | setWidth(): void {
    method setActiveDescendant (line 119) | setActiveDescendant(activeDescendantID: string): void {
    method removeActiveDescendant (line 123) | removeActiveDescendant(): void {
    method _onInput (line 127) | _onInput(): void {
    method _onPaste (line 133) | _onPaste(event: ClipboardEvent): void {
    method _onFocus (line 139) | _onFocus(): void {
    method _onBlur (line 143) | _onBlur(): void {

FILE: src/scripts/components/list.ts
  class List (line 3) | class List {
    method constructor (line 10) | constructor({ element }: { element: HTMLElement }) {
    method prepend (line 16) | prepend(node: Element | DocumentFragment): void {
    method scrollToTop (line 25) | scrollToTop(): void {
    method scrollToChildElement (line 29) | scrollToChildElement(element: HTMLElement, direction: 1 | -1): void {
    method _scrollDown (line 50) | _scrollDown(scrollPos: number, strength: number, destination: number):...
    method _scrollUp (line 57) | _scrollUp(scrollPos: number, strength: number, destination: number): v...
    method _animateScroll (line 64) | _animateScroll(destination: number, direction: number): void {

FILE: src/scripts/components/wrapped-element.ts
  class WrappedElement (line 6) | class WrappedElement<T extends HTMLInputElement | HTMLSelectElement> {
    method constructor (line 13) | constructor({ element, classNames }) {
    method isActive (line 19) | get isActive(): boolean {
    method dir (line 23) | get dir(): string {
    method value (line 27) | get value(): string {
    method value (line 31) | set value(value: string) {
    method conceal (line 36) | conceal(): void {
    method reveal (line 55) | reveal(): void {
    method enable (line 74) | enable(): void {
    method disable (line 80) | disable(): void {
    method triggerEvent (line 86) | triggerEvent<K extends EventTypes>(eventType: EventTypes, data?: Event...

FILE: src/scripts/components/wrapped-input.ts
  class WrappedInput (line 3) | class WrappedInput extends WrappedElement<HTMLInputElement> {}

FILE: src/scripts/components/wrapped-select.ts
  class WrappedSelect (line 9) | class WrappedSelect extends WrappedElement<HTMLSelectElement> {
    method constructor (line 16) | constructor({
    method placeholderOption (line 32) | get placeholderOption(): HTMLOptionElement | null {
    method addOptions (line 40) | addOptions(choices: ChoiceFull[]): void {
    method optionsAsChoices (line 55) | optionsAsChoices(): (ChoiceFull | GroupFull)[] {
    method _optionToChoice (line 71) | _optionToChoice(option: HTMLOptionElement): ChoiceFull {
    method _optgroupToChoice (line 104) | _optgroupToChoice(optgroup: HTMLOptGroupElement): GroupFull {

FILE: src/scripts/constants.ts
  constant SCROLLING_SPEED (line 1) | const SCROLLING_SPEED: number = 4 as const;

FILE: src/scripts/defaults.ts
  constant DEFAULT_CLASSNAMES (line 6) | const DEFAULT_CLASSNAMES: ClassNames = {
  constant DEFAULT_CONFIG (line 39) | const DEFAULT_CONFIG: Options = {

FILE: src/scripts/interfaces/action-type.ts
  type ActionTypes (line 15) | type ActionTypes = Types.ValueOf<typeof ActionType>;

FILE: src/scripts/interfaces/choice-full.ts
  type ChoiceFull (line 12) | interface ChoiceFull {

FILE: src/scripts/interfaces/class-names.ts
  type ClassNames (line 2) | interface ClassNames {

FILE: src/scripts/interfaces/event-choice.ts
  type EventChoiceValueType (line 4) | type EventChoiceValueType<B extends boolean> = B extends true ? string :...
  type EventChoice (line 6) | interface EventChoice extends InputChoice {

FILE: src/scripts/interfaces/event-type.ts
  type EventTypes (line 16) | type EventTypes = Types.ValueOf<typeof EventType>;

FILE: src/scripts/interfaces/group-full.ts
  type GroupFull (line 4) | interface GroupFull {

FILE: src/scripts/interfaces/input-choice.ts
  type InputChoice (line 6) | interface InputChoice {

FILE: src/scripts/interfaces/input-group.ts
  type InputGroup (line 4) | interface InputGroup {

FILE: src/scripts/interfaces/item.ts
  type Item (line 7) | interface Item extends InputChoice {}
  type Choice (line 12) | interface Choice extends InputChoice {}
  type Group (line 17) | interface Group extends InputGroup {}

FILE: src/scripts/interfaces/options.ts
  type Options (line 20) | interface Options {

FILE: src/scripts/interfaces/passed-element-type.ts
  type PassedElementType (line 9) | type PassedElementType = Types.ValueOf<typeof PassedElementTypes>;

FILE: src/scripts/interfaces/passed-element.ts
  type EventMap (line 7) | interface EventMap {

FILE: src/scripts/interfaces/position-options-type.ts
  type PositionOptionsType (line 1) | type PositionOptionsType = 'auto' | 'top' | 'bottom';

FILE: src/scripts/interfaces/search.ts
  type SearchResult (line 1) | interface SearchResult<T extends object> {
  type Searcher (line 7) | interface Searcher<T extends object> {

FILE: src/scripts/interfaces/state.ts
  type State (line 4) | interface State {
  type StateChangeSet (line 10) | type StateChangeSet = {

FILE: src/scripts/interfaces/store.ts
  type AnyAction (line 6) | interface AnyAction<A extends ActionTypes = ActionTypes> {
  type StateUpdate (line 10) | interface StateUpdate<T> {
  type Reducer (line 15) | type Reducer<T> = (state: T, action: AnyAction, context?: unknown) => St...
  type StoreListener (line 17) | type StoreListener = (changes: StateChangeSet) => void;
  type Store (line 19) | interface Store {

FILE: src/scripts/interfaces/string-pre-escaped.ts
  type StringPreEscaped (line 1) | interface StringPreEscaped {

FILE: src/scripts/interfaces/string-untrusted.ts
  type StringUntrusted (line 1) | interface StringUntrusted {

FILE: src/scripts/interfaces/templates.ts
  type TemplateOptions (line 9) | type TemplateOptions = Pick<
  type NoticeType (line 26) | type NoticeType = Types.ValueOf<typeof NoticeTypes>;
  type CallbackOnCreateTemplatesFn (line 28) | type CallbackOnCreateTemplatesFn = (
  type Templates (line 34) | interface Templates {

FILE: src/scripts/interfaces/types.ts
  type StrToEl (line 7) | type StrToEl = (str: string) => HTMLElement | HTMLInputElement | HTMLOpt...
  type EscapeForTemplateFn (line 8) | type EscapeForTemplateFn = (allowHTML: boolean, s: StringUntrusted | Str...
  type GetClassNamesFn (line 9) | type GetClassNamesFn = (s: string | Array<string>) => string;
  type StringFunction (line 10) | type StringFunction = () => string;
  type NoticeStringFunction (line 11) | type NoticeStringFunction = (value: string, valueRaw: string, item?: Eve...
  type NoticeLimitFunction (line 12) | type NoticeLimitFunction = (maxItemCount: number) => string;
  type FilterFunction (line 13) | type FilterFunction = (value: string) => boolean;
  type ValueCompareFunction (line 14) | type ValueCompareFunction = (value1: string, value2: string) => boolean;
  type RecordToCompare (line 16) | interface RecordToCompare {
  type ValueOf (line 20) | type ValueOf<T extends object> = T[keyof T];
  type CustomProperties (line 22) | type CustomProperties = Record<string, any> | string;

FILE: src/scripts/lib/choice-input.ts
  type MappedInputTypeToChoiceType (line 7) | type MappedInputTypeToChoiceType<T extends string | InputChoice | InputG...

FILE: src/scripts/reducers/choices.ts
  type ActionTypes (line 9) | type ActionTypes = ChoiceActions | ItemActions;
  type StateType (line 10) | type StateType = State['choices'];
  function choices (line 12) | function choices(s: StateType, action: ActionTypes, context?: Options): ...

FILE: src/scripts/reducers/groups.ts
  type ActionTypes (line 7) | type ActionTypes = ChoiceActions | GroupActions;
  type StateType (line 8) | type StateType = State['groups'];
  function groups (line 10) | function groups(s: StateType, action: ActionTypes): StateUpdate<StateTyp...

FILE: src/scripts/reducers/items.ts
  type ActionTypes (line 10) | type ActionTypes = ChoiceActions | ItemActions;
  type StateType (line 11) | type StateType = State['items'];
  function items (line 21) | function items(s: StateType, action: ActionTypes, context?: Options): St...

FILE: src/scripts/search/fuse.ts
  class SearchByFuse (line 9) | class SearchByFuse<T extends object> implements Searcher<T> {
    method constructor (line 16) | constructor(config: Options) {
    method index (line 24) | index(data: T[]): void {
    method reset (line 31) | reset(): void {
    method isEmptyIndex (line 36) | isEmptyIndex(): boolean {
    method search (line 40) | search(needle: string): SearchResult<T>[] {

FILE: src/scripts/search/index.ts
  function getSearcher (line 8) | function getSearcher<T extends object>(config: Options): Searcher<T> {

FILE: src/scripts/search/kmp.ts
  function kmpSearch (line 4) | function kmpSearch(pattern: string, text: string): number {
  class SearchByKMP (line 39) | class SearchByKMP<T extends object> implements Searcher<T> {
    method constructor (line 44) | constructor(config: Options) {
    method index (line 48) | index(data: T[]): void {
    method reset (line 52) | reset(): void {
    method isEmptyIndex (line 56) | isEmptyIndex(): boolean {
    method search (line 60) | search(_needle: string): SearchResult<T>[] {

FILE: src/scripts/search/prefix-filter.ts
  class SearchByPrefixFilter (line 4) | class SearchByPrefixFilter<T extends object> implements Searcher<T> {
    method constructor (line 9) | constructor(config: Options) {
    method index (line 13) | index(data: T[]): void {
    method reset (line 17) | reset(): void {
    method isEmptyIndex (line 21) | isEmptyIndex(): boolean {
    method search (line 25) | search(_needle: string): SearchResult<T>[] {

FILE: src/scripts/store/store.ts
  type ReducerList (line 10) | type ReducerList = { [K in keyof State]: Reducer<State[K]> };
  class Store (line 18) | class Store<T> implements IStore {
    method constructor (line 29) | constructor(context: T) {
    method defaultState (line 34) | get defaultState(): State {
    method changeSet (line 43) | changeSet(init: boolean): StateChangeSet {
    method reset (line 51) | reset(): void {
    method subscribe (line 61) | subscribe(onChange: StoreListener): this {
    method dispatch (line 67) | dispatch(action: AnyAction): void {
    method withTxn (line 90) | withTxn(func: () => void): void {
    method state (line 110) | get state(): State {
    method items (line 117) | get items(): ChoiceFull[] {
    method highlightedActiveItems (line 124) | get highlightedActiveItems(): ChoiceFull[] {
    method choices (line 131) | get choices(): ChoiceFull[] {
    method activeChoices (line 138) | get activeChoices(): ChoiceFull[] {
    method searchableChoices (line 145) | get searchableChoices(): ChoiceFull[] {
    method groups (line 154) | get groups(): GroupFull[] {
    method activeGroups (line 161) | get activeGroups(): GroupFull[] {
    method inTxn (line 170) | inTxn(): boolean {
    method getChoiceById (line 177) | getChoiceById(id: number): ChoiceFull | undefined {
    method getGroupById (line 184) | getGroupById(id: number): GroupFull | undefined {

FILE: src/scripts/templates.ts
  method containerOuter (line 65) | containerOuter(
  method containerInner (line 106) | containerInner({ classNames: { containerInner } }: TemplateOptions): HTM...
  method itemList (line 113) | itemList(
  method placeholder (line 128) | placeholder(
  method item (line 139) | item(
  method choiceList (line 211) | choiceList({ classNames: { list } }: TemplateOptions, isSelectOneElement...
  method choiceGroup (line 223) | choiceGroup(
  method choice (line 252) | choice(
  method input (line 331) | input(
  method dropdown (line 353) | dropdown({ classNames: { list, listDropdown } }: TemplateOptions): HTMLD...
  method notice (line 363) | notice(
  method option (line 396) | option(choice: ChoiceFull): HTMLOptionElement {

FILE: test-e2e/bundle-test.ts
  type BundleTest (line 3) | type BundleTest = {

FILE: test-e2e/select-test-suit.ts
  class SelectTestSuit (line 4) | class SelectTestSuit extends TestSuit {
    method constructor (line 13) | constructor(page: Page, choicesBundle: string | undefined, url: string...
    method startWithClick (line 22) | async startWithClick(): Promise<void> {
    method delayData (line 28) | async delayData(): Promise<() => void> {
    method delayDisaabledData (line 52) | async delayDisaabledData(): Promise<() => void> {
    method getWrappedElement (line 77) | getWrappedElement(): Locator {
    method expectChoiceCount (line 81) | async expectChoiceCount(count: number): Promise<void> {
    method getChoiceWithText (line 85) | getChoiceWithText(text: string): Locator {

FILE: test-e2e/test-suit.ts
  class TestSuit (line 5) | class TestSuit {
    method constructor (line 26) | constructor(page: Page, choicesBundle: string | undefined, url: string...
    method logConsole (line 39) | logConsole(): void {
    method start (line 46) | async start(textInput?: string): Promise<void> {
    method advanceClock (line 70) | async advanceClock(): Promise<void> {
    method selectByKeyPress (line 75) | async selectByKeyPress(textInput: string): Promise<void> {
    method selectByClick (line 83) | async selectByClick(): Promise<void> {
    method typeTextAndEnter (line 89) | async typeTextAndEnter(textInput: string): Promise<void> {
    method typeText (line 94) | async typeText(textInput: string): Promise<void> {
    method keyPress (line 102) | async keyPress(key: string, _locator?: Locator): Promise<void> {
    method ctrlA (line 110) | ctrlA(locator?: Locator): Promise<void> {
    method ctrlX (line 114) | ctrlX(locator?: Locator): Promise<void> {
    method ctrlC (line 118) | ctrlC(locator?: Locator): Promise<void> {
    method ctrlV (line 122) | ctrlV(locator?: Locator): Promise<void> {
    method enterKey (line 126) | enterKey(locator?: Locator): Promise<void> {
    method escapeKey (line 130) | escapeKey(locator?: Locator): Promise<void> {
    method backspaceKey (line 134) | backspaceKey(locator?: Locator): Promise<void> {
    method expectVisibleDropdown (line 138) | async expectVisibleDropdown(): Promise<void> {
    method expectVisibleDropdownWithItem (line 145) | async expectVisibleDropdownWithItem(text: string): Promise<void> {
    method expectVisibleNoticeHtml (line 152) | async expectVisibleNoticeHtml(html: string, singleItem: boolean = fals...
    method expectHiddenDropdown (line 162) | async expectHiddenDropdown(): Promise<void> {
    method expectHiddenNotice (line 168) | async expectHiddenNotice(singleItem: boolean = false): Promise<void> {
    method getWrappedElement (line 178) | getWrappedElement(): Locator {
    method getWrapper (line 182) | getWrapper(): Locator {
    method expectedValue (line 186) | async expectedValue(text: string): Promise<void> {
    method expectedItemCount (line 194) | async expectedItemCount(count: number): Promise<void> {
    method crossProcessLock (line 199) | async crossProcessLock(func: () => Promise<void>): Promise<void> {
    method pasteText (line 214) | async pasteText(text: string, _locator?: Locator): Promise<void> {

FILE: test-e2e/text-test-suit.ts
  class TextTestSuit (line 4) | class TextTestSuit extends TestSuit {
    method constructor (line 7) | constructor(page: Page, choicesBundle: string | undefined, url: string...
    method getWrappedElement (line 13) | getWrappedElement(): Locator {

FILE: test/scripts/search/index.test.ts
  type SearchableShape (line 9) | interface SearchableShape {

FILE: test/scripts/store/store.test.ts
  function shimStore (line 11) | function shimStore() {

FILE: test/scripts/templates.test.ts
  function expectEqualElements (line 12) | function expectEqualElements(element1, element2): void {
  function createOptionsWithPartialClasses (line 23) | function createOptionsWithPartialClasses(classNames: Partial<ClassNames>...
  function shimTemplates (line 34) | function shimTemplates(element: string): TemplatesInterface {
Condensed preview — 199 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,371K chars).
[
  {
    "path": ".browserslistrc",
    "chars": 5,
    "preview": "> 1%\n"
  },
  {
    "path": ".codebeatignore",
    "chars": 34,
    "preview": "public/**\nwebpack.config.*.js\n*.js"
  },
  {
    "path": ".codecov.yml",
    "chars": 64,
    "preview": "coverage:\n  parsers:\n    javascript:\n      enable_partials: yes\n"
  },
  {
    "path": ".editorconfig",
    "chars": 119,
    "preview": "\nroot = true\n\n[*]\nindent_style = space\nindent_size = 2\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true"
  },
  {
    "path": ".eslintrc.json",
    "chars": 3298,
    "preview": "{\n  \"parser\": \"@typescript-eslint/parser\",\n  \"plugins\": [\"@typescript-eslint\", \"prettier\", \"sort-class-members\"],\n  \"ext"
  },
  {
    "path": ".git-blame-ignore-revs",
    "chars": 549,
    "preview": "# byte shaving (hoist semi-commonly variables, remove some low level low-usage functions)\n157a47a44a01e3ce4b54ad211b1756"
  },
  {
    "path": ".gitattributes",
    "chars": 1825,
    "preview": "## GITATTRIBUTES FOR WEB PROJECTS\n#\n# These settings are for any web project.\n#\n# Details per file setting:\n#   text    "
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 990,
    "preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: bug\nassignees: ''\n\n---\n\n**Describe the "
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 608,
    "preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: feature request\nassignees: ''\n\n---\n\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "chars": 1213,
    "preview": "## Description\n\n<!--- Describe your changes in detail -->\n<!--- Why is this change required? What problem does it solve?"
  },
  {
    "path": ".github/actions-scripts/polyfills-sync.cjs",
    "chars": 484,
    "preview": "const { readFileSync } = require('fs');\nconst path = require('path');\nconst assert = require('assert');\n\nconst readme = "
  },
  {
    "path": ".github/release-drafter.yml",
    "chars": 602,
    "preview": "name-template: 'Draft (next release)'\ntag-template: 'v$NEXT_PATCH_VERSION'\nsort-direction: descending\nexclude-labels:\n  "
  },
  {
    "path": ".github/workflows/browsers.yml",
    "chars": 2002,
    "preview": "name: End-to-end tests (playwright)\non:\n  push:\n    branches: [ main ]\n    paths:\n      - 'src/**'\n      - 'test-e2e/**'"
  },
  {
    "path": ".github/workflows/bundlesize.yml",
    "chars": 1284,
    "preview": "name: Bundle size checks\n\non:\n  push:\n    branches: [ main ]\n    paths:\n      - '.github/workflows/bundlesize.yml'\n     "
  },
  {
    "path": ".github/workflows/deploy-pages.yml",
    "chars": 596,
    "preview": "name: Deploy Pages\n\non:\n  release:\n    types: [published]\n  workflow_dispatch:\n\njobs:\n  deploy-gh-pages:\n    runs-on: ub"
  },
  {
    "path": ".github/workflows/deployment.yml",
    "chars": 414,
    "preview": "name: Publish to npm\n\non:\n  release:\n    types: [published]\n\npermissions:\n  id-token: write  # Required for OIDC\n  conte"
  },
  {
    "path": ".github/workflows/lint.yml",
    "chars": 1475,
    "preview": "name: Code linting\n\non:\n  push:\n    branches: [ main ]\n    paths:\n      - '.github/workflows/lint.yml'\n      - 'src/scri"
  },
  {
    "path": ".github/workflows/polyfills-sync.yml",
    "chars": 461,
    "preview": "name: Polyfills documentation\n\non:\n  pull_request:\n    paths:\n      - 'README.md'\n      - '.browserslistrc'\n      - '.es"
  },
  {
    "path": ".github/workflows/release-drafter.yml",
    "chars": 241,
    "preview": "name: Release drafter\n\non:\n  push:\n    branches: [ main ]\n\njobs:\n  update-draft-release:\n    runs-on: ubuntu-latest\n    "
  },
  {
    "path": ".github/workflows/unit-tests.yml",
    "chars": 1389,
    "preview": "name: Unit tests\n\non:\n  push:\n    branches: [ main ]\n    paths:\n      - '.github/workflows/unit-tests.yml'\n      - 'src/"
  },
  {
    "path": ".gitignore",
    "chars": 216,
    "preview": "node_modules\nnpm-debug.log\n.DS_Store\n.idea\n.rollup.cache\ntsconfig.tsbuildinfo\n.npmrc\n.run\n\n# Test\ntests/reports\ntests/re"
  },
  {
    "path": ".nvmrc",
    "chars": 8,
    "preview": "v22.17.0"
  },
  {
    "path": ".prettierrc.json",
    "chars": 358,
    "preview": "{\n  \"printWidth\": 120,\n  \"singleQuote\": true,\n  \"trailingComma\": \"all\",\n  \"endOfLine\": \"lf\",\n  \"overrides\": [\n    {\n    "
  },
  {
    "path": ".stylelintrc.json",
    "chars": 172,
    "preview": "{\n  \"extends\": \"stylelint-config-standard-scss\",\n  \"rules\": {\n    \"media-feature-range-notation\": null,\n    \"declaration"
  },
  {
    "path": ".vscode/extensions.json",
    "chars": 500,
    "preview": "{\n  // See http://go.microsoft.com/fwlink/?LinkId=827846\n  // for the documentation about the extensions.json format\n  \""
  },
  {
    "path": ".vscode/launch.json",
    "chars": 360,
    "preview": "{\n  \"version\": \"0.2.0\",\n  \"configurations\": [\n    {\n      \"type\": \"chrome\",\n      \"request\": \"launch\",\n      \"name\": \"La"
  },
  {
    "path": ".vscode/settings.json",
    "chars": 1362,
    "preview": "{\n  \"eslint.enable\": true,\n  // prevent watch task failures on lint errors\n  \"eslint.autoFixOnSave\": true,\n  // switch o"
  },
  {
    "path": ".vscode/tasks.json",
    "chars": 1799,
    "preview": "{\n  // See https://go.microsoft.com/fwlink/?LinkId=733558\n  // for the documentation about the tasks.json format\n  \"vers"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 20721,
    "preview": "# Changelog\n\n## [11.2.0] (2026-01-05)\n\n### Features\n- Add `searchRenderSelectedChoices` configuration option to control "
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 3221,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 2842,
    "preview": "# Contributions\nIn lieu of a formal styleguide, take care to maintain the existing coding style ensuring there are no li"
  },
  {
    "path": "LICENSE",
    "chars": 1079,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2016 Josh Johnson\n\nPermission is hereby granted, free of charge, to any person obta"
  },
  {
    "path": "README.md",
    "chars": 55533,
    "preview": "# Choices.js [![Actions Status](https://github.com/Choices-js/Choices/actions/workflows/unit-tests.yml/badge.svg)](https"
  },
  {
    "path": "babel.config.json",
    "chars": 136,
    "preview": "{\n  \"presets\": [\"@babel/preset-env\", \"@babel/preset-typescript\"],\n  \"plugins\": [\n    \"@babel/plugin-transform-object-res"
  },
  {
    "path": "jsconfig.json",
    "chars": 392,
    "preview": "{\n  \"compilerOptions\": {\n    \"checkJs\": true,\n    \"target\": \"es2020\",\n    \"lib\": [\"esnext\", \"dom\"],\n    \"types\": [],\n   "
  },
  {
    "path": "package.json",
    "chars": 6248,
    "preview": "{\n  \"name\": \"choices.js\",\n  \"version\": \"11.2.1\",\n  \"description\": \"A vanilla JS customisable text input/select box plugi"
  },
  {
    "path": "playwright.config.ts",
    "chars": 3354,
    "preview": "import { defineConfig, devices } from '@playwright/test';\nimport { PlaywrightTestConfig } from 'playwright/types/test';\n"
  },
  {
    "path": "public/assets/images/browserconfig.xml",
    "chars": 236,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<browserconfig>\n  <msapplication>\n    <tile>\n      <square150x150logo src=\"/asset"
  },
  {
    "path": "public/assets/images/manifest.json",
    "chars": 208,
    "preview": "{\n\t\"name\": \"Choices.js\",\n\t\"icons\": [\n\t\t{\n\t\t\t\"src\": \"\\/assets\\/images\\/android-chrome-192x192.png\",\n\t\t\t\"sizes\": \"192x192\""
  },
  {
    "path": "public/assets/scripts/choices.js",
    "chars": 206862,
    "preview": "/*! choices.js v11.2.1 | © 2026 Josh Johnson | https://github.com/Choices-js/Choices#readme */\n\n(function (global, facto"
  },
  {
    "path": "public/assets/scripts/choices.mjs",
    "chars": 185811,
    "preview": "/*! choices.js v11.2.1 | © 2026 Josh Johnson | https://github.com/Choices-js/Choices#readme */\n\n/***********************"
  },
  {
    "path": "public/assets/scripts/choices.search-basic.js",
    "chars": 193342,
    "preview": "/*! choices.js v11.2.1 | © 2026 Josh Johnson | https://github.com/Choices-js/Choices#readme */\n\n(function (global, facto"
  },
  {
    "path": "public/assets/scripts/choices.search-basic.mjs",
    "chars": 174099,
    "preview": "/*! choices.js v11.2.1 | © 2026 Josh Johnson | https://github.com/Choices-js/Choices#readme */\n\n/***********************"
  },
  {
    "path": "public/assets/scripts/choices.search-kmp.js",
    "chars": 158957,
    "preview": "/*! choices.js v11.2.1 | © 2026 Josh Johnson | https://github.com/Choices-js/Choices#readme */\n\n(function (global, facto"
  },
  {
    "path": "public/assets/scripts/choices.search-kmp.mjs",
    "chars": 144026,
    "preview": "/*! choices.js v11.2.1 | © 2026 Josh Johnson | https://github.com/Choices-js/Choices#readme */\n\n/***********************"
  },
  {
    "path": "public/assets/scripts/choices.search-prefix.js",
    "chars": 157506,
    "preview": "/*! choices.js v11.2.1 | © 2026 Josh Johnson | https://github.com/Choices-js/Choices#readme */\n\n(function (global, facto"
  },
  {
    "path": "public/assets/scripts/choices.search-prefix.mjs",
    "chars": 142743,
    "preview": "/*! choices.js v11.2.1 | © 2026 Josh Johnson | https://github.com/Choices-js/Choices#readme */\n\n/***********************"
  },
  {
    "path": "public/assets/styles/base.css",
    "chars": 3876,
    "preview": "/* =============================================\n=            Generic styling                  =\n======================="
  },
  {
    "path": "public/assets/styles/choices.css",
    "chars": 12126,
    "preview": "/* ===============================\n=            Choices            =\n=============================== */\n.choices {\n  pos"
  },
  {
    "path": "public/index.html",
    "chars": 34983,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta\n      name=\"viewport\"\n      content=\"wi"
  },
  {
    "path": "public/robots.txt",
    "chars": 17,
    "preview": "Disallow: /test/*"
  },
  {
    "path": "public/test/data.json",
    "chars": 564,
    "preview": "[\n  {\n    \"label\": \"Label 1\",\n    \"value\": \"Value 1\"\n  },\n  {\n    \"label\": \"Label 2\",\n    \"value\": \"Value 2\"\n  },\n  {\n  "
  },
  {
    "path": "public/test/disabled-data.json",
    "chars": 964,
    "preview": "[\n  {\n    \"label\": \"Disabled Label 1\",\n    \"value\": \"Disabled Value 1\",\n    \"disabled\": true\n  },\n  {\n    \"label\": \"Disa"
  },
  {
    "path": "public/test/select-multiple/index-performance.html",
    "chars": 3508,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta\n      name=\"viewport\"\n      content=\"wi"
  },
  {
    "path": "public/test/select-multiple/index.html",
    "chars": 44023,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta\n      name=\"viewport\"\n      content=\"wi"
  },
  {
    "path": "public/test/select-one/index.html",
    "chars": 43006,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta\n      name=\"viewport\"\n      content=\"wi"
  },
  {
    "path": "public/test/text/index.html",
    "chars": 13379,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta\n      name=\"viewport\"\n      content=\"wi"
  },
  {
    "path": "public/types/src/index.d.ts",
    "chars": 236,
    "preview": "import Choices from './scripts/choices';\nexport * from './scripts/interfaces';\nexport * from './scripts/constants';\nexpo"
  },
  {
    "path": "public/types/src/scripts/actions/choices.d.ts",
    "chars": 1430,
    "preview": "import { ChoiceFull } from '../interfaces/choice-full';\nimport { ActionType } from '../interfaces';\nimport { SearchResul"
  },
  {
    "path": "public/types/src/scripts/actions/groups.d.ts",
    "chars": 364,
    "preview": "import { GroupFull } from '../interfaces/group-full';\nimport { ActionType } from '../interfaces';\nimport { AnyAction } f"
  },
  {
    "path": "public/types/src/scripts/actions/items.d.ts",
    "chars": 825,
    "preview": "import { ChoiceFull } from '../interfaces/choice-full';\nimport { ActionType } from '../interfaces';\nimport { AnyAction }"
  },
  {
    "path": "public/types/src/scripts/choices.d.ts",
    "chars": 8814,
    "preview": "import { Container, Dropdown, Input, List, WrappedInput, WrappedSelect } from './components';\nimport { InputChoice } fro"
  },
  {
    "path": "public/types/src/scripts/components/container.d.ts",
    "chars": 1304,
    "preview": "import { ClassNames } from '../interfaces/class-names';\nimport { PositionOptionsType } from '../interfaces/position-opti"
  },
  {
    "path": "public/types/src/scripts/components/dropdown.d.ts",
    "chars": 577,
    "preview": "import { ClassNames } from '../interfaces/class-names';\nimport { PassedElementType } from '../interfaces/passed-element-"
  },
  {
    "path": "public/types/src/scripts/components/index.d.ts",
    "chars": 292,
    "preview": "import Dropdown from './dropdown';\nimport Container from './container';\nimport Input from './input';\nimport List from '."
  },
  {
    "path": "public/types/src/scripts/components/input.d.ts",
    "chars": 1128,
    "preview": "import { ClassNames } from '../interfaces/class-names';\nimport { PassedElementType } from '../interfaces/passed-element-"
  },
  {
    "path": "public/types/src/scripts/components/list.d.ts",
    "chars": 545,
    "preview": "export default class List {\n    element: HTMLElement;\n    scrollPos: number;\n    height: number;\n    constructor({ eleme"
  },
  {
    "path": "public/types/src/scripts/components/wrapped-element.d.ts",
    "chars": 696,
    "preview": "import { ClassNames } from '../interfaces/class-names';\nimport { EventTypes } from '../interfaces/event-type';\nimport { "
  },
  {
    "path": "public/types/src/scripts/components/wrapped-input.d.ts",
    "chars": 127,
    "preview": "import WrappedElement from './wrapped-element';\nexport default class WrappedInput extends WrappedElement<HTMLInputElemen"
  },
  {
    "path": "public/types/src/scripts/components/wrapped-select.d.ts",
    "chars": 926,
    "preview": "import { ClassNames } from '../interfaces/class-names';\nimport WrappedElement from './wrapped-element';\nimport { GroupFu"
  },
  {
    "path": "public/types/src/scripts/constants.d.ts",
    "chars": 46,
    "preview": "export declare const SCROLLING_SPEED: number;\n"
  },
  {
    "path": "public/types/src/scripts/defaults.d.ts",
    "chars": 202,
    "preview": "import { ClassNames } from './interfaces/class-names';\nimport { Options } from './interfaces/options';\nexport declare co"
  },
  {
    "path": "public/types/src/scripts/interfaces/action-type.d.ts",
    "chars": 518,
    "preview": "import { Types } from './types';\nexport declare const ActionType: {\n    readonly ADD_CHOICE: \"ADD_CHOICE\";\n    readonly "
  },
  {
    "path": "public/types/src/scripts/interfaces/build-flags.d.ts",
    "chars": 402,
    "preview": "export declare const canUseDom: boolean;\nexport declare const searchFuse: string | undefined;\nexport declare const searc"
  },
  {
    "path": "public/types/src/scripts/interfaces/choice-full.d.ts",
    "chars": 755,
    "preview": "import { StringUntrusted } from './string-untrusted';\nimport { StringPreEscaped } from './string-pre-escaped';\nimport { "
  },
  {
    "path": "public/types/src/scripts/interfaces/class-names.d.ts",
    "chars": 2555,
    "preview": "/** Classes added to HTML generated by  By default classnames follow the BEM notation. */\nexport interface ClassNames {\n"
  },
  {
    "path": "public/types/src/scripts/interfaces/event-choice.d.ts",
    "chars": 294,
    "preview": "import { InputChoice } from './input-choice';\nexport type EventChoiceValueType<B extends boolean> = B extends true ? str"
  },
  {
    "path": "public/types/src/scripts/interfaces/event-type.d.ts",
    "chars": 522,
    "preview": "import { Types } from './types';\nexport declare const EventType: {\n    readonly showDropdown: \"showDropdown\";\n    readon"
  },
  {
    "path": "public/types/src/scripts/interfaces/group-full.d.ts",
    "chars": 244,
    "preview": "import { ChoiceFull } from './choice-full';\nexport interface GroupFull {\n    id: number;\n    active: boolean;\n    disabl"
  },
  {
    "path": "public/types/src/scripts/interfaces/index.d.ts",
    "chars": 433,
    "preview": "export * from './action-type';\nexport * from './input-choice';\nexport * from './input-group';\nexport * from './event-cho"
  },
  {
    "path": "public/types/src/scripts/interfaces/input-choice.d.ts",
    "chars": 527,
    "preview": "import { StringUntrusted } from './string-untrusted';\nimport { StringPreEscaped } from './string-pre-escaped';\nimport { "
  },
  {
    "path": "public/types/src/scripts/interfaces/input-group.d.ts",
    "chars": 280,
    "preview": "import { InputChoice } from './input-choice';\nimport { StringUntrusted } from './string-untrusted';\nexport interface Inp"
  },
  {
    "path": "public/types/src/scripts/interfaces/item.d.ts",
    "chars": 370,
    "preview": "import { InputChoice } from './input-choice';\nimport { InputGroup } from './input-group';\n/**\n * @deprecated Use InputCh"
  },
  {
    "path": "public/types/src/scripts/interfaces/keycode-map.d.ts",
    "chars": 338,
    "preview": "export declare const KeyCodeMap: {\n    readonly TAB_KEY: 9;\n    readonly SHIFT_KEY: 16;\n    readonly BACK_KEY: 46;\n    r"
  },
  {
    "path": "public/types/src/scripts/interfaces/options.d.ts",
    "chars": 20588,
    "preview": "import { IFuseOptions } from 'fuse.js';\nimport { InputChoice } from './input-choice';\nimport { ClassNames } from './clas"
  },
  {
    "path": "public/types/src/scripts/interfaces/passed-element-type.d.ts",
    "chars": 266,
    "preview": "import { Types } from './types';\nexport declare const PassedElementTypes: {\n    readonly Text: \"text\";\n    readonly Sele"
  },
  {
    "path": "public/types/src/scripts/interfaces/passed-element.d.ts",
    "chars": 2969,
    "preview": "import { InputChoice } from './input-choice';\nimport { EventChoice } from './event-choice';\n/**\n * Events fired by Choic"
  },
  {
    "path": "public/types/src/scripts/interfaces/position-options-type.d.ts",
    "chars": 61,
    "preview": "export type PositionOptionsType = 'auto' | 'top' | 'bottom';\n"
  },
  {
    "path": "public/types/src/scripts/interfaces/search.d.ts",
    "chars": 273,
    "preview": "export interface SearchResult<T extends object> {\n    item: T;\n    score: number;\n    rank: number;\n}\nexport interface S"
  },
  {
    "path": "public/types/src/scripts/interfaces/state.d.ts",
    "chars": 257,
    "preview": "import { ChoiceFull } from './choice-full';\nimport { GroupFull } from './group-full';\nexport interface State {\n    choic"
  },
  {
    "path": "public/types/src/scripts/interfaces/store.d.ts",
    "chars": 1723,
    "preview": "import { StateChangeSet, State } from './state';\nimport { ChoiceFull } from './choice-full';\nimport { GroupFull } from '"
  },
  {
    "path": "public/types/src/scripts/interfaces/string-pre-escaped.d.ts",
    "chars": 68,
    "preview": "export interface StringPreEscaped {\n    readonly trusted: string;\n}\n"
  },
  {
    "path": "public/types/src/scripts/interfaces/string-untrusted.d.ts",
    "chars": 93,
    "preview": "export interface StringUntrusted {\n    readonly escaped: string;\n    readonly raw: string;\n}\n"
  },
  {
    "path": "public/types/src/scripts/interfaces/templates.d.ts",
    "chars": 2048,
    "preview": "import { PassedElementType } from './passed-element-type';\nimport { StringPreEscaped } from './string-pre-escaped';\nimpo"
  },
  {
    "path": "public/types/src/scripts/interfaces/types.d.ts",
    "chars": 1019,
    "preview": "import { StringUntrusted } from './string-untrusted';\nimport { StringPreEscaped } from './string-pre-escaped';\nimport { "
  },
  {
    "path": "public/types/src/scripts/lib/choice-input.d.ts",
    "chars": 727,
    "preview": "import { InputChoice } from '../interfaces/input-choice';\nimport { InputGroup } from '../interfaces/input-group';\nimport"
  },
  {
    "path": "public/types/src/scripts/lib/html-guard-statements.d.ts",
    "chars": 316,
    "preview": "export declare const isHtmlInputElement: (e: Element) => e is HTMLInputElement;\nexport declare const isHtmlSelectElement"
  },
  {
    "path": "public/types/src/scripts/lib/utils.d.ts",
    "chars": 2981,
    "preview": "import { EventTypes } from '../interfaces/event-type';\nimport { StringUntrusted } from '../interfaces/string-untrusted';"
  },
  {
    "path": "public/types/src/scripts/reducers/choices.d.ts",
    "chars": 404,
    "preview": "import { Options, State } from '../interfaces';\nimport { StateUpdate } from '../interfaces/store';\nimport { ChoiceAction"
  },
  {
    "path": "public/types/src/scripts/reducers/groups.d.ts",
    "chars": 383,
    "preview": "import { GroupActions } from '../actions/groups';\nimport { State } from '../interfaces/state';\nimport { StateUpdate } fr"
  },
  {
    "path": "public/types/src/scripts/reducers/items.d.ts",
    "chars": 438,
    "preview": "import { ItemActions } from '../actions/items';\nimport { State } from '../interfaces/state';\nimport { ChoiceActions } fr"
  },
  {
    "path": "public/types/src/scripts/search/fuse.d.ts",
    "chars": 569,
    "preview": "import { default as FuseFull, IFuseOptions } from 'fuse.js';\nimport { default as FuseBasic } from 'fuse.js/basic';\nimpor"
  },
  {
    "path": "public/types/src/scripts/search/index.d.ts",
    "chars": 175,
    "preview": "import { Options } from '../interfaces';\nimport { Searcher } from '../interfaces/search';\nexport declare function getSea"
  },
  {
    "path": "public/types/src/scripts/search/kmp.d.ts",
    "chars": 383,
    "preview": "import { Options } from '../interfaces';\nimport { Searcher, SearchResult } from '../interfaces/search';\nexport declare c"
  },
  {
    "path": "public/types/src/scripts/search/prefix-filter.d.ts",
    "chars": 392,
    "preview": "import { Options } from '../interfaces';\nimport { Searcher, SearchResult } from '../interfaces/search';\nexport declare c"
  },
  {
    "path": "public/types/src/scripts/store/store.d.ts",
    "chars": 1621,
    "preview": "import { AnyAction, Store as IStore, StoreListener } from '../interfaces/store';\nimport { StateChangeSet, State } from '"
  },
  {
    "path": "public/types/src/scripts/templates.d.ts",
    "chars": 385,
    "preview": "/**\n * Helpers to create HTML elements used by Choices\n * Can be overridden by providing `callbackOnCreateTemplates` opt"
  },
  {
    "path": "scripts/lint-staged.config.js",
    "chars": 461,
    "preview": "module.exports = {\n  '*.js': ['eslint --fix --quiet -f visualstudio', 'git add'],\n  '*.{ts,scss,yaml,yml,md,html,json,ba"
  },
  {
    "path": "scripts/rollup.config.mjs",
    "chars": 5195,
    "preview": "import replace from '@rollup/plugin-replace';\nimport nodeResolve from'@rollup/plugin-node-resolve';\nimport babel from '@"
  },
  {
    "path": "scripts/server.mjs",
    "chars": 367,
    "preview": "import dev from 'rollup-plugin-dev';\n\nexport default function server() {\n  const WATCH_HOST = process.env.WATCH_HOST;\n\n "
  },
  {
    "path": "src/entry.js",
    "chars": 66,
    "preview": "import Choices from './scripts/choices';\n\nexport default Choices;\n"
  },
  {
    "path": "src/index.ts",
    "chars": 238,
    "preview": "import Choices from './scripts/choices';\n\nexport * from './scripts/interfaces';\nexport * from './scripts/constants';\nexp"
  },
  {
    "path": "src/scripts/actions/choices.ts",
    "chars": 1653,
    "preview": "import { ChoiceFull } from '../interfaces/choice-full';\nimport { ActionType } from '../interfaces';\nimport { SearchResul"
  },
  {
    "path": "src/scripts/actions/groups.ts",
    "chars": 404,
    "preview": "import { GroupFull } from '../interfaces/group-full';\nimport { ActionType } from '../interfaces';\nimport { AnyAction } f"
  },
  {
    "path": "src/scripts/actions/items.ts",
    "chars": 959,
    "preview": "import { ChoiceFull } from '../interfaces/choice-full';\nimport { ActionType } from '../interfaces';\nimport { AnyAction }"
  },
  {
    "path": "src/scripts/choices.ts",
    "chars": 72646,
    "preview": "import { activateChoices, addChoice, removeChoice, filterChoices } from './actions/choices';\nimport { addGroup } from '."
  },
  {
    "path": "src/scripts/components/container.ts",
    "chars": 4585,
    "preview": "import { addClassesToElement, removeClassesFromElement } from '../lib/utils';\nimport { ClassNames } from '../interfaces/"
  },
  {
    "path": "src/scripts/components/dropdown.ts",
    "chars": 1105,
    "preview": "import { ClassNames } from '../interfaces/class-names';\nimport { PassedElementType } from '../interfaces/passed-element-"
  },
  {
    "path": "src/scripts/components/index.ts",
    "chars": 293,
    "preview": "import Dropdown from './dropdown';\nimport Container from './container';\nimport Input from './input';\nimport List from '."
  },
  {
    "path": "src/scripts/components/input.ts",
    "chars": 3225,
    "preview": "import { ClassNames } from '../interfaces/class-names';\nimport { PassedElementType, PassedElementTypes } from '../interf"
  },
  {
    "path": "src/scripts/components/list.ts",
    "chars": 2481,
    "preview": "import { SCROLLING_SPEED } from '../constants';\n\nexport default class List {\n  element: HTMLElement;\n\n  scrollPos: numbe"
  },
  {
    "path": "src/scripts/components/wrapped-element.ts",
    "chars": 2228,
    "preview": "import { ClassNames } from '../interfaces/class-names';\nimport { EventTypes } from '../interfaces/event-type';\nimport { "
  },
  {
    "path": "src/scripts/components/wrapped-input.ts",
    "chars": 127,
    "preview": "import WrappedElement from './wrapped-element';\n\nexport default class WrappedInput extends WrappedElement<HTMLInputEleme"
  },
  {
    "path": "src/scripts/components/wrapped-select.ts",
    "chars": 4088,
    "preview": "import { parseCustomProperties } from '../lib/utils';\nimport { ClassNames } from '../interfaces/class-names';\nimport Wra"
  },
  {
    "path": "src/scripts/constants.ts",
    "chars": 51,
    "preview": "export const SCROLLING_SPEED: number = 4 as const;\n"
  },
  {
    "path": "src/scripts/defaults.ts",
    "chars": 3278,
    "preview": "import { ClassNames } from './interfaces/class-names';\nimport { Options } from './interfaces/options';\nimport { sanitise"
  },
  {
    "path": "src/scripts/interfaces/action-type.ts",
    "chars": 423,
    "preview": "import { Types } from './types';\n\nexport const ActionType = {\n  ADD_CHOICE: 'ADD_CHOICE',\n  REMOVE_CHOICE: 'REMOVE_CHOIC"
  },
  {
    "path": "src/scripts/interfaces/build-flags.ts",
    "chars": 551,
    "preview": "export const canUseDom: boolean =\n  process.env.CHOICES_CAN_USE_DOM !== undefined\n    ? process.env.CHOICES_CAN_USE_DOM "
  },
  {
    "path": "src/scripts/interfaces/choice-full.ts",
    "chars": 1033,
    "preview": "import { StringUntrusted } from './string-untrusted';\nimport { StringPreEscaped } from './string-pre-escaped';\nimport { "
  },
  {
    "path": "src/scripts/interfaces/class-names.ts",
    "chars": 2435,
    "preview": "/** Classes added to HTML generated by  By default classnames follow the BEM notation. */\nexport interface ClassNames {\n"
  },
  {
    "path": "src/scripts/interfaces/event-choice.ts",
    "chars": 334,
    "preview": "// eslint-disable-next-line import/no-cycle\nimport { InputChoice } from './input-choice';\n\nexport type EventChoiceValueT"
  },
  {
    "path": "src/scripts/interfaces/event-type.ts",
    "chars": 416,
    "preview": "import { Types } from './types';\n\nexport const EventType = {\n  showDropdown: 'showDropdown',\n  hideDropdown: 'hideDropdo"
  },
  {
    "path": "src/scripts/interfaces/group-full.ts",
    "chars": 275,
    "preview": "// eslint-disable-next-line import/no-cycle\nimport { ChoiceFull } from './choice-full';\n\nexport interface GroupFull {\n  "
  },
  {
    "path": "src/scripts/interfaces/index.ts",
    "chars": 433,
    "preview": "export * from './action-type';\nexport * from './input-choice';\nexport * from './input-group';\nexport * from './event-cho"
  },
  {
    "path": "src/scripts/interfaces/input-choice.ts",
    "chars": 610,
    "preview": "import { StringUntrusted } from './string-untrusted';\nimport { StringPreEscaped } from './string-pre-escaped';\n// eslint"
  },
  {
    "path": "src/scripts/interfaces/input-group.ts",
    "chars": 269,
    "preview": "import { InputChoice } from './input-choice';\nimport { StringUntrusted } from './string-untrusted';\n\nexport interface In"
  },
  {
    "path": "src/scripts/interfaces/item.ts",
    "chars": 370,
    "preview": "import { InputChoice } from './input-choice';\nimport { InputGroup } from './input-group';\n\n/**\n * @deprecated Use InputC"
  },
  {
    "path": "src/scripts/interfaces/keycode-map.ts",
    "chars": 219,
    "preview": "export const KeyCodeMap = {\n  TAB_KEY: 9,\n  SHIFT_KEY: 16,\n  BACK_KEY: 46,\n  DELETE_KEY: 8,\n  ENTER_KEY: 13,\n  A_KEY: 65"
  },
  {
    "path": "src/scripts/interfaces/options.ts",
    "chars": 19608,
    "preview": "import { IFuseOptions } from 'fuse.js';\nimport { InputChoice } from './input-choice';\nimport { ClassNames } from './clas"
  },
  {
    "path": "src/scripts/interfaces/passed-element-type.ts",
    "chars": 237,
    "preview": "import { Types } from './types';\n\nexport const PassedElementTypes = {\n  Text: 'text',\n  SelectOne: 'select-one',\n  Selec"
  },
  {
    "path": "src/scripts/interfaces/passed-element.ts",
    "chars": 2761,
    "preview": "import { InputChoice } from './input-choice';\nimport { EventChoice } from './event-choice';\n\n/**\n * Events fired by Choi"
  },
  {
    "path": "src/scripts/interfaces/position-options-type.ts",
    "chars": 61,
    "preview": "export type PositionOptionsType = 'auto' | 'top' | 'bottom';\n"
  },
  {
    "path": "src/scripts/interfaces/search.ts",
    "chars": 348,
    "preview": "export interface SearchResult<T extends object> {\n  item: T;\n  score: number;\n  rank: number; // values of 0 means this "
  },
  {
    "path": "src/scripts/interfaces/state.ts",
    "chars": 251,
    "preview": "import { ChoiceFull } from './choice-full';\nimport { GroupFull } from './group-full';\n\nexport interface State {\n  choice"
  },
  {
    "path": "src/scripts/interfaces/store.ts",
    "chars": 1637,
    "preview": "import { StateChangeSet, State } from './state';\nimport { ChoiceFull } from './choice-full';\nimport { GroupFull } from '"
  },
  {
    "path": "src/scripts/interfaces/string-pre-escaped.ts",
    "chars": 66,
    "preview": "export interface StringPreEscaped {\n  readonly trusted: string;\n}\n"
  },
  {
    "path": "src/scripts/interfaces/string-untrusted.ts",
    "chars": 90,
    "preview": "export interface StringUntrusted {\n  readonly escaped: string;\n\n  readonly raw: string;\n}\n"
  },
  {
    "path": "src/scripts/interfaces/templates.ts",
    "chars": 2103,
    "preview": "import { PassedElementType } from './passed-element-type';\nimport { StringPreEscaped } from './string-pre-escaped';\nimpo"
  },
  {
    "path": "src/scripts/interfaces/types.ts",
    "chars": 1167,
    "preview": "import { StringUntrusted } from './string-untrusted';\nimport { StringPreEscaped } from './string-pre-escaped';\n// eslint"
  },
  {
    "path": "src/scripts/lib/choice-input.ts",
    "chars": 2954,
    "preview": "import { InputChoice } from '../interfaces/input-choice';\nimport { InputGroup } from '../interfaces/input-group';\nimport"
  },
  {
    "path": "src/scripts/lib/html-guard-statements.ts",
    "chars": 388,
    "preview": "export const isHtmlInputElement = (e: Element): e is HTMLInputElement => e.tagName === 'INPUT';\n\nexport const isHtmlSele"
  },
  {
    "path": "src/scripts/lib/utils.ts",
    "chars": 7276,
    "preview": "import { EventTypes } from '../interfaces/event-type';\nimport { StringUntrusted } from '../interfaces/string-untrusted';"
  },
  {
    "path": "src/scripts/reducers/choices.ts",
    "chars": 2291,
    "preview": "/* eslint-disable */\nimport { ActionType, Options, State } from '../interfaces';\nimport { StateUpdate } from '../interfa"
  },
  {
    "path": "src/scripts/reducers/groups.ts",
    "chars": 734,
    "preview": "import { GroupActions } from '../actions/groups';\nimport { State } from '../interfaces/state';\nimport { ActionType } fro"
  },
  {
    "path": "src/scripts/reducers/items.ts",
    "chars": 2672,
    "preview": "import { ItemActions } from '../actions/items';\nimport { State } from '../interfaces/state';\nimport { ChoiceActions } fr"
  },
  {
    "path": "src/scripts/search/fuse.ts",
    "chars": 1576,
    "preview": "// eslint-disable-next-line import/no-named-default\nimport { default as FuseFull, IFuseOptions } from 'fuse.js';\n// esli"
  },
  {
    "path": "src/scripts/search/index.ts",
    "chars": 557,
    "preview": "import { Options } from '../interfaces';\nimport { Searcher } from '../interfaces/search';\nimport { SearchByPrefixFilter "
  },
  {
    "path": "src/scripts/search/kmp.ts",
    "chars": 2180,
    "preview": "import { Options } from '../interfaces';\nimport { Searcher, SearchResult } from '../interfaces/search';\n\nfunction kmpSea"
  },
  {
    "path": "src/scripts/search/prefix-filter.ts",
    "chars": 988,
    "preview": "import { Options } from '../interfaces';\nimport { Searcher, SearchResult } from '../interfaces/search';\n\nexport class Se"
  },
  {
    "path": "src/scripts/store/store.ts",
    "chars": 4241,
    "preview": "import { AnyAction, Reducer, Store as IStore, StoreListener } from '../interfaces/store';\nimport { StateChangeSet, State"
  },
  {
    "path": "src/scripts/templates.ts",
    "chars": 12416,
    "preview": "/**\n * Helpers to create HTML elements used by Choices\n * Can be overridden by providing `callbackOnCreateTemplates` opt"
  },
  {
    "path": "src/styles/base.scss",
    "chars": 4288,
    "preview": "/* =============================================\n=            Generic styling                  =\n======================="
  },
  {
    "path": "src/styles/choices.scss",
    "chars": 14378,
    "preview": "/* ===============================\n=            Choices            =\n=============================== */\n\n$choices-select"
  },
  {
    "path": "src/tsconfig.json",
    "chars": 541,
    "preview": "{\n  \"compilerOptions\": {\n    \"module\": \"es6\",\n    \"lib\": [\"es2017\", \"dom\"],\n    \"target\": \"es5\",\n    \"moduleResolution\":"
  },
  {
    "path": "test/scripts/actions/choices.test.ts",
    "chars": 2779,
    "preview": "import { expect } from 'chai';\nimport * as actions from '../../../src/scripts/actions/choices';\nimport { cloneObject } f"
  },
  {
    "path": "test/scripts/actions/groups.test.ts",
    "chars": 762,
    "preview": "import { expect } from 'chai';\nimport * as actions from '../../../src/scripts/actions/groups';\nimport { GroupFull } from"
  },
  {
    "path": "test/scripts/actions/items.test.ts",
    "chars": 1556,
    "preview": "import { expect } from 'chai';\nimport * as actions from '../../../src/scripts/actions/items';\nimport { cloneObject } fro"
  },
  {
    "path": "test/scripts/choices.test.ts",
    "chars": 73625,
    "preview": "import { expect } from 'chai';\nimport { spy, stub } from 'sinon';\n\nimport sinonChai from 'sinon-chai';\nimport Choices, {"
  },
  {
    "path": "test/scripts/components/container.test.ts",
    "chars": 10561,
    "preview": "import { expect } from 'chai';\nimport { stub } from 'sinon';\nimport { DEFAULT_CLASSNAMES } from '../../../src';\nimport C"
  },
  {
    "path": "test/scripts/components/dropdown.test.ts",
    "chars": 3421,
    "preview": "import { expect } from 'chai';\nimport { DEFAULT_CLASSNAMES } from '../../../src';\nimport Dropdown from '../../../src/scr"
  },
  {
    "path": "test/scripts/components/input.test.ts",
    "chars": 9167,
    "preview": "import { expect } from 'chai';\nimport { stub } from 'sinon';\nimport { DEFAULT_CLASSNAMES } from '../../../src';\nimport I"
  },
  {
    "path": "test/scripts/components/list.test.ts",
    "chars": 1198,
    "preview": "import { expect } from 'chai';\nimport List from '../../../src/scripts/components/list';\n\ndescribe('components/list', () "
  },
  {
    "path": "test/scripts/components/wrapped-element.test.ts",
    "chars": 6925,
    "preview": "import { expect } from 'chai';\nimport { getClassNames } from '../../../src/scripts/lib/utils';\nimport { DEFAULT_CLASSNAM"
  },
  {
    "path": "test/scripts/components/wrapped-input.test.ts",
    "chars": 2234,
    "preview": "import { expect } from 'chai';\nimport { stub } from 'sinon';\nimport { DEFAULT_CLASSNAMES } from '../../../src';\nimport W"
  },
  {
    "path": "test/scripts/components/wrapped-select.test.ts",
    "chars": 3848,
    "preview": "import { expect } from 'chai';\nimport { stub, spy } from 'sinon';\nimport WrappedElement from '../../../src/scripts/compo"
  },
  {
    "path": "test/scripts/lib/utils.test.ts",
    "chars": 6606,
    "preview": "/* eslint-disable no-new-wrappers */\nimport { expect } from 'chai';\nimport { stub } from 'sinon';\n\nimport {\n  cloneObjec"
  },
  {
    "path": "test/scripts/reducers/choices.test.ts",
    "chars": 4917,
    "preview": "import { expect } from 'chai';\nimport choices from '../../../src/scripts/reducers/choices';\nimport { cloneObject } from "
  },
  {
    "path": "test/scripts/reducers/groups.test.ts",
    "chars": 1000,
    "preview": "import { expect } from 'chai';\nimport groups from '../../../src/scripts/reducers/groups';\nimport { cloneObject } from '."
  },
  {
    "path": "test/scripts/reducers/items.test.ts",
    "chars": 4665,
    "preview": "import { expect } from 'chai';\nimport items from '../../../src/scripts/reducers/items';\nimport { RemoveItemAction } from"
  },
  {
    "path": "test/scripts/search/index.test.ts",
    "chars": 4927,
    "preview": "import { expect } from 'chai';\nimport { beforeEach } from 'vitest';\nimport { DEFAULT_CONFIG } from '../../../src';\nimpor"
  },
  {
    "path": "test/scripts/store/store.test.ts",
    "chars": 9742,
    "preview": "import { expect } from 'chai';\nimport sinon from 'sinon';\nimport { beforeEach } from 'vitest';\nimport Store from '../../"
  },
  {
    "path": "test/scripts/templates.test.ts",
    "chars": 22544,
    "preview": "import { expect } from 'chai';\n// eslint-disable-next-line import/no-named-default\nimport { default as _templates } from"
  },
  {
    "path": "test/setupFiles/window-matchMedia.ts",
    "chars": 455,
    "preview": "import { beforeAll } from 'vitest';\n\nbeforeAll(() => {\n  Object.defineProperty(globalThis.window, 'matchMedia', {\n    wr"
  },
  {
    "path": "test/tsconfig.json",
    "chars": 620,
    "preview": "{\n  \"compilerOptions\": {\n    \"module\": \"es6\",\n    \"lib\": [\"es2017\", \"dom\"],\n    \"target\": \"ES2020\",\n    \"moduleResolutio"
  },
  {
    "path": "test-e2e/bundle-test.ts",
    "chars": 298,
    "preview": "import { test as base } from '@playwright/test';\n\nexport type BundleTest = {\n  bundle: string | undefined;\n};\n\nexport co"
  },
  {
    "path": "test-e2e/hars/0432285dab6a62ab5e6efaf4cb1272720e0c3f1b.json",
    "chars": 27062,
    "preview": "{\"pagination\": {\"page\": 1, \"pages\": 20, \"per_page\": 50, \"items\": 980, \"urls\": {\"last\": \"https://api.discogs.com/artists/"
  },
  {
    "path": "test-e2e/hars/69c6136c671f1173ee6d6596d125e821dea44a4f.json",
    "chars": 27660,
    "preview": "{\"pagination\": {\"page\": 1, \"pages\": 8, \"per_page\": 50, \"items\": 362, \"urls\": {\"last\": \"https://api.discogs.com/artists/5"
  },
  {
    "path": "test-e2e/hars/a8763b95c9f6c98156a9100e8bed82cb17b93ecd.json",
    "chars": 27274,
    "preview": "{\"pagination\": {\"page\": 1, \"pages\": 8, \"per_page\": 50, \"items\": 386, \"urls\": {\"last\": \"https://api.discogs.com/artists/3"
  },
  {
    "path": "test-e2e/hars/discogs.har",
    "chars": 13416,
    "preview": "{\n  \"log\": {\n    \"version\": \"1.2\",\n    \"creator\": {\n      \"name\": \"Playwright\",\n      \"version\": \"1.46.0\"\n    },\n    \"br"
  },
  {
    "path": "test-e2e/select-test-suit.ts",
    "chars": 2443,
    "preview": "import { expect, type Locator, type Page } from '@playwright/test';\nimport { TestSuit } from './test-suit';\n\nexport clas"
  },
  {
    "path": "test-e2e/test-suit.ts",
    "chars": 7139,
    "preview": "import { expect, type Locator, type Page } from '@playwright/test';\nimport { lock } from 'cross-process-lock';\nimport { "
  },
  {
    "path": "test-e2e/tests/demo-page.spec.ts",
    "chars": 2359,
    "preview": "import { expect } from '@playwright/test';\nimport { test } from '../bundle-test';\nimport { SelectTestSuit } from '../sel"
  },
  {
    "path": "test-e2e/tests/select-multiple-performance.spec.ts",
    "chars": 8496,
    "preview": "import { expect } from '@playwright/test';\nimport { test } from '../bundle-test';\nimport { SelectTestSuit } from '../sel"
  },
  {
    "path": "test-e2e/tests/select-multiple.spec.ts",
    "chars": 44969,
    "preview": "import { expect } from '@playwright/test';\nimport { test } from '../bundle-test';\nimport { SelectTestSuit } from '../sel"
  },
  {
    "path": "test-e2e/tests/select-one.spec.ts",
    "chars": 39325,
    "preview": "import { expect } from '@playwright/test';\nimport { test } from '../bundle-test';\nimport { SelectTestSuit } from '../sel"
  },
  {
    "path": "test-e2e/tests/text.spec.ts",
    "chars": 13329,
    "preview": "import { expect } from '@playwright/test';\nimport { test } from '../bundle-test';\nimport { TextTestSuit } from '../text-"
  },
  {
    "path": "test-e2e/text-test-suit.ts",
    "chars": 454,
    "preview": "import { type Locator, type Page } from '@playwright/test';\nimport { TestSuit } from './test-suit';\n\nexport class TextTe"
  },
  {
    "path": "test-e2e/tsconfig.json",
    "chars": 586,
    "preview": "{\n  \"compilerOptions\": {\n    \"module\": \"es6\",\n    \"lib\": [\"es2017\", \"dom\"],\n    \"target\": \"ES2020\",\n    \"moduleResolutio"
  },
  {
    "path": "vitest.config.ts",
    "chars": 297,
    "preview": "import { defineConfig } from 'vitest/config';\n\nexport default defineConfig({\n  test: {\n    globals: true,\n    environmen"
  }
]

About this extraction

This page contains the full source code of the Choices-js/Choices GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 199 files (2.2 MB), approximately 580.3k tokens, and a symbol index with 936 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!