diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index a09b998d..37657928 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -29,7 +29,9 @@ "ms-vsliveshare.vsliveshare", "wholroyd.jinja", "dbaeumer.vscode-eslint", - "esbenp.prettier-vscode" + "esbenp.prettier-vscode", + "stylelint.vscode-stylelint", + "pranaygp.vscode-css-peek" ], "settings": { "editor.formatOnPaste": false, diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 92b153a5..18cfec5e 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -7,3 +7,4 @@ pyproject.toml .github/workflows/* .devcontainer/devcontainer.json .pre-commit-config.yaml +package.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5563a6aa..90d6ebec 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,8 +36,15 @@ jobs: python-version: ${{ env.PYTHON_VERSION }} cache: "poetry" + - uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc + cache: "npm" + - name: Install dependencies - run: poetry install + run: | + poetry install + npm install - name: run ruff run: poetry run ruff check --output-format=github @@ -48,6 +55,12 @@ jobs: - name: Run pyright run: poetry run pyright + - name: Run eslint + run: npm run lint + + - name: Run prettier + run: npm run prettier:check + security: runs-on: ubuntu-latest steps: @@ -83,6 +96,8 @@ jobs: - run: docker compose build - run: docker compose down -v --remove-orphans - run: docker compose up -d + - name: test frontend + run: docker compose run amt-test npm run test - name: test app run: docker compose run amt-test poetry run pytest -m 'not slow' --db postgresql - name: db downgrade test @@ -91,7 +106,23 @@ jobs: run: docker compose exec -T amt alembic upgrade head - run: docker compose down -v --remove-orphans - test-local: + test-local-frontend: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc + cache: "npm" + + - name: Install dependencies + run: npm install + + - name: Run tests + run: npm run test + + test-local-backend: runs-on: ubuntu-latest strategy: matrix: @@ -111,8 +142,15 @@ jobs: python-version: ${{ matrix.python-version }} cache: "poetry" + - uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc + cache: "npm" + - name: Install dependencies - run: poetry install + run: | + poetry install + npm install - name: Install Playwright browsers run: poetry run playwright install --with-deps @@ -123,6 +161,10 @@ jobs: poetry run alembic downgrade -1 poetry run alembic upgrade head + - name: Generate required files + run: | + npm run build + - name: Run pytest run: TZ=UTC poetry run coverage run -m pytest @@ -161,7 +203,7 @@ jobs: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} build: - needs: [test-local, test-compose] + needs: [test-local-frontend, test-local-backend, test-compose] if: ${{ !github.event.act }} runs-on: ubuntu-latest permissions: @@ -313,8 +355,16 @@ jobs: notifyMattermost: runs-on: ubuntu-latest - eeds: [lint, security, test-local, test-compose, build] - if: ${{ always() && contains(needs.*.result, 'failure') && !github.event.act}} + needs: + [ + lint, + security, + test-local-backend, + test-local-frontend, + test-compose, + build, + ] + if: ${{ always() && contains(needs.*.result, 'failure') }} steps: - uses: mattermost/action-mattermost-notify@master if: github.event_name != 'pull_request' || github.event.pull_request.draft == false diff --git a/.gitignore b/.gitignore index 0075629b..d6e6b144 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,6 @@ node_modules/ # ignore tsc generated files amt/site/static/js/* + +# ignore webpack build files +amt/site/templates/layouts/base.html.j2 diff --git a/.husky/pre-commit b/.husky/pre-commit index 2312dc58..6e7e7336 100644 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1 +1,3 @@ npx lint-staged +npm run typecheck +npm run stylecheck diff --git a/.nvmrc b/.nvmrc index 120d3f5e..80a9956e 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -()v22.6.0 +v20.16.0 diff --git a/.stylelintrc.json b/.stylelintrc.json new file mode 100644 index 00000000..6c971990 --- /dev/null +++ b/.stylelintrc.json @@ -0,0 +1,12 @@ +{ + "extends": "stylelint-config-standard", + "rules": { + "declaration-block-no-redundant-longhand-properties": null + }, + "ignoreFiles": [ + "amt/site/static/css/*cols.css", + "amt/site/static/css/col.css", + "amt/site/static/css/html5reset.css", + "htmlcov/*.css" + ] +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 3e709067..32a5bbfe 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -13,6 +13,8 @@ "ms-vsliveshare.vsliveshare", "wholroyd.jinja", "dbaeumer.vscode-eslint", - "esbenp.prettier-vscode" + "esbenp.prettier-vscode", + "stylelint.vscode-stylelint", + "pranaygp.vscode-css-peek" ] } diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 9a87be23..90145a46 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -27,7 +27,7 @@ }, { "label": "Ruff format", - "detail": "format code.", + "detail": "format code ruff.", "type": "shell", "command": "poetry run ruff format", "group": "test", @@ -37,6 +37,18 @@ }, "problemMatcher": [] }, + { + "label": "prettier", + "detail": "format code prettier.", + "type": "shell", + "command": "npm run prettier", + "group": "test", + "presentation": { + "reveal": "always", + "panel": "new" + }, + "problemMatcher": [] + }, { "label": "Code Coverage", "detail": "Generate code coverage report.", @@ -51,7 +63,7 @@ }, { "label": "PyTest", - "detail": "test all code", + "detail": "test all backend code", "type": "shell", "command": "poetry run coverage run -m pytest", "group": { @@ -63,6 +75,20 @@ "panel": "new" }, "problemMatcher": [] + }, + { + "label": "npm test", + "detail": "test all frontend code", + "type": "shell", + "command": "npm run test", + "group": { + "kind": "test" + }, + "presentation": { + "reveal": "always", + "panel": "new" + }, + "problemMatcher": [] } ] } diff --git a/BUILD.md b/BUILD.md index 33f22ac8..5656e2c1 100644 --- a/BUILD.md +++ b/BUILD.md @@ -1,28 +1,69 @@ # Buiding AMT +Before you can build AMT you first need to clone the git repository: + +``` +git clone https://github.com/MinBZK/amt.git +cd amt/ +``` + There are several ways to build and run AMT. -1. Poetry +1. Poetry & NPM 2. Container -## Building AMT with Poetry +## Building with Poetry & NPM + +AMT uses 2 build systems within its project. One for the frontend (NPM) and one for the backend (Poetry). Poetry is a Python package and dependency manager. Before you can install Poetry you first need to install Python. Please follow [these](https://github.com/pyenv/pyenv?amt=readme-ov-file#installation) instructions. Once you have Python available you can install Poetry. See [here](https://python-poetry.org/docs/#installation). -Once you have Poetry and Python installed you can start installing the dependencies with the following shell command. +NPM (Node package manager) is a node package and dependency manager. Before you can use NPM we recommend you install NVM (node version manager). Please follow[these](https://github.com/nvm-sh/nvm?tab=readme-ov-file#installing-and-updating) instructions. + +once NVM is install you can execute the following commands to install node and NPM + +```bash +nvm install +nvm use +``` + +Note that the .nvmrc is used to determine the version that is being installed for this project. + +Once you have Poetry and NPM installed you can start installing the dependencies with the following shell commands. ```shell +npm install poetry install ``` -When poetry is done installing all dependencies you can start using the tool. +When poetry and npm are done installing all dependencies you can start using the tool. you need to start 2 processes + +```shell +npm start +``` ```shell poetry run python -m uvicorn amt.server:app --log-level warning ``` +## Building AMT with Containers + +Containers allows to package software, make it portable, and isolated. Before you can run a container you first need a container runtime. There are several available, but al lot of users use [docker desktop](https://www.docker.com/products/docker-desktop/). + +After installing a Docker runtime like Docker Desktop you can start building the applications with this command: + +```shell +docker compose build +``` + +To run the application you use this command: + +```shell +docker compose up +``` + ### Suggested development ENVIRONMENT settings To use a development environment during local development, you can use the following environment options. @@ -49,22 +90,6 @@ to upgrade to the latest version of the database schema use alembic upgrade head ``` -## Building AMT with Containers - -Containers allows to package software, make it portable, and isolated. Before you can run a container you first need a container runtime. There are several available, but al lot of users use [docker desktop](https://www.docker.com/products/docker-desktop/). - -After installing a Docker runtime like Docker Desktop you can start building the applications with this command: - -```shell -docker compose build -``` - -To run the application you use this command: - -```shell -docker compose up -``` - ## Language support We use babel for translations and a custom yaml for dynamic translations. Babel does not support Frysian, so we added a custom piece of code to support this. To generate, update or compile the language files, use the script in ./script/translate. diff --git a/Dockerfile b/Dockerfile index 360ea6d0..d15406de 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,8 @@ ARG PYTHON_VERSION=3.11.7-slim +ARG NVM_VERSION=0.40.0 FROM --platform=$BUILDPLATFORM python:${PYTHON_VERSION} AS project-base +ARG NVM_VERSION LABEL maintainer=ai-validatie@minbzk.nl \ organization=MinBZK \ @@ -16,7 +18,8 @@ ENV PYTHONUNBUFFERED=1 \ PIP_DEFAULT_TIMEOUT=100 \ POETRY_VIRTUALENVS_IN_PROJECT=true \ POETRY_NO_INTERACTION=1 \ - POETRY_HOME='/usr/local' + POETRY_HOME='/usr/local' \ + NVM_DIR=/usr/local/nvm RUN apt-get update && apt-get install -y --no-install-recommends \ curl libpq-dev \ @@ -26,8 +29,18 @@ RUN curl -sSL https://install.python-poetry.org | python3 - WORKDIR /app/ COPY ./poetry.lock ./pyproject.toml ./ +COPY ./package-lock.json ./package.json .nvmrc ./ +COPY ./webpack.config.js ./webpack.config.prod.js ./ +COPY ./tsconfig.json ./eslint.config.mjs ./ +COPY ./jest.config.ts ./ + +RUN mkdir -p $NVM_DIR && curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v${NVM_VERSION}/install.sh | bash + +RUN . ~/.bashrc && nvm install && nvm use RUN poetry install --without dev,test +RUN . "$NVM_DIR/nvm.sh" && npm install +ENV PATH="$NVM_DIR/versions/node/v20.16.0/bin:$PATH" ENV PATH="/app/.venv/bin:$PATH" FROM project-base AS development @@ -39,18 +52,21 @@ COPY ./README.md ./README.md RUN poetry install FROM development AS lint - -RUN ruff check +COPY ./.prettierrc ./.prettierignore ./ RUN ruff format --check +RUN npm run prettier:check +RUN ruff check +RUN npm run lint RUN pyright FROM development AS test COPY ./example/ ./example/ -# RUN poetry run playwright install --with-deps +RUN npm run build FROM project-base AS production + RUN groupadd amt && \ adduser --uid 100 --system --ingroup amt amt @@ -65,6 +81,12 @@ COPY --chown=root:root --chmod=755 alembic.ini /app/alembic.ini COPY --chown=root:root --chmod=755 prod.env /app/.env COPY --chown=root:root --chmod=755 LICENSE /app/LICENSE COPY --chown=amt:amt --chmod=755 docker-entrypoint.sh /app/docker-entrypoint.sh +USER root +RUN mkdir -p ./amt/site/static/dist/ +RUN chown amt:amt -R ./amt/site/static/dist/ +RUN chown amt:amt -R ./amt/site/templates/layouts/ +USER amt +RUN npm run build ENV PYTHONPATH=/app/ WORKDIR /app/ diff --git a/README.md b/README.md index 769bc718..7cba30bf 100644 --- a/README.md +++ b/README.md @@ -15,10 +15,14 @@ Note: The main branch may be in an unstable or even broken state during developm See [contributing docs](CONTRIBUTING.md) -## How to build and run AMT +## How to build and develop AMT See [build docs](BUILD.md) +## How to run AMT + +See [usage docs](USAGE.md) + ## How to run the CLI The check-state can be executed to see what tasks are waiting to be done. @@ -36,6 +40,7 @@ An example command: When running the GitHub actions locally you can use [act](https://github.com/nektos/act), to do this run change the matrix in the `ci.yml` of the `test-local` job to have only python version 3.11. Then run the following command: + ```shell act -W '.github/workflows/ci.yml' -s GITHUB_TOKEN="$(gh auth token)" --artifact-server-path tmp/artifacts -e act_event.json ``` diff --git a/USAGE.md b/USAGE.md new file mode 100644 index 00000000..c6a1cc4c --- /dev/null +++ b/USAGE.md @@ -0,0 +1,114 @@ +# USAGE + +This document describes how you can use AMT without building it. + +## Using AMT + +To use AMT without building we recommend the pre-build docker images on [github](https://github.com/MinBZK/amt/pkgs/container/amt). + +You can deploy AMT to kubernetes or run the container locally using docker compose. + +- Example [kubernetes](https://github.com/MinBZK/ai-validation-infra/tree/main/apps/amt) +- Example [docker compose](./compose.yml) + +To run amt locally create a compose.yml file and install [docker desktop](https://www.docker.com/products/docker-desktop/). Once you have install docker you can run the following command in the directory where you created the compose.yml + +```bash +docker compose up +``` + +Once all services started (can take 1 minute) you can reach the site at localhost:8000 + +Example of a compose.yml file (this is not a secure example) + +```yml +services: + amt: + image: ghcr.io/minbzk/amt:main + restart: unless-stopped + depends_on: + db: + condition: service_healthy + environment: + - ENVIRONMENT=local + - APP_DATABASE_SCHEME=postgresql + - APP_DATABASE_USER=postgres + - APP_DATABASE_PASSWORD=changethis + - APP_DATABASE_DB=postgres + ports: + - 8000:8000 + healthcheck: + test: + [ + "CMD-SHELL", + "curl -f http://localhost:8000/health/live || exit 1", + ] + db: + image: postgres:16 + restart: unless-stopped + volumes: + - app-db-data:/var/lib/postgresql/data/pgdata + environment: + - PGDATA=/var/lib/postgresql/data/pgdata + - POSTGRES_USER=postgres + - POSTGRES_PASSWORD=changethis + healthcheck: + test: ["CMD", "pg_isready", "-q", "-d", "amt", "-U", "amt"] + +volumes: + app-db-data: +``` + +## Database for AMT + +it is possible to run AMT with the following databases: + +- SQLite (tested) +- Postgresql (tested) +- MySQL +- MariaDB +- Oracle + +We recommend using postgresql for production grade deployments because that one is tested in our CI/CD. By default AMT will use SQLite which will create a local database within the AMT container. + +See [Options](#Option) on how to configure a database + +## Logging for AMT + +AMT supports detailed logging that gives you control on what to log. + +See [Options](#Option) for the logging options. + +Currently AMT uses the logging config as defined [here](https://github.com/MinBZK/amt/blob/main/amt/core/log.py). youi can append or change the config byu setting the LOGGING_CONFIG environmental variable. + +```shell +export LOGGING_CONFIG='{"loggers": { "amt": { "propagate": "True" }},"formatters": { "generic": { "fmt": "{name}: {message}"}}}' +``` + +For more info on how to set logging see the python [logging.config](https://docs.python.org/3/library/logging.config.html) library + +## Options + +AMT uses environmental options that you can set when running the application. + +| Variable | Description | Default | +| ----------------------- | --------------------------------------------------------------------- | --------------------------- | +| SECRET_KEY | secret to use | random | +| ENVIRONMENT | local or production | local | +| LOGGING_LEVEL | default Logging level "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL" | INFO | +| LOGGING_CONFIG | json dict of extra logging config | | +| DEBUG | enable debugging with trace dumps | False | +| AUTO_CREATE_SCHEMA | Auto create schema, not recommended for production | False | +| CARD_DIR | Directory to Card storage | /tmp/ | +| APP_DATABASE_SCHEME | one of "sqlite", "postgresql", "mysql", "oracle" | sqlite | +| APP_DATABASE_DRIVER | database driver to use | use default based on schema | +| APP_DATABASE_SERVER | location of the database | db | +| APP_DATABASE_PORT | port of the database | 5432 | +| APP_DATABASE_USER | user of the database | amt | +| APP_DATABASE_PASSWORD | set a password for the database user | +| APP_DATABASE_DB | database to connect to on the database server | amt | +| APP_DATABASE_FILE | file to use when selecting schema as sqlite | /database.sqlite3 | +| CSRF_PROTECT_SECRET_KEY | secret to use | random | +| CSRF_TOKEN_LOCATION | location of the token | header | +| CSRF_TOKEN_KEY | | csrf-token | +| CSRF_COOKIE_SAMESITE | | strict | diff --git a/act_event.json b/act_event.json index 43c2f0eb..176cfa80 100644 --- a/act_event.json +++ b/act_event.json @@ -1,3 +1,3 @@ { - "act": true + "act": true } diff --git a/amt/api/deps.py b/amt/api/deps.py index 490c04da..c1a31f83 100644 --- a/amt/api/deps.py +++ b/amt/api/deps.py @@ -69,7 +69,12 @@ def TemplateResponse( # pyright: ignore [reportIncompatibleMethodOverride] if context is None: context = {} - context["csrftoken"] = request.state.csrftoken + + if hasattr(request.state, "csrftoken"): + context["csrftoken"] = request.state.csrftoken + else: + context["csrftoken"] = "" + return super().TemplateResponse(request, name, context, status_code, headers, media_type, background) def Redirect(self, request: Request, url: str) -> HTMLResponse: diff --git a/amt/middleware/csrf.py b/amt/middleware/csrf.py index ff4290cd..126eb863 100644 --- a/amt/middleware/csrf.py +++ b/amt/middleware/csrf.py @@ -40,8 +40,10 @@ def _include_request(self, request: Request) -> bool: async def dispatch(self, request: Request, call_next: RequestResponseEndpoint) -> Response: signed_token = "" + if self._include_request(request): request.state.csrftoken = "" + if request.method in self.safe_methods: csrf_token, signed_token = self.csrf_protect.generate_csrf_tokens() logger.debug(f"generating tokens: csrf_token={csrf_token}, signed_token={signed_token}") diff --git a/amt/site/static/css/layout.css b/amt/site/static/scss/layout.scss similarity index 72% rename from amt/site/static/css/layout.css rename to amt/site/static/scss/layout.scss index b5291447..d599ab17 100644 --- a/amt/site/static/css/layout.css +++ b/amt/site/static/scss/layout.scss @@ -1,38 +1,35 @@ @font-face { font-family: "Rijksoverheid Sans"; - src: url(../fonts/ROsanswebtextregular.woff) format("opentype"); + src: url("../fonts/ROsanswebtextregular.woff") format("opentype"); font-style: normal; font-weight: 400; } @font-face { font-family: "Rijksoverheid Sans"; - src: url(../fonts/ROsanswebtextitalic.woff) format("opentype"); + src: url("../fonts/ROsanswebtextitalic.woff") format("opentype"); font-style: italic; font-weight: 400; } @font-face { font-family: "Rijksoverheid Sans"; - src: url(../fonts/ROsanswebtextbold.woff) format("opentype"); + src: url("../fonts/ROsanswebtextbold.woff") format("opentype"); font-weight: 700; font-style: normal; } :root { - --clr-neutral-800: hsl(234, 29%, 20%); - --clr-neutral-700: hsl(235, 18%, 26%); - --clr-neutral-200: hsl(231, 7%, 60%); - --clr-neutral-100: hsl(0, 0%, 100%); - - --clr-accent-600: hsl(211, 69%, 27%); - --clr-accent-400: hsl(203, 100%, 39%); - --clr-accent-200: hsl(203, 63.8%, 81.6%); - + --clr-neutral-800: hsl(234deg 29% 20%); + --clr-neutral-700: hsl(235deg 18% 26%); + --clr-neutral-200: hsl(231deg 7% 60%); + --clr-neutral-100: hsl(0deg 0% 100%); + --clr-accent-600: hsl(211deg 69% 27%); + --clr-accent-400: hsl(203deg 100% 39%); + --clr-accent-200: hsl(203deg 63.8% 81.6%); --ff-base: "Rijksoverheid Sans", sans-serif; --fw-regular: 400; --fw-bold: 700; - --fs-300: 0.825rem; --fs-400: 1rem; --fs-900: 2.5rem; @@ -49,12 +46,10 @@ body { font-family: var(--ff-base); font-size: var(--fs-400); font-weight: var(--fw-regular); - color: var(--clr-neutral-800); line-height: 1.5; min-height: 100vh; min-height: 100svh; - background-color: var(--clr-neutral-100); display: flex; flex-direction: column; @@ -72,7 +67,7 @@ footer { border-block-start-color: var(--clr-accent-200); border-block-start-style: solid; border-block-start-width: 0.5rem; - background-color: rgb(0, 123, 199); + background-color: hsl(203deg 100% 39%); height: 2rem; } @@ -88,7 +83,7 @@ footer { text-decoration: none; } -.header_top { +.header-top { padding-inline: 0.75em; padding-block: 0.5em; color: var(--clr-accent-600); @@ -97,17 +92,23 @@ footer { white-space: nowrap; } -.header_logo_image { +.header-logo-image { aspect-ratio: 1 / 1; max-width: 180px; display: block; } -.language_selection { +.language-selection { margin-inline-end: clamp(1rem, 2vw, 4rem); } -.header_nav { +/* Add an empty line before the rule */ +.project-list a { + text-decoration: none; + color: inherit; +} + +.header-nav { background-color: var(--clr-accent-400); height: 50px; color: var(--clr-neutral-100); @@ -117,18 +118,18 @@ footer { justify-content: flex-end; } -.header_nav > div { +.header-nav > div { align-self: center; } -.header_nav a { +.header-nav a { border-block-end: 0.1em solid; border-block-end-color: var(--clr-accent-200); border-block-end-style: dashed; padding-block: 0.2em; } -.header_nav a:hover { +.header-nav a:hover { color: var(--clr-accent-600); background-color: var(--clr-accent-200); flex-grow: 1; @@ -136,50 +137,50 @@ footer { border-radius: 0.5em; } -.header_nav_container ul { +.header-nav-container ul { display: flex; justify-content: space-between; align-items: center; gap: clamp(1rem, 2vw, 4rem); } -.margin-bottom--large { +.margin-bottom-large { margin-bottom: 1em; } -.margin-bottom--small { +.margin-bottom-small { margin-bottom: 0.5em; } -.margin-bottom--extra-small { +.margin-bottom-extra-small { margin-bottom: 0.25em; } -.progress_cards_container { +.progress-cards-container { min-height: 30em; - background-color: rgb(229, 241, 249); + background-color: rgb(229 241 249); border-radius: 10px; margin: 0 0.5em; overflow: hidden; } -.progress_card_container { +.progress-card-container { margin: 0.5em; - border: 1px solid rgb(21, 66, 115); + border: 1px solid rgb(21 66 115); padding: 0.5em; border-radius: 10px; - background-color: #ffffff; - box-shadow: rgba(00, 00, 00, 0.12) 0 3px 6px 0; + background-color: #fff; + box-shadow: rgba(0 0 0 / 12%) 0 3px 6px 0; cursor: move; user-select: none; } -.progress_card_assignees_container { +.progress-card-assignees-container { display: flex; justify-content: flex-end; } -.progress_card_assignees_image { +.progress-card-assignees-image { border-radius: 50%; height: 35px; } @@ -196,7 +197,3 @@ footer { list-style-type: none; white-space: nowrap; } -.project-list a { - text-decoration: none; - color: inherit; -} diff --git a/amt/site/static/ts/amt.ts b/amt/site/static/ts/amt.ts index 5fe3df51..6f83a5cf 100644 --- a/amt/site/static/ts/amt.ts +++ b/amt/site/static/ts/amt.ts @@ -1,32 +1,39 @@ import Sortable from "sortablejs"; -import "htmx.org"; +import htmx from "htmx.org"; +import _hyperscript from "hyperscript.org"; + +import "../scss/layout.scss"; + +_hyperscript.browserInit(); window.onload = function () { // TODO (robbert): we need (better) event handling and displaying of server errors document.body.addEventListener("htmx:sendError", function () { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion document.getElementById("errorContainer")!.innerHTML = "

Placeholder: Error while connecting to server; - for (let i = 0; i < columns.length; i++) { - new Sortable(columns[i], { + for (const column of columns) { + new Sortable(column, { //NOSONAR group: "shared", // set both lists to same group animation: 150, onEnd: function (evt) { if (evt.oldIndex !== evt.newIndex || evt.from !== evt.to) { - let previousSiblingId = evt.item.previousElementSibling + const previousSiblingId = evt.item.previousElementSibling ? evt.item.previousElementSibling.getAttribute("data-id") : "-1"; - let nextSiblingId = evt.item.nextElementSibling + const nextSiblingId = evt.item.nextElementSibling ? evt.item.nextElementSibling.getAttribute("data-id") : "-1"; - let targetId = "#" + evt.item.getAttribute("data-target-id"); - let toStatusId = evt.to.getAttribute("data-id"); - let form = document.getElementById("cardMovedForm"); + const targetId = "#" + evt.item.getAttribute("data-target-id"); + const toStatusId = evt.to.getAttribute("data-id"); + const form = (document.getElementById("cardMovedForm") ?? + "") as HTMLFormElement; (document.getElementsByName("taskId")[0] as HTMLInputElement).value = evt.item.getAttribute("data-id") ?? ""; @@ -41,9 +48,9 @@ window.onload = function () { ( document.getElementsByName("nextSiblingId")[0] as HTMLInputElement ).value = nextSiblingId ?? ""; - form!.setAttribute("hx-target", targetId); + form.setAttribute("hx-target", targetId); - // @ts-expect-error" + // @ts-expect-error Description: Ignoring type error because the htmx.trigger function is not recognized by TypeScript. htmx.trigger("#cardMovedForm", "cardmoved"); } }, @@ -51,8 +58,7 @@ window.onload = function () { } }; -// @ts-expect-error" -function setCookie( +export function setCookie( cookieName: string, cookieValue: string, expirationDays: number, @@ -63,3 +69,18 @@ function setCookie( document.cookie = cookieName + "=" + cookieValue + ";" + expires + ";path=/;SameSite=Strict"; } + +declare global { + interface Window { + setCookie: ( + cookieName: string, + cookieValue: string, + expirationDays: number, + ) => void; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + htmx: any; + } +} + +window.setCookie = setCookie; +window.htmx = htmx; diff --git a/amt/site/static/vendor/htmx/js/1.9.12.min.js b/amt/site/static/vendor/htmx/js/1.9.12.min.js deleted file mode 100644 index 52866033..00000000 --- a/amt/site/static/vendor/htmx/js/1.9.12.min.js +++ /dev/null @@ -1 +0,0 @@ -(function (e, t) { if (typeof define === "function" && define.amd) { define([], t) } else if (typeof module === "object" && module.exports) { module.exports = t() } else { e.htmx = e.htmx || t() } })(typeof self !== "undefined" ? self : this, function () { return function () { "use strict"; var Q = { onLoad: F, process: zt, on: de, off: ge, trigger: ce, ajax: Nr, find: C, findAll: f, closest: v, values: function (e, t) { var r = dr(e, t || "post"); return r.values }, remove: _, addClass: z, removeClass: n, toggleClass: $, takeClass: W, defineExtension: Ur, removeExtension: Br, logAll: V, logNone: j, logger: null, config: { historyEnabled: true, historyCacheSize: 10, refreshOnHistoryMiss: false, defaultSwapStyle: "innerHTML", defaultSwapDelay: 0, defaultSettleDelay: 20, includeIndicatorStyles: true, indicatorClass: "htmx-indicator", requestClass: "htmx-request", addedClass: "htmx-added", settlingClass: "htmx-settling", swappingClass: "htmx-swapping", allowEval: true, allowScriptTags: true, inlineScriptNonce: "", attributesToSettle: ["class", "style", "width", "height"], withCredentials: false, timeout: 0, wsReconnectDelay: "full-jitter", wsBinaryType: "blob", disableSelector: "[hx-disable], [data-hx-disable]", useTemplateFragments: false, scrollBehavior: "smooth", defaultFocusScroll: false, getCacheBusterParam: false, globalViewTransitions: false, methodsThatUseUrlParams: ["get"], selfRequestsOnly: false, ignoreTitle: false, scrollIntoViewOnBoost: true, triggerSpecsCache: null }, parseInterval: d, _: t, createEventSource: function (e) { return new EventSource(e, { withCredentials: true }) }, createWebSocket: function (e) { var t = new WebSocket(e, []); t.binaryType = Q.config.wsBinaryType; return t }, version: "1.9.12" }; var r = { addTriggerHandler: Lt, bodyContains: se, canAccessLocalStorage: U, findThisElement: xe, filterValues: yr, hasAttribute: o, getAttributeValue: te, getClosestAttributeValue: ne, getClosestMatch: c, getExpressionVars: Hr, getHeaders: xr, getInputValues: dr, getInternalData: ae, getSwapSpecification: wr, getTriggerSpecs: it, getTarget: ye, makeFragment: l, mergeObjects: le, makeSettleInfo: T, oobSwap: Ee, querySelectorExt: ue, selectAndSwap: je, settleImmediately: nr, shouldCancel: ut, triggerEvent: ce, triggerErrorEvent: fe, withExtensions: R }; var w = ["get", "post", "put", "delete", "patch"]; var i = w.map(function (e) { return "[hx-" + e + "], [data-hx-" + e + "]" }).join(", "); var S = e("head"), q = e("title"), H = e("svg", true); function e(e, t) { return new RegExp("<" + e + "(\\s[^>]*>|>)([\\s\\S]*?)<\\/" + e + ">", !!t ? "gim" : "im") } function d(e) { if (e == undefined) { return undefined } let t = NaN; if (e.slice(-2) == "ms") { t = parseFloat(e.slice(0, -2)) } else if (e.slice(-1) == "s") { t = parseFloat(e.slice(0, -1)) * 1e3 } else if (e.slice(-1) == "m") { t = parseFloat(e.slice(0, -1)) * 1e3 * 60 } else { t = parseFloat(e) } return isNaN(t) ? undefined : t } function ee(e, t) { return e.getAttribute && e.getAttribute(t) } function o(e, t) { return e.hasAttribute && (e.hasAttribute(t) || e.hasAttribute("data-" + t)) } function te(e, t) { return ee(e, t) || ee(e, "data-" + t) } function u(e) { return e.parentElement } function re() { return document } function c(e, t) { while (e && !t(e)) { e = u(e) } return e ? e : null } function L(e, t, r) { var n = te(t, r); var i = te(t, "hx-disinherit"); if (e !== t && i && (i === "*" || i.split(" ").indexOf(r) >= 0)) { return "unset" } else { return n } } function ne(t, r) { var n = null; c(t, function (e) { return n = L(t, e, r) }); if (n !== "unset") { return n } } function h(e, t) { var r = e.matches || e.matchesSelector || e.msMatchesSelector || e.mozMatchesSelector || e.webkitMatchesSelector || e.oMatchesSelector; return r && r.call(e, t) } function A(e) { var t = /<([a-z][^\/\0>\x20\t\r\n\f]*)/i; var r = t.exec(e); if (r) { return r[1].toLowerCase() } else { return "" } } function s(e, t) { var r = new DOMParser; var n = r.parseFromString(e, "text/html"); var i = n.body; while (t > 0) { t--; i = i.firstChild } if (i == null) { i = re().createDocumentFragment() } return i } function N(e) { return /", 0); var a = i.querySelector("template").content; if (Q.config.allowScriptTags) { oe(a.querySelectorAll("script"), function (e) { if (Q.config.inlineScriptNonce) { e.nonce = Q.config.inlineScriptNonce } e.htmxExecuted = navigator.userAgent.indexOf("Firefox") === -1 }) } else { oe(a.querySelectorAll("script"), function (e) { _(e) }) } return a } switch (r) { case "thead": case "tbody": case "tfoot": case "colgroup": case "caption": return s("" + n + "
", 1); case "col": return s("" + n + "
", 2); case "tr": return s("" + n + "
", 2); case "td": case "th": return s("" + n + "
", 3); case "script": case "style": return s("
" + n + "
", 1); default: return s(n, 0) } } function ie(e) { if (e) { e() } } function I(e, t) { return Object.prototype.toString.call(e) === "[object " + t + "]" } function k(e) { return I(e, "Function") } function P(e) { return I(e, "Object") } function ae(e) { var t = "htmx-internal-data"; var r = e[t]; if (!r) { r = e[t] = {} } return r } function M(e) { var t = []; if (e) { for (var r = 0; r < e.length; r++) { t.push(e[r]) } } return t } function oe(e, t) { if (e) { for (var r = 0; r < e.length; r++) { t(e[r]) } } } function X(e) { var t = e.getBoundingClientRect(); var r = t.top; var n = t.bottom; return r < window.innerHeight && n >= 0 } function se(e) { if (e.getRootNode && e.getRootNode() instanceof window.ShadowRoot) { return re().body.contains(e.getRootNode().host) } else { return re().body.contains(e) } } function D(e) { return e.trim().split(/\s+/) } function le(e, t) { for (var r in t) { if (t.hasOwnProperty(r)) { e[r] = t[r] } } return e } function E(e) { try { return JSON.parse(e) } catch (e) { b(e); return null } } function U() { var e = "htmx:localStorageTest"; try { localStorage.setItem(e, e); localStorage.removeItem(e); return true } catch (e) { return false } } function B(t) { try { var e = new URL(t); if (e) { t = e.pathname + e.search } if (!/^\/$/.test(t)) { t = t.replace(/\/+$/, "") } return t } catch (e) { return t } } function t(e) { return Tr(re().body, function () { return eval(e) }) } function F(t) { var e = Q.on("htmx:load", function (e) { t(e.detail.elt) }); return e } function V() { Q.logger = function (e, t, r) { if (console) { console.log(t, e, r) } } } function j() { Q.logger = null } function C(e, t) { if (t) { return e.querySelector(t) } else { return C(re(), e) } } function f(e, t) { if (t) { return e.querySelectorAll(t) } else { return f(re(), e) } } function _(e, t) { e = p(e); if (t) { setTimeout(function () { _(e); e = null }, t) } else { e.parentElement.removeChild(e) } } function z(e, t, r) { e = p(e); if (r) { setTimeout(function () { z(e, t); e = null }, r) } else { e.classList && e.classList.add(t) } } function n(e, t, r) { e = p(e); if (r) { setTimeout(function () { n(e, t); e = null }, r) } else { if (e.classList) { e.classList.remove(t); if (e.classList.length === 0) { e.removeAttribute("class") } } } } function $(e, t) { e = p(e); e.classList.toggle(t) } function W(e, t) { e = p(e); oe(e.parentElement.children, function (e) { n(e, t) }); z(e, t) } function v(e, t) { e = p(e); if (e.closest) { return e.closest(t) } else { do { if (e == null || h(e, t)) { return e } } while (e = e && u(e)); return null } } function g(e, t) { return e.substring(0, t.length) === t } function G(e, t) { return e.substring(e.length - t.length) === t } function J(e) { var t = e.trim(); if (g(t, "<") && G(t, "/>")) { return t.substring(1, t.length - 2) } else { return t } } function Z(e, t) { if (t.indexOf("closest ") === 0) { return [v(e, J(t.substr(8)))] } else if (t.indexOf("find ") === 0) { return [C(e, J(t.substr(5)))] } else if (t === "next") { return [e.nextElementSibling] } else if (t.indexOf("next ") === 0) { return [K(e, J(t.substr(5)))] } else if (t === "previous") { return [e.previousElementSibling] } else if (t.indexOf("previous ") === 0) { return [Y(e, J(t.substr(9)))] } else if (t === "document") { return [document] } else if (t === "window") { return [window] } else if (t === "body") { return [document.body] } else { return re().querySelectorAll(J(t)) } } var K = function (e, t) { var r = re().querySelectorAll(t); for (var n = 0; n < r.length; n++) { var i = r[n]; if (i.compareDocumentPosition(e) === Node.DOCUMENT_POSITION_PRECEDING) { return i } } }; var Y = function (e, t) { var r = re().querySelectorAll(t); for (var n = r.length - 1; n >= 0; n--) { var i = r[n]; if (i.compareDocumentPosition(e) === Node.DOCUMENT_POSITION_FOLLOWING) { return i } } }; function ue(e, t) { if (t) { return Z(e, t)[0] } else { return Z(re().body, e)[0] } } function p(e) { if (I(e, "String")) { return C(e) } else { return e } } function ve(e, t, r) { if (k(t)) { return { target: re().body, event: e, listener: t } } else { return { target: p(e), event: t, listener: r } } } function de(t, r, n) { jr(function () { var e = ve(t, r, n); e.target.addEventListener(e.event, e.listener) }); var e = k(r); return e ? r : n } function ge(t, r, n) { jr(function () { var e = ve(t, r, n); e.target.removeEventListener(e.event, e.listener) }); return k(r) ? r : n } var pe = re().createElement("output"); function me(e, t) { var r = ne(e, t); if (r) { if (r === "this") { return [xe(e, t)] } else { var n = Z(e, r); if (n.length === 0) { b('The selector "' + r + '" on ' + t + " returned no matches!"); return [pe] } else { return n } } } } function xe(e, t) { return c(e, function (e) { return te(e, t) != null }) } function ye(e) { var t = ne(e, "hx-target"); if (t) { if (t === "this") { return xe(e, "hx-target") } else { return ue(e, t) } } else { var r = ae(e); if (r.boosted) { return re().body } else { return e } } } function be(e) { var t = Q.config.attributesToSettle; for (var r = 0; r < t.length; r++) { if (e === t[r]) { return true } } return false } function we(t, r) { oe(t.attributes, function (e) { if (!r.hasAttribute(e.name) && be(e.name)) { t.removeAttribute(e.name) } }); oe(r.attributes, function (e) { if (be(e.name)) { t.setAttribute(e.name, e.value) } }) } function Se(e, t) { var r = Fr(t); for (var n = 0; n < r.length; n++) { var i = r[n]; try { if (i.isInlineSwap(e)) { return true } } catch (e) { b(e) } } return e === "outerHTML" } function Ee(e, i, a) { var t = "#" + ee(i, "id"); var o = "outerHTML"; if (e === "true") { } else if (e.indexOf(":") > 0) { o = e.substr(0, e.indexOf(":")); t = e.substr(e.indexOf(":") + 1, e.length) } else { o = e } var r = re().querySelectorAll(t); if (r) { oe(r, function (e) { var t; var r = i.cloneNode(true); t = re().createDocumentFragment(); t.appendChild(r); if (!Se(o, e)) { t = r } var n = { shouldSwap: true, target: e, fragment: t }; if (!ce(e, "htmx:oobBeforeSwap", n)) return; e = n.target; if (n["shouldSwap"]) { Fe(o, e, e, t, a) } oe(a.elts, function (e) { ce(e, "htmx:oobAfterSwap", n) }) }); i.parentNode.removeChild(i) } else { i.parentNode.removeChild(i); fe(re().body, "htmx:oobErrorNoTarget", { content: i }) } return e } function Ce(e, t, r) { var n = ne(e, "hx-select-oob"); if (n) { var i = n.split(","); for (var a = 0; a < i.length; a++) { var o = i[a].split(":", 2); var s = o[0].trim(); if (s.indexOf("#") === 0) { s = s.substring(1) } var l = o[1] || "true"; var u = t.querySelector("#" + s); if (u) { Ee(l, u, r) } } } oe(f(t, "[hx-swap-oob], [data-hx-swap-oob]"), function (e) { var t = te(e, "hx-swap-oob"); if (t != null) { Ee(t, e, r) } }) } function Re(e) { oe(f(e, "[hx-preserve], [data-hx-preserve]"), function (e) { var t = te(e, "id"); var r = re().getElementById(t); if (r != null) { e.parentNode.replaceChild(r, e) } }) } function Te(o, e, s) { oe(e.querySelectorAll("[id]"), function (e) { var t = ee(e, "id"); if (t && t.length > 0) { var r = t.replace("'", "\\'"); var n = e.tagName.replace(":", "\\:"); var i = o.querySelector(n + "[id='" + r + "']"); if (i && i !== o) { var a = e.cloneNode(); we(e, i); s.tasks.push(function () { we(e, a) }) } } }) } function Oe(e) { return function () { n(e, Q.config.addedClass); zt(e); Nt(e); qe(e); ce(e, "htmx:load") } } function qe(e) { var t = "[autofocus]"; var r = h(e, t) ? e : e.querySelector(t); if (r != null) { r.focus() } } function a(e, t, r, n) { Te(e, r, n); while (r.childNodes.length > 0) { var i = r.firstChild; z(i, Q.config.addedClass); e.insertBefore(i, t); if (i.nodeType !== Node.TEXT_NODE && i.nodeType !== Node.COMMENT_NODE) { n.tasks.push(Oe(i)) } } } function He(e, t) { var r = 0; while (r < e.length) { t = (t << 5) - t + e.charCodeAt(r++) | 0 } return t } function Le(e) { var t = 0; if (e.attributes) { for (var r = 0; r < e.attributes.length; r++) { var n = e.attributes[r]; if (n.value) { t = He(n.name, t); t = He(n.value, t) } } } return t } function Ae(e) { var t = ae(e); if (t.onHandlers) { for (var r = 0; r < t.onHandlers.length; r++) { const n = t.onHandlers[r]; e.removeEventListener(n.event, n.listener) } delete t.onHandlers } } function Ne(e) { var t = ae(e); if (t.timeout) { clearTimeout(t.timeout) } if (t.webSocket) { t.webSocket.close() } if (t.sseEventSource) { t.sseEventSource.close() } if (t.listenerInfos) { oe(t.listenerInfos, function (e) { if (e.on) { e.on.removeEventListener(e.trigger, e.listener) } }) } Ae(e); oe(Object.keys(t), function (e) { delete t[e] }) } function m(e) { ce(e, "htmx:beforeCleanupElement"); Ne(e); if (e.children) { oe(e.children, function (e) { m(e) }) } } function Ie(t, e, r) { if (t.tagName === "BODY") { return Ue(t, e, r) } else { var n; var i = t.previousSibling; a(u(t), t, e, r); if (i == null) { n = u(t).firstChild } else { n = i.nextSibling } r.elts = r.elts.filter(function (e) { return e != t }); while (n && n !== t) { if (n.nodeType === Node.ELEMENT_NODE) { r.elts.push(n) } n = n.nextElementSibling } m(t); u(t).removeChild(t) } } function ke(e, t, r) { return a(e, e.firstChild, t, r) } function Pe(e, t, r) { return a(u(e), e, t, r) } function Me(e, t, r) { return a(e, null, t, r) } function Xe(e, t, r) { return a(u(e), e.nextSibling, t, r) } function De(e, t, r) { m(e); return u(e).removeChild(e) } function Ue(e, t, r) { var n = e.firstChild; a(e, n, t, r); if (n) { while (n.nextSibling) { m(n.nextSibling); e.removeChild(n.nextSibling) } m(n); e.removeChild(n) } } function Be(e, t, r) { var n = r || ne(e, "hx-select"); if (n) { var i = re().createDocumentFragment(); oe(t.querySelectorAll(n), function (e) { i.appendChild(e) }); t = i } return t } function Fe(e, t, r, n, i) { switch (e) { case "none": return; case "outerHTML": Ie(r, n, i); return; case "afterbegin": ke(r, n, i); return; case "beforebegin": Pe(r, n, i); return; case "beforeend": Me(r, n, i); return; case "afterend": Xe(r, n, i); return; case "delete": De(r, n, i); return; default: var a = Fr(t); for (var o = 0; o < a.length; o++) { var s = a[o]; try { var l = s.handleSwap(e, r, n, i); if (l) { if (typeof l.length !== "undefined") { for (var u = 0; u < l.length; u++) { var f = l[u]; if (f.nodeType !== Node.TEXT_NODE && f.nodeType !== Node.COMMENT_NODE) { i.tasks.push(Oe(f)) } } } return } } catch (e) { b(e) } } if (e === "innerHTML") { Ue(r, n, i) } else { Fe(Q.config.defaultSwapStyle, t, r, n, i) } } } function Ve(e) { if (e.indexOf(" -1) { var t = e.replace(H, ""); var r = t.match(q); if (r) { return r[2] } } } function je(e, t, r, n, i, a) { i.title = Ve(n); var o = l(n); if (o) { Ce(r, o, i); o = Be(r, o, a); Re(o); return Fe(e, r, t, o, i) } } function _e(e, t, r) { var n = e.getResponseHeader(t); if (n.indexOf("{") === 0) { var i = E(n); for (var a in i) { if (i.hasOwnProperty(a)) { var o = i[a]; if (!P(o)) { o = { value: o } } ce(r, a, o) } } } else { var s = n.split(","); for (var l = 0; l < s.length; l++) { ce(r, s[l].trim(), []) } } } var ze = /\s/; var x = /[\s,]/; var $e = /[_$a-zA-Z]/; var We = /[_$a-zA-Z0-9]/; var Ge = ['"', "'", "/"]; var Je = /[^\s]/; var Ze = /[{(]/; var Ke = /[})]/; function Ye(e) { var t = []; var r = 0; while (r < e.length) { if ($e.exec(e.charAt(r))) { var n = r; while (We.exec(e.charAt(r + 1))) { r++ } t.push(e.substr(n, r - n + 1)) } else if (Ge.indexOf(e.charAt(r)) !== -1) { var i = e.charAt(r); var n = r; r++; while (r < e.length && e.charAt(r) !== i) { if (e.charAt(r) === "\\") { r++ } r++ } t.push(e.substr(n, r - n + 1)) } else { var a = e.charAt(r); t.push(a) } r++ } return t } function Qe(e, t, r) { return $e.exec(e.charAt(0)) && e !== "true" && e !== "false" && e !== "this" && e !== r && t !== "." } function et(e, t, r) { if (t[0] === "[") { t.shift(); var n = 1; var i = " return (function(" + r + "){ return ("; var a = null; while (t.length > 0) { var o = t[0]; if (o === "]") { n--; if (n === 0) { if (a === null) { i = i + "true" } t.shift(); i += ")})"; try { var s = Tr(e, function () { return Function(i)() }, function () { return true }); s.source = i; return s } catch (e) { fe(re().body, "htmx:syntax:error", { error: e, source: i }); return null } } } else if (o === "[") { n++ } if (Qe(o, a, r)) { i += "((" + r + "." + o + ") ? (" + r + "." + o + ") : (window." + o + "))" } else { i = i + o } a = t.shift() } } } function y(e, t) { var r = ""; while (e.length > 0 && !t.test(e[0])) { r += e.shift() } return r } function tt(e) { var t; if (e.length > 0 && Ze.test(e[0])) { e.shift(); t = y(e, Ke).trim(); e.shift() } else { t = y(e, x) } return t } var rt = "input, textarea, select"; function nt(e, t, r) { var n = []; var i = Ye(t); do { y(i, Je); var a = i.length; var o = y(i, /[,\[\s]/); if (o !== "") { if (o === "every") { var s = { trigger: "every" }; y(i, Je); s.pollInterval = d(y(i, /[,\[\s]/)); y(i, Je); var l = et(e, i, "event"); if (l) { s.eventFilter = l } n.push(s) } else if (o.indexOf("sse:") === 0) { n.push({ trigger: "sse", sseEvent: o.substr(4) }) } else { var u = { trigger: o }; var l = et(e, i, "event"); if (l) { u.eventFilter = l } while (i.length > 0 && i[0] !== ",") { y(i, Je); var f = i.shift(); if (f === "changed") { u.changed = true } else if (f === "once") { u.once = true } else if (f === "consume") { u.consume = true } else if (f === "delay" && i[0] === ":") { i.shift(); u.delay = d(y(i, x)) } else if (f === "from" && i[0] === ":") { i.shift(); if (Ze.test(i[0])) { var c = tt(i) } else { var c = y(i, x); if (c === "closest" || c === "find" || c === "next" || c === "previous") { i.shift(); var h = tt(i); if (h.length > 0) { c += " " + h } } } u.from = c } else if (f === "target" && i[0] === ":") { i.shift(); u.target = tt(i) } else if (f === "throttle" && i[0] === ":") { i.shift(); u.throttle = d(y(i, x)) } else if (f === "queue" && i[0] === ":") { i.shift(); u.queue = y(i, x) } else if (f === "root" && i[0] === ":") { i.shift(); u[f] = tt(i) } else if (f === "threshold" && i[0] === ":") { i.shift(); u[f] = y(i, x) } else { fe(e, "htmx:syntax:error", { token: i.shift() }) } } n.push(u) } } if (i.length === a) { fe(e, "htmx:syntax:error", { token: i.shift() }) } y(i, Je) } while (i[0] === "," && i.shift()); if (r) { r[t] = n } return n } function it(e) { var t = te(e, "hx-trigger"); var r = []; if (t) { var n = Q.config.triggerSpecsCache; r = n && n[t] || nt(e, t, n) } if (r.length > 0) { return r } else if (h(e, "form")) { return [{ trigger: "submit" }] } else if (h(e, 'input[type="button"], input[type="submit"]')) { return [{ trigger: "click" }] } else if (h(e, rt)) { return [{ trigger: "change" }] } else { return [{ trigger: "click" }] } } function at(e) { ae(e).cancelled = true } function ot(e, t, r) { var n = ae(e); n.timeout = setTimeout(function () { if (se(e) && n.cancelled !== true) { if (!ct(r, e, Wt("hx:poll:trigger", { triggerSpec: r, target: e }))) { t(e) } ot(e, t, r) } }, r.pollInterval) } function st(e) { return location.hostname === e.hostname && ee(e, "href") && ee(e, "href").indexOf("#") !== 0 } function lt(t, r, e) { if (t.tagName === "A" && st(t) && (t.target === "" || t.target === "_self") || t.tagName === "FORM") { r.boosted = true; var n, i; if (t.tagName === "A") { n = "get"; i = ee(t, "href") } else { var a = ee(t, "method"); n = a ? a.toLowerCase() : "get"; if (n === "get") { } i = ee(t, "action") } e.forEach(function (e) { ht(t, function (e, t) { if (v(e, Q.config.disableSelector)) { m(e); return } he(n, i, e, t) }, r, e, true) }) } } function ut(e, t) { if (e.type === "submit" || e.type === "click") { if (t.tagName === "FORM") { return true } if (h(t, 'input[type="submit"], button') && v(t, "form") !== null) { return true } if (t.tagName === "A" && t.href && (t.getAttribute("href") === "#" || t.getAttribute("href").indexOf("#") !== 0)) { return true } } return false } function ft(e, t) { return ae(e).boosted && e.tagName === "A" && t.type === "click" && (t.ctrlKey || t.metaKey) } function ct(e, t, r) { var n = e.eventFilter; if (n) { try { return n.call(t, r) !== true } catch (e) { fe(re().body, "htmx:eventFilter:error", { error: e, source: n.source }); return true } } return false } function ht(a, o, e, s, l) { var u = ae(a); var t; if (s.from) { t = Z(a, s.from) } else { t = [a] } if (s.changed) { t.forEach(function (e) { var t = ae(e); t.lastValue = e.value }) } oe(t, function (n) { var i = function (e) { if (!se(a)) { n.removeEventListener(s.trigger, i); return } if (ft(a, e)) { return } if (l || ut(e, a)) { e.preventDefault() } if (ct(s, a, e)) { return } var t = ae(e); t.triggerSpec = s; if (t.handledFor == null) { t.handledFor = [] } if (t.handledFor.indexOf(a) < 0) { t.handledFor.push(a); if (s.consume) { e.stopPropagation() } if (s.target && e.target) { if (!h(e.target, s.target)) { return } } if (s.once) { if (u.triggeredOnce) { return } else { u.triggeredOnce = true } } if (s.changed) { var r = ae(n); if (r.lastValue === n.value) { return } r.lastValue = n.value } if (u.delayed) { clearTimeout(u.delayed) } if (u.throttle) { return } if (s.throttle > 0) { if (!u.throttle) { o(a, e); u.throttle = setTimeout(function () { u.throttle = null }, s.throttle) } } else if (s.delay > 0) { u.delayed = setTimeout(function () { o(a, e) }, s.delay) } else { ce(a, "htmx:trigger"); o(a, e) } } }; if (e.listenerInfos == null) { e.listenerInfos = [] } e.listenerInfos.push({ trigger: s.trigger, listener: i, on: n }); n.addEventListener(s.trigger, i) }) } var vt = false; var dt = null; function gt() { if (!dt) { dt = function () { vt = true }; window.addEventListener("scroll", dt); setInterval(function () { if (vt) { vt = false; oe(re().querySelectorAll("[hx-trigger='revealed'],[data-hx-trigger='revealed']"), function (e) { pt(e) }) } }, 200) } } function pt(t) { if (!o(t, "data-hx-revealed") && X(t)) { t.setAttribute("data-hx-revealed", "true"); var e = ae(t); if (e.initHash) { ce(t, "revealed") } else { t.addEventListener("htmx:afterProcessNode", function (e) { ce(t, "revealed") }, { once: true }) } } } function mt(e, t, r) { var n = D(r); for (var i = 0; i < n.length; i++) { var a = n[i].split(/:(.+)/); if (a[0] === "connect") { xt(e, a[1], 0) } if (a[0] === "send") { bt(e) } } } function xt(s, r, n) { if (!se(s)) { return } if (r.indexOf("/") == 0) { var e = location.hostname + (location.port ? ":" + location.port : ""); if (location.protocol == "https:") { r = "wss://" + e + r } else if (location.protocol == "http:") { r = "ws://" + e + r } } var t = Q.createWebSocket(r); t.onerror = function (e) { fe(s, "htmx:wsError", { error: e, socket: t }); yt(s) }; t.onclose = function (e) { if ([1006, 1012, 1013].indexOf(e.code) >= 0) { var t = wt(n); setTimeout(function () { xt(s, r, n + 1) }, t) } }; t.onopen = function (e) { n = 0 }; ae(s).webSocket = t; t.addEventListener("message", function (e) { if (yt(s)) { return } var t = e.data; R(s, function (e) { t = e.transformResponse(t, null, s) }); var r = T(s); var n = l(t); var i = M(n.children); for (var a = 0; a < i.length; a++) { var o = i[a]; Ee(te(o, "hx-swap-oob") || "true", o, r) } nr(r.tasks) }) } function yt(e) { if (!se(e)) { ae(e).webSocket.close(); return true } } function bt(u) { var f = c(u, function (e) { return ae(e).webSocket != null }); if (f) { u.addEventListener(it(u)[0].trigger, function (e) { var t = ae(f).webSocket; var r = xr(u, f); var n = dr(u, "post"); var i = n.errors; var a = n.values; var o = Hr(u); var s = le(a, o); var l = yr(s, u); l["HEADERS"] = r; if (i && i.length > 0) { ce(u, "htmx:validation:halted", i); return } t.send(JSON.stringify(l)); if (ut(e, u)) { e.preventDefault() } }) } else { fe(u, "htmx:noWebSocketSourceError") } } function wt(e) { var t = Q.config.wsReconnectDelay; if (typeof t === "function") { return t(e) } if (t === "full-jitter") { var r = Math.min(e, 6); var n = 1e3 * Math.pow(2, r); return n * Math.random() } b('htmx.config.wsReconnectDelay must either be a function or the string "full-jitter"') } function St(e, t, r) { var n = D(r); for (var i = 0; i < n.length; i++) { var a = n[i].split(/:(.+)/); if (a[0] === "connect") { Et(e, a[1]) } if (a[0] === "swap") { Ct(e, a[1]) } } } function Et(t, e) { var r = Q.createEventSource(e); r.onerror = function (e) { fe(t, "htmx:sseError", { error: e, source: r }); Tt(t) }; ae(t).sseEventSource = r } function Ct(a, o) { var s = c(a, Ot); if (s) { var l = ae(s).sseEventSource; var u = function (e) { if (Tt(s)) { return } if (!se(a)) { l.removeEventListener(o, u); return } var t = e.data; R(a, function (e) { t = e.transformResponse(t, null, a) }); var r = wr(a); var n = ye(a); var i = T(a); je(r.swapStyle, n, a, t, i); nr(i.tasks); ce(a, "htmx:sseMessage", e) }; ae(a).sseListener = u; l.addEventListener(o, u) } else { fe(a, "htmx:noSSESourceError") } } function Rt(e, t, r) { var n = c(e, Ot); if (n) { var i = ae(n).sseEventSource; var a = function () { if (!Tt(n)) { if (se(e)) { t(e) } else { i.removeEventListener(r, a) } } }; ae(e).sseListener = a; i.addEventListener(r, a) } else { fe(e, "htmx:noSSESourceError") } } function Tt(e) { if (!se(e)) { ae(e).sseEventSource.close(); return true } } function Ot(e) { return ae(e).sseEventSource != null } function qt(e, t, r, n) { var i = function () { if (!r.loaded) { r.loaded = true; t(e) } }; if (n > 0) { setTimeout(i, n) } else { i() } } function Ht(t, i, e) { var a = false; oe(w, function (r) { if (o(t, "hx-" + r)) { var n = te(t, "hx-" + r); a = true; i.path = n; i.verb = r; e.forEach(function (e) { Lt(t, e, i, function (e, t) { if (v(e, Q.config.disableSelector)) { m(e); return } he(r, n, e, t) }) }) } }); return a } function Lt(n, e, t, r) { if (e.sseEvent) { Rt(n, r, e.sseEvent) } else if (e.trigger === "revealed") { gt(); ht(n, r, t, e); pt(n) } else if (e.trigger === "intersect") { var i = {}; if (e.root) { i.root = ue(n, e.root) } if (e.threshold) { i.threshold = parseFloat(e.threshold) } var a = new IntersectionObserver(function (e) { for (var t = 0; t < e.length; t++) { var r = e[t]; if (r.isIntersecting) { ce(n, "intersect"); break } } }, i); a.observe(n); ht(n, r, t, e) } else if (e.trigger === "load") { if (!ct(e, n, Wt("load", { elt: n }))) { qt(n, r, t, e.delay) } } else if (e.pollInterval > 0) { t.polling = true; ot(n, r, e) } else { ht(n, r, t, e) } } function At(e) { if (!e.htmxExecuted && Q.config.allowScriptTags && (e.type === "text/javascript" || e.type === "module" || e.type === "")) { var t = re().createElement("script"); oe(e.attributes, function (e) { t.setAttribute(e.name, e.value) }); t.textContent = e.textContent; t.async = false; if (Q.config.inlineScriptNonce) { t.nonce = Q.config.inlineScriptNonce } var r = e.parentElement; try { r.insertBefore(t, e) } catch (e) { b(e) } finally { if (e.parentElement) { e.parentElement.removeChild(e) } } } } function Nt(e) { if (h(e, "script")) { At(e) } oe(f(e, "script"), function (e) { At(e) }) } function It(e) { var t = e.attributes; if (!t) { return false } for (var r = 0; r < t.length; r++) { var n = t[r].name; if (g(n, "hx-on:") || g(n, "data-hx-on:") || g(n, "hx-on-") || g(n, "data-hx-on-")) { return true } } return false } function kt(e) { var t = null; var r = []; if (It(e)) { r.push(e) } if (document.evaluate) { var n = document.evaluate('.//*[@*[ starts-with(name(), "hx-on:") or starts-with(name(), "data-hx-on:") or' + ' starts-with(name(), "hx-on-") or starts-with(name(), "data-hx-on-") ]]', e); while (t = n.iterateNext()) r.push(t) } else if (typeof e.getElementsByTagName === "function") { var i = e.getElementsByTagName("*"); for (var a = 0; a < i.length; a++) { if (It(i[a])) { r.push(i[a]) } } } return r } function Pt(e) { if (e.querySelectorAll) { var t = ", [hx-boost] a, [data-hx-boost] a, a[hx-boost], a[data-hx-boost]"; var r = e.querySelectorAll(i + t + ", form, [type='submit'], [hx-sse], [data-hx-sse], [hx-ws]," + " [data-hx-ws], [hx-ext], [data-hx-ext], [hx-trigger], [data-hx-trigger], [hx-on], [data-hx-on]"); return r } else { return [] } } function Mt(e) { var t = v(e.target, "button, input[type='submit']"); var r = Dt(e); if (r) { r.lastButtonClicked = t } } function Xt(e) { var t = Dt(e); if (t) { t.lastButtonClicked = null } } function Dt(e) { var t = v(e.target, "button, input[type='submit']"); if (!t) { return } var r = p("#" + ee(t, "form")) || v(t, "form"); if (!r) { return } return ae(r) } function Ut(e) { e.addEventListener("click", Mt); e.addEventListener("focusin", Mt); e.addEventListener("focusout", Xt) } function Bt(e) { var t = Ye(e); var r = 0; for (var n = 0; n < t.length; n++) { const i = t[n]; if (i === "{") { r++ } else if (i === "}") { r-- } } return r } function Ft(t, e, r) { var n = ae(t); if (!Array.isArray(n.onHandlers)) { n.onHandlers = [] } var i; var a = function (e) { return Tr(t, function () { if (!i) { i = new Function("event", r) } i.call(t, e) }) }; t.addEventListener(e, a); n.onHandlers.push({ event: e, listener: a }) } function Vt(e) { var t = te(e, "hx-on"); if (t) { var r = {}; var n = t.split("\n"); var i = null; var a = 0; while (n.length > 0) { var o = n.shift(); var s = o.match(/^\s*([a-zA-Z:\-\.]+:)(.*)/); if (a === 0 && s) { o.split(":"); i = s[1].slice(0, -1); r[i] = s[2] } else { r[i] += o } a += Bt(o) } for (var l in r) { Ft(e, l, r[l]) } } } function jt(e) { Ae(e); for (var t = 0; t < e.attributes.length; t++) { var r = e.attributes[t].name; var n = e.attributes[t].value; if (g(r, "hx-on") || g(r, "data-hx-on")) { var i = r.indexOf("-on") + 3; var a = r.slice(i, i + 1); if (a === "-" || a === ":") { var o = r.slice(i + 1); if (g(o, ":")) { o = "htmx" + o } else if (g(o, "-")) { o = "htmx:" + o.slice(1) } else if (g(o, "htmx-")) { o = "htmx:" + o.slice(5) } Ft(e, o, n) } } } } function _t(t) { if (v(t, Q.config.disableSelector)) { m(t); return } var r = ae(t); if (r.initHash !== Le(t)) { Ne(t); r.initHash = Le(t); Vt(t); ce(t, "htmx:beforeProcessNode"); if (t.value) { r.lastValue = t.value } var e = it(t); var n = Ht(t, r, e); if (!n) { if (ne(t, "hx-boost") === "true") { lt(t, r, e) } else if (o(t, "hx-trigger")) { e.forEach(function (e) { Lt(t, e, r, function () { }) }) } } if (t.tagName === "FORM" || ee(t, "type") === "submit" && o(t, "form")) { Ut(t) } var i = te(t, "hx-sse"); if (i) { St(t, r, i) } var a = te(t, "hx-ws"); if (a) { mt(t, r, a) } ce(t, "htmx:afterProcessNode") } } function zt(e) { e = p(e); if (v(e, Q.config.disableSelector)) { m(e); return } _t(e); oe(Pt(e), function (e) { _t(e) }); oe(kt(e), jt) } function $t(e) { return e.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase() } function Wt(e, t) { var r; if (window.CustomEvent && typeof window.CustomEvent === "function") { r = new CustomEvent(e, { bubbles: true, cancelable: true, detail: t }) } else { r = re().createEvent("CustomEvent"); r.initCustomEvent(e, true, true, t) } return r } function fe(e, t, r) { ce(e, t, le({ error: t }, r)) } function Gt(e) { return e === "htmx:afterProcessNode" } function R(e, t) { oe(Fr(e), function (e) { try { t(e) } catch (e) { b(e) } }) } function b(e) { if (console.error) { console.error(e) } else if (console.log) { console.log("ERROR: ", e) } } function ce(e, t, r) { e = p(e); if (r == null) { r = {} } r["elt"] = e; var n = Wt(t, r); if (Q.logger && !Gt(t)) { Q.logger(e, t, r) } if (r.error) { b(r.error); ce(e, "htmx:error", { errorInfo: r }) } var i = e.dispatchEvent(n); var a = $t(t); if (i && a !== t) { var o = Wt(a, n.detail); i = i && e.dispatchEvent(o) } R(e, function (e) { i = i && (e.onEvent(t, n) !== false && !n.defaultPrevented) }); return i } var Jt = location.pathname + location.search; function Zt() { var e = re().querySelector("[hx-history-elt],[data-hx-history-elt]"); return e || re().body } function Kt(e, t, r, n) { if (!U()) { return } if (Q.config.historyCacheSize <= 0) { localStorage.removeItem("htmx-history-cache"); return } e = B(e); var i = E(localStorage.getItem("htmx-history-cache")) || []; for (var a = 0; a < i.length; a++) { if (i[a].url === e) { i.splice(a, 1); break } } var o = { url: e, content: t, title: r, scroll: n }; ce(re().body, "htmx:historyItemCreated", { item: o, cache: i }); i.push(o); while (i.length > Q.config.historyCacheSize) { i.shift() } while (i.length > 0) { try { localStorage.setItem("htmx-history-cache", JSON.stringify(i)); break } catch (e) { fe(re().body, "htmx:historyCacheError", { cause: e, cache: i }); i.shift() } } } function Yt(e) { if (!U()) { return null } e = B(e); var t = E(localStorage.getItem("htmx-history-cache")) || []; for (var r = 0; r < t.length; r++) { if (t[r].url === e) { return t[r] } } return null } function Qt(e) { var t = Q.config.requestClass; var r = e.cloneNode(true); oe(f(r, "." + t), function (e) { n(e, t) }); return r.innerHTML } function er() { var e = Zt(); var t = Jt || location.pathname + location.search; var r; try { r = re().querySelector('[hx-history="false" i],[data-hx-history="false" i]') } catch (e) { r = re().querySelector('[hx-history="false"],[data-hx-history="false"]') } if (!r) { ce(re().body, "htmx:beforeHistorySave", { path: t, historyElt: e }); Kt(t, Qt(e), re().title, window.scrollY) } if (Q.config.historyEnabled) history.replaceState({ htmx: true }, re().title, window.location.href) } function tr(e) { if (Q.config.getCacheBusterParam) { e = e.replace(/org\.htmx\.cache-buster=[^&]*&?/, ""); if (G(e, "&") || G(e, "?")) { e = e.slice(0, -1) } } if (Q.config.historyEnabled) { history.pushState({ htmx: true }, "", e) } Jt = e } function rr(e) { if (Q.config.historyEnabled) history.replaceState({ htmx: true }, "", e); Jt = e } function nr(e) { oe(e, function (e) { e.call() }) } function ir(a) { var e = new XMLHttpRequest; var o = { path: a, xhr: e }; ce(re().body, "htmx:historyCacheMiss", o); e.open("GET", a, true); e.setRequestHeader("HX-Request", "true"); e.setRequestHeader("HX-History-Restore-Request", "true"); e.setRequestHeader("HX-Current-URL", re().location.href); e.onload = function () { if (this.status >= 200 && this.status < 400) { ce(re().body, "htmx:historyCacheMissLoad", o); var e = l(this.response); e = e.querySelector("[hx-history-elt],[data-hx-history-elt]") || e; var t = Zt(); var r = T(t); var n = Ve(this.response); if (n) { var i = C("title"); if (i) { i.innerHTML = n } else { window.document.title = n } } Ue(t, e, r); nr(r.tasks); Jt = a; ce(re().body, "htmx:historyRestore", { path: a, cacheMiss: true, serverResponse: this.response }) } else { fe(re().body, "htmx:historyCacheMissLoadError", o) } }; e.send() } function ar(e) { er(); e = e || location.pathname + location.search; var t = Yt(e); if (t) { var r = l(t.content); var n = Zt(); var i = T(n); Ue(n, r, i); nr(i.tasks); document.title = t.title; setTimeout(function () { window.scrollTo(0, t.scroll) }, 0); Jt = e; ce(re().body, "htmx:historyRestore", { path: e, item: t }) } else { if (Q.config.refreshOnHistoryMiss) { window.location.reload(true) } else { ir(e) } } } function or(e) { var t = me(e, "hx-indicator"); if (t == null) { t = [e] } oe(t, function (e) { var t = ae(e); t.requestCount = (t.requestCount || 0) + 1; e.classList["add"].call(e.classList, Q.config.requestClass) }); return t } function sr(e) { var t = me(e, "hx-disabled-elt"); if (t == null) { t = [] } oe(t, function (e) { var t = ae(e); t.requestCount = (t.requestCount || 0) + 1; e.setAttribute("disabled", "") }); return t } function lr(e, t) { oe(e, function (e) { var t = ae(e); t.requestCount = (t.requestCount || 0) - 1; if (t.requestCount === 0) { e.classList["remove"].call(e.classList, Q.config.requestClass) } }); oe(t, function (e) { var t = ae(e); t.requestCount = (t.requestCount || 0) - 1; if (t.requestCount === 0) { e.removeAttribute("disabled") } }) } function ur(e, t) { for (var r = 0; r < e.length; r++) { var n = e[r]; if (n.isSameNode(t)) { return true } } return false } function fr(e) { if (e.name === "" || e.name == null || e.disabled || v(e, "fieldset[disabled]")) { return false } if (e.type === "button" || e.type === "submit" || e.tagName === "image" || e.tagName === "reset" || e.tagName === "file") { return false } if (e.type === "checkbox" || e.type === "radio") { return e.checked } return true } function cr(e, t, r) { if (e != null && t != null) { var n = r[e]; if (n === undefined) { r[e] = t } else if (Array.isArray(n)) { if (Array.isArray(t)) { r[e] = n.concat(t) } else { n.push(t) } } else { if (Array.isArray(t)) { r[e] = [n].concat(t) } else { r[e] = [n, t] } } } } function hr(t, r, n, e, i) { if (e == null || ur(t, e)) { return } else { t.push(e) } if (fr(e)) { var a = ee(e, "name"); var o = e.value; if (e.multiple && e.tagName === "SELECT") { o = M(e.querySelectorAll("option:checked")).map(function (e) { return e.value }) } if (e.files) { o = M(e.files) } cr(a, o, r); if (i) { vr(e, n) } } if (h(e, "form")) { var s = e.elements; oe(s, function (e) { hr(t, r, n, e, i) }) } } function vr(e, t) { if (e.willValidate) { ce(e, "htmx:validation:validate"); if (!e.checkValidity()) { t.push({ elt: e, message: e.validationMessage, validity: e.validity }); ce(e, "htmx:validation:failed", { message: e.validationMessage, validity: e.validity }) } } } function dr(e, t) { var r = []; var n = {}; var i = {}; var a = []; var o = ae(e); if (o.lastButtonClicked && !se(o.lastButtonClicked)) { o.lastButtonClicked = null } var s = h(e, "form") && e.noValidate !== true || te(e, "hx-validate") === "true"; if (o.lastButtonClicked) { s = s && o.lastButtonClicked.formNoValidate !== true } if (t !== "get") { hr(r, i, a, v(e, "form"), s) } hr(r, n, a, e, s); if (o.lastButtonClicked || e.tagName === "BUTTON" || e.tagName === "INPUT" && ee(e, "type") === "submit") { var l = o.lastButtonClicked || e; var u = ee(l, "name"); cr(u, l.value, i) } var f = me(e, "hx-include"); oe(f, function (e) { hr(r, n, a, e, s); if (!h(e, "form")) { oe(e.querySelectorAll(rt), function (e) { hr(r, n, a, e, s) }) } }); n = le(n, i); return { errors: a, values: n } } function gr(e, t, r) { if (e !== "") { e += "&" } if (String(r) === "[object Object]") { r = JSON.stringify(r) } var n = encodeURIComponent(r); e += encodeURIComponent(t) + "=" + n; return e } function pr(e) { var t = ""; for (var r in e) { if (e.hasOwnProperty(r)) { var n = e[r]; if (Array.isArray(n)) { oe(n, function (e) { t = gr(t, r, e) }) } else { t = gr(t, r, n) } } } return t } function mr(e) { var t = new FormData; for (var r in e) { if (e.hasOwnProperty(r)) { var n = e[r]; if (Array.isArray(n)) { oe(n, function (e) { t.append(r, e) }) } else { t.append(r, n) } } } return t } function xr(e, t, r) { var n = { "HX-Request": "true", "HX-Trigger": ee(e, "id"), "HX-Trigger-Name": ee(e, "name"), "HX-Target": te(t, "id"), "HX-Current-URL": re().location.href }; Rr(e, "hx-headers", false, n); if (r !== undefined) { n["HX-Prompt"] = r } if (ae(e).boosted) { n["HX-Boosted"] = "true" } return n } function yr(t, e) { var r = ne(e, "hx-params"); if (r) { if (r === "none") { return {} } else if (r === "*") { return t } else if (r.indexOf("not ") === 0) { oe(r.substr(4).split(","), function (e) { e = e.trim(); delete t[e] }); return t } else { var n = {}; oe(r.split(","), function (e) { e = e.trim(); n[e] = t[e] }); return n } } else { return t } } function br(e) { return ee(e, "href") && ee(e, "href").indexOf("#") >= 0 } function wr(e, t) { var r = t ? t : ne(e, "hx-swap"); var n = { swapStyle: ae(e).boosted ? "innerHTML" : Q.config.defaultSwapStyle, swapDelay: Q.config.defaultSwapDelay, settleDelay: Q.config.defaultSettleDelay }; if (Q.config.scrollIntoViewOnBoost && ae(e).boosted && !br(e)) { n["show"] = "top" } if (r) { var i = D(r); if (i.length > 0) { for (var a = 0; a < i.length; a++) { var o = i[a]; if (o.indexOf("swap:") === 0) { n["swapDelay"] = d(o.substr(5)) } else if (o.indexOf("settle:") === 0) { n["settleDelay"] = d(o.substr(7)) } else if (o.indexOf("transition:") === 0) { n["transition"] = o.substr(11) === "true" } else if (o.indexOf("ignoreTitle:") === 0) { n["ignoreTitle"] = o.substr(12) === "true" } else if (o.indexOf("scroll:") === 0) { var s = o.substr(7); var l = s.split(":"); var u = l.pop(); var f = l.length > 0 ? l.join(":") : null; n["scroll"] = u; n["scrollTarget"] = f } else if (o.indexOf("show:") === 0) { var c = o.substr(5); var l = c.split(":"); var h = l.pop(); var f = l.length > 0 ? l.join(":") : null; n["show"] = h; n["showTarget"] = f } else if (o.indexOf("focus-scroll:") === 0) { var v = o.substr("focus-scroll:".length); n["focusScroll"] = v == "true" } else if (a == 0) { n["swapStyle"] = o } else { b("Unknown modifier in hx-swap: " + o) } } } } return n } function Sr(e) { return ne(e, "hx-encoding") === "multipart/form-data" || h(e, "form") && ee(e, "enctype") === "multipart/form-data" } function Er(t, r, n) { var i = null; R(r, function (e) { if (i == null) { i = e.encodeParameters(t, n, r) } }); if (i != null) { return i } else { if (Sr(r)) { return mr(n) } else { return pr(n) } } } function T(e) { return { tasks: [], elts: [e] } } function Cr(e, t) { var r = e[0]; var n = e[e.length - 1]; if (t.scroll) { var i = null; if (t.scrollTarget) { i = ue(r, t.scrollTarget) } if (t.scroll === "top" && (r || i)) { i = i || r; i.scrollTop = 0 } if (t.scroll === "bottom" && (n || i)) { i = i || n; i.scrollTop = i.scrollHeight } } if (t.show) { var i = null; if (t.showTarget) { var a = t.showTarget; if (t.showTarget === "window") { a = "body" } i = ue(r, a) } if (t.show === "top" && (r || i)) { i = i || r; i.scrollIntoView({ block: "start", behavior: Q.config.scrollBehavior }) } if (t.show === "bottom" && (n || i)) { i = i || n; i.scrollIntoView({ block: "end", behavior: Q.config.scrollBehavior }) } } } function Rr(e, t, r, n) { if (n == null) { n = {} } if (e == null) { return n } var i = te(e, t); if (i) { var a = i.trim(); var o = r; if (a === "unset") { return null } if (a.indexOf("javascript:") === 0) { a = a.substr(11); o = true } else if (a.indexOf("js:") === 0) { a = a.substr(3); o = true } if (a.indexOf("{") !== 0) { a = "{" + a + "}" } var s; if (o) { s = Tr(e, function () { return Function("return (" + a + ")")() }, {}) } else { s = E(a) } for (var l in s) { if (s.hasOwnProperty(l)) { if (n[l] == null) { n[l] = s[l] } } } } return Rr(u(e), t, r, n) } function Tr(e, t, r) { if (Q.config.allowEval) { return t() } else { fe(e, "htmx:evalDisallowedError"); return r } } function Or(e, t) { return Rr(e, "hx-vars", true, t) } function qr(e, t) { return Rr(e, "hx-vals", false, t) } function Hr(e) { return le(Or(e), qr(e)) } function Lr(t, r, n) { if (n !== null) { try { t.setRequestHeader(r, n) } catch (e) { t.setRequestHeader(r, encodeURIComponent(n)); t.setRequestHeader(r + "-URI-AutoEncoded", "true") } } } function Ar(t) { if (t.responseURL && typeof URL !== "undefined") { try { var e = new URL(t.responseURL); return e.pathname + e.search } catch (e) { fe(re().body, "htmx:badResponseUrl", { url: t.responseURL }) } } } function O(e, t) { return t.test(e.getAllResponseHeaders()) } function Nr(e, t, r) { e = e.toLowerCase(); if (r) { if (r instanceof Element || I(r, "String")) { return he(e, t, null, null, { targetOverride: p(r), returnPromise: true }) } else { return he(e, t, p(r.source), r.event, { handler: r.handler, headers: r.headers, values: r.values, targetOverride: p(r.target), swapOverride: r.swap, select: r.select, returnPromise: true }) } } else { return he(e, t, null, null, { returnPromise: true }) } } function Ir(e) { var t = []; while (e) { t.push(e); e = e.parentElement } return t } function kr(e, t, r) { var n; var i; if (typeof URL === "function") { i = new URL(t, document.location.href); var a = document.location.origin; n = a === i.origin } else { i = t; n = g(t, document.location.origin) } if (Q.config.selfRequestsOnly) { if (!n) { return false } } return ce(e, "htmx:validateUrl", le({ url: i, sameHost: n }, r)) } function he(t, r, n, i, a, e) { var o = null; var s = null; a = a != null ? a : {}; if (a.returnPromise && typeof Promise !== "undefined") { var l = new Promise(function (e, t) { o = e; s = t }) } if (n == null) { n = re().body } var M = a.handler || Mr; var X = a.select || null; if (!se(n)) { ie(o); return l } var u = a.targetOverride || ye(n); if (u == null || u == pe) { fe(n, "htmx:targetError", { target: te(n, "hx-target") }); ie(s); return l } var f = ae(n); var c = f.lastButtonClicked; if (c) { var h = ee(c, "formaction"); if (h != null) { r = h } var v = ee(c, "formmethod"); if (v != null) { if (v.toLowerCase() !== "dialog") { t = v } } } var d = ne(n, "hx-confirm"); if (e === undefined) { var D = function (e) { return he(t, r, n, i, a, !!e) }; var U = { target: u, elt: n, path: r, verb: t, triggeringEvent: i, etc: a, issueRequest: D, question: d }; if (ce(n, "htmx:confirm", U) === false) { ie(o); return l } } var g = n; var p = ne(n, "hx-sync"); var m = null; var x = false; if (p) { var B = p.split(":"); var F = B[0].trim(); if (F === "this") { g = xe(n, "hx-sync") } else { g = ue(n, F) } p = (B[1] || "drop").trim(); f = ae(g); if (p === "drop" && f.xhr && f.abortable !== true) { ie(o); return l } else if (p === "abort") { if (f.xhr) { ie(o); return l } else { x = true } } else if (p === "replace") { ce(g, "htmx:abort") } else if (p.indexOf("queue") === 0) { var V = p.split(" "); m = (V[1] || "last").trim() } } if (f.xhr) { if (f.abortable) { ce(g, "htmx:abort") } else { if (m == null) { if (i) { var y = ae(i); if (y && y.triggerSpec && y.triggerSpec.queue) { m = y.triggerSpec.queue } } if (m == null) { m = "last" } } if (f.queuedRequests == null) { f.queuedRequests = [] } if (m === "first" && f.queuedRequests.length === 0) { f.queuedRequests.push(function () { he(t, r, n, i, a) }) } else if (m === "all") { f.queuedRequests.push(function () { he(t, r, n, i, a) }) } else if (m === "last") { f.queuedRequests = []; f.queuedRequests.push(function () { he(t, r, n, i, a) }) } ie(o); return l } } var b = new XMLHttpRequest; f.xhr = b; f.abortable = x; var w = function () { f.xhr = null; f.abortable = false; if (f.queuedRequests != null && f.queuedRequests.length > 0) { var e = f.queuedRequests.shift(); e() } }; var j = ne(n, "hx-prompt"); if (j) { var S = prompt(j); if (S === null || !ce(n, "htmx:prompt", { prompt: S, target: u })) { ie(o); w(); return l } } if (d && !e) { if (!confirm(d)) { ie(o); w(); return l } } var E = xr(n, u, S); if (t !== "get" && !Sr(n)) { E["Content-Type"] = "application/x-www-form-urlencoded" } if (a.headers) { E = le(E, a.headers) } var _ = dr(n, t); var C = _.errors; var R = _.values; if (a.values) { R = le(R, a.values) } var z = Hr(n); var $ = le(R, z); var T = yr($, n); if (Q.config.getCacheBusterParam && t === "get") { T["org.htmx.cache-buster"] = ee(u, "id") || "true" } if (r == null || r === "") { r = re().location.href } var O = Rr(n, "hx-request"); var W = ae(n).boosted; var q = Q.config.methodsThatUseUrlParams.indexOf(t) >= 0; var H = { boosted: W, useUrlParams: q, parameters: T, unfilteredParameters: $, headers: E, target: u, verb: t, errors: C, withCredentials: a.credentials || O.credentials || Q.config.withCredentials, timeout: a.timeout || O.timeout || Q.config.timeout, path: r, triggeringEvent: i }; if (!ce(n, "htmx:configRequest", H)) { ie(o); w(); return l } r = H.path; t = H.verb; E = H.headers; T = H.parameters; C = H.errors; q = H.useUrlParams; if (C && C.length > 0) { ce(n, "htmx:validation:halted", H); ie(o); w(); return l } var G = r.split("#"); var J = G[0]; var L = G[1]; var A = r; if (q) { A = J; var Z = Object.keys(T).length !== 0; if (Z) { if (A.indexOf("?") < 0) { A += "?" } else { A += "&" } A += pr(T); if (L) { A += "#" + L } } } if (!kr(n, A, H)) { fe(n, "htmx:invalidPath", H); ie(s); return l } b.open(t.toUpperCase(), A, true); b.overrideMimeType("text/html"); b.withCredentials = H.withCredentials; b.timeout = H.timeout; if (O.noHeaders) { } else { for (var N in E) { if (E.hasOwnProperty(N)) { var K = E[N]; Lr(b, N, K) } } } var I = { xhr: b, target: u, requestConfig: H, etc: a, boosted: W, select: X, pathInfo: { requestPath: r, finalRequestPath: A, anchor: L } }; b.onload = function () { try { var e = Ir(n); I.pathInfo.responsePath = Ar(b); M(n, I); lr(k, P); ce(n, "htmx:afterRequest", I); ce(n, "htmx:afterOnLoad", I); if (!se(n)) { var t = null; while (e.length > 0 && t == null) { var r = e.shift(); if (se(r)) { t = r } } if (t) { ce(t, "htmx:afterRequest", I); ce(t, "htmx:afterOnLoad", I) } } ie(o); w() } catch (e) { fe(n, "htmx:onLoadError", le({ error: e }, I)); throw e } }; b.onerror = function () { lr(k, P); fe(n, "htmx:afterRequest", I); fe(n, "htmx:sendError", I); ie(s); w() }; b.onabort = function () { lr(k, P); fe(n, "htmx:afterRequest", I); fe(n, "htmx:sendAbort", I); ie(s); w() }; b.ontimeout = function () { lr(k, P); fe(n, "htmx:afterRequest", I); fe(n, "htmx:timeout", I); ie(s); w() }; if (!ce(n, "htmx:beforeRequest", I)) { ie(o); w(); return l } var k = or(n); var P = sr(n); oe(["loadstart", "loadend", "progress", "abort"], function (t) { oe([b, b.upload], function (e) { e.addEventListener(t, function (e) { ce(n, "htmx:xhr:" + t, { lengthComputable: e.lengthComputable, loaded: e.loaded, total: e.total }) }) }) }); ce(n, "htmx:beforeSend", I); var Y = q ? null : Er(b, n, T); b.send(Y); return l } function Pr(e, t) { var r = t.xhr; var n = null; var i = null; if (O(r, /HX-Push:/i)) { n = r.getResponseHeader("HX-Push"); i = "push" } else if (O(r, /HX-Push-Url:/i)) { n = r.getResponseHeader("HX-Push-Url"); i = "push" } else if (O(r, /HX-Replace-Url:/i)) { n = r.getResponseHeader("HX-Replace-Url"); i = "replace" } if (n) { if (n === "false") { return {} } else { return { type: i, path: n } } } var a = t.pathInfo.finalRequestPath; var o = t.pathInfo.responsePath; var s = ne(e, "hx-push-url"); var l = ne(e, "hx-replace-url"); var u = ae(e).boosted; var f = null; var c = null; if (s) { f = "push"; c = s } else if (l) { f = "replace"; c = l } else if (u) { f = "push"; c = o || a } if (c) { if (c === "false") { return {} } if (c === "true") { c = o || a } if (t.pathInfo.anchor && c.indexOf("#") === -1) { c = c + "#" + t.pathInfo.anchor } return { type: f, path: c } } else { return {} } } function Mr(l, u) { var f = u.xhr; var c = u.target; var e = u.etc; var t = u.requestConfig; var h = u.select; if (!ce(l, "htmx:beforeOnLoad", u)) return; if (O(f, /HX-Trigger:/i)) { _e(f, "HX-Trigger", l) } if (O(f, /HX-Location:/i)) { er(); var r = f.getResponseHeader("HX-Location"); var v; if (r.indexOf("{") === 0) { v = E(r); r = v["path"]; delete v["path"] } Nr("GET", r, v).then(function () { tr(r) }); return } var n = O(f, /HX-Refresh:/i) && "true" === f.getResponseHeader("HX-Refresh"); if (O(f, /HX-Redirect:/i)) { location.href = f.getResponseHeader("HX-Redirect"); n && location.reload(); return } if (n) { location.reload(); return } if (O(f, /HX-Retarget:/i)) { if (f.getResponseHeader("HX-Retarget") === "this") { u.target = l } else { u.target = ue(l, f.getResponseHeader("HX-Retarget")) } } var d = Pr(l, u); var i = f.status >= 200 && f.status < 400 && f.status !== 204; var g = f.response; var a = f.status >= 400; var p = Q.config.ignoreTitle; var o = le({ shouldSwap: i, serverResponse: g, isError: a, ignoreTitle: p }, u); if (!ce(c, "htmx:beforeSwap", o)) return; c = o.target; g = o.serverResponse; a = o.isError; p = o.ignoreTitle; u.target = c; u.failed = a; u.successful = !a; if (o.shouldSwap) { if (f.status === 286) { at(l) } R(l, function (e) { g = e.transformResponse(g, f, l) }); if (d.type) { er() } var s = e.swapOverride; if (O(f, /HX-Reswap:/i)) { s = f.getResponseHeader("HX-Reswap") } var v = wr(l, s); if (v.hasOwnProperty("ignoreTitle")) { p = v.ignoreTitle } c.classList.add(Q.config.swappingClass); var m = null; var x = null; var y = function () { try { var e = document.activeElement; var t = {}; try { t = { elt: e, start: e ? e.selectionStart : null, end: e ? e.selectionEnd : null } } catch (e) { } var r; if (h) { r = h } if (O(f, /HX-Reselect:/i)) { r = f.getResponseHeader("HX-Reselect") } if (d.type) { ce(re().body, "htmx:beforeHistoryUpdate", le({ history: d }, u)); if (d.type === "push") { tr(d.path); ce(re().body, "htmx:pushedIntoHistory", { path: d.path }) } else { rr(d.path); ce(re().body, "htmx:replacedInHistory", { path: d.path }) } } var n = T(c); je(v.swapStyle, c, l, g, n, r); if (t.elt && !se(t.elt) && ee(t.elt, "id")) { var i = document.getElementById(ee(t.elt, "id")); var a = { preventScroll: v.focusScroll !== undefined ? !v.focusScroll : !Q.config.defaultFocusScroll }; if (i) { if (t.start && i.setSelectionRange) { try { i.setSelectionRange(t.start, t.end) } catch (e) { } } i.focus(a) } } c.classList.remove(Q.config.swappingClass); oe(n.elts, function (e) { if (e.classList) { e.classList.add(Q.config.settlingClass) } ce(e, "htmx:afterSwap", u) }); if (O(f, /HX-Trigger-After-Swap:/i)) { var o = l; if (!se(l)) { o = re().body } _e(f, "HX-Trigger-After-Swap", o) } var s = function () { oe(n.tasks, function (e) { e.call() }); oe(n.elts, function (e) { if (e.classList) { e.classList.remove(Q.config.settlingClass) } ce(e, "htmx:afterSettle", u) }); if (u.pathInfo.anchor) { var e = re().getElementById(u.pathInfo.anchor); if (e) { e.scrollIntoView({ block: "start", behavior: "auto" }) } } if (n.title && !p) { var t = C("title"); if (t) { t.innerHTML = n.title } else { window.document.title = n.title } } Cr(n.elts, v); if (O(f, /HX-Trigger-After-Settle:/i)) { var r = l; if (!se(l)) { r = re().body } _e(f, "HX-Trigger-After-Settle", r) } ie(m) }; if (v.settleDelay > 0) { setTimeout(s, v.settleDelay) } else { s() } } catch (e) { fe(l, "htmx:swapError", u); ie(x); throw e } }; var b = Q.config.globalViewTransitions; if (v.hasOwnProperty("transition")) { b = v.transition } if (b && ce(l, "htmx:beforeTransition", u) && typeof Promise !== "undefined" && document.startViewTransition) { var w = new Promise(function (e, t) { m = e; x = t }); var S = y; y = function () { document.startViewTransition(function () { S(); return w }) } } if (v.swapDelay > 0) { setTimeout(y, v.swapDelay) } else { y() } } if (a) { fe(l, "htmx:responseError", le({ error: "Response Status Error Code " + f.status + " from " + u.pathInfo.requestPath }, u)) } } var Xr = {}; function Dr() { return { init: function (e) { return null }, onEvent: function (e, t) { return true }, transformResponse: function (e, t, r) { return e }, isInlineSwap: function (e) { return false }, handleSwap: function (e, t, r, n) { return false }, encodeParameters: function (e, t, r) { return null } } } function Ur(e, t) { if (t.init) { t.init(r) } Xr[e] = le(Dr(), t) } function Br(e) { delete Xr[e] } function Fr(e, r, n) { if (e == undefined) { return r } if (r == undefined) { r = [] } if (n == undefined) { n = [] } var t = te(e, "hx-ext"); if (t) { oe(t.split(","), function (e) { e = e.replace(/ /g, ""); if (e.slice(0, 7) == "ignore:") { n.push(e.slice(7)); return } if (n.indexOf(e) < 0) { var t = Xr[e]; if (t && r.indexOf(t) < 0) { r.push(t) } } }) } return Fr(u(e), r, n) } var Vr = false; re().addEventListener("DOMContentLoaded", function () { Vr = true }); function jr(e) { if (Vr || re().readyState === "complete") { e() } else { re().addEventListener("DOMContentLoaded", e) } } function _r() { if (Q.config.includeIndicatorStyles !== false) { re().head.insertAdjacentHTML("beforeend", "") } } function zr() { var e = re().querySelector('meta[name="htmx-config"]'); if (e) { return E(e.content) } else { return null } } function $r() { var e = zr(); if (e) { Q.config = le(Q.config, e) } } jr(function () { $r(); _r(); var e = re().body; zt(e); var t = re().querySelectorAll("[hx-trigger='restored'],[data-hx-trigger='restored']"); e.addEventListener("htmx:abort", function (e) { var t = e.target; var r = ae(t); if (r && r.xhr) { r.xhr.abort() } }); const r = window.onpopstate ? window.onpopstate.bind(window) : null; window.onpopstate = function (e) { if (e.state && e.state.htmx) { ar(); oe(t, function (e) { ce(e, "htmx:restored", { document: re(), triggerEvent: ce }) }) } else { if (r) { r(e) } } }; setTimeout(function () { ce(e, "htmx:load", {}); e = null }, 0) }); return Q }() }); diff --git a/amt/site/static/vendor/htmx/js/hyperscript.min.js b/amt/site/static/vendor/htmx/js/hyperscript.min.js deleted file mode 100644 index 9e11f0b5..00000000 --- a/amt/site/static/vendor/htmx/js/hyperscript.min.js +++ /dev/null @@ -1 +0,0 @@ -(function(e,r){if(typeof define==="function"&&define.amd){define([],r)}else{e._hyperscript=r()}})(typeof self!=="undefined"?self:this,function(){return function(){"use strict";function M(e,r){for(var t in r){if(r.hasOwnProperty(t)){e[t]=r[t]}}return e}function r(e){try{return JSON.parse(e)}catch(e){t(e);return null}}function t(e){if(console.error){console.error(e)}else if(console.log){console.log("ERROR: ",e)}}function u(e,r){return new(e.bind.apply(e,[e].concat(r)))}var _=typeof self!=="undefined"?self:typeof global!=="undefined"?global:this;var j=function(){var b={"+":"PLUS","-":"MINUS","*":"MULTIPLY","/":"DIVIDE",".":"PERIOD","..":"ELLIPSIS","\\":"BACKSLASH",":":"COLON","%":"PERCENT","|":"PIPE","!":"EXCLAMATION","?":"QUESTION","#":"POUND","&":"AMPERSAND",$:"DOLLAR",";":"SEMI",",":"COMMA","(":"L_PAREN",")":"R_PAREN","<":"L_ANG",">":"R_ANG","<=":"LTE_ANG",">=":"GTE_ANG","==":"EQ","===":"EQQ","!=":"NEQ","!==":"NEQQ","{":"L_BRACE","}":"R_BRACE","[":"L_BRACKET","]":"R_BRACKET","=":"EQUALS"};function w(e){return R(e)||C(e)||e==="-"||e==="_"||e===":"}function N(e){return R(e)||C(e)||e==="-"||e==="_"||e===":"}function I(e){return e===" "||e==="\t"||A(e)}function O(e){return"[Line: "+e.line+", Column: "+e.col+"]"}function A(e){return e==="\r"||e==="\n"}function C(e){return e>="0"&&e<="9"}function R(e){return e>="a"&&e<="z"||e>="A"&&e<="Z"}function S(e){return e==="_"||e==="$"}function L(e){return e==="`"||e==="^"}function P(i,o,e){u();var r=null;function u(){while(y(0,true).type==="WHITESPACE"){o.push(i.shift())}}function s(e,r){D.raiseParseError(e,r)}function t(e){var r=l(e);if(r){return r}else{s(this,"Expected '"+e+"' but found '"+k().value+"'")}}function n(e,r,t){for(var n=0;n=0){return v()}}function p(e,r){var t=m(e,r);if(t){return t}else{s(this,"Expected '"+e+"' but found '"+k().value+"'")}}function m(e,r){var r=r||"IDENTIFIER";if(k()&&k().value===e&&k().type===r){return v()}}function v(){var e=i.shift();o.push(e);r=e;u();return e}function h(e,r){var t=[];var n=y(0,true);while((r==null||n.type!==r)&&(e==null||n.value!==e)&&n.type!=="EOF"){var a=i.shift();o.push(a);t.push(n);n=y(0,true)}u();return t}function d(){if(o[o.length-1]&&o[o.length-1].type==="WHITESPACE"){return o[o.length-1].value}else{return""}}function E(){return h(null,"WHITESPACE")}function T(){return i.length>0}function y(e,r){var t;var n=0;do{if(!r){while(i[n]&&i[n].type==="WHITESPACE"){n++}}t=i[n];e--;n++}while(e>-1);if(t){return t}else{return{type:"EOF",value:"<<>>"}}}function k(){return y(0)}function x(){return r}function g(){return e.substring(this.startToken.start,this.endToken.end)}function q(){return e.split("\n")[this.startToken.line-1]}return{matchAnyToken:a,matchAnyOpToken:n,matchOpToken:l,requireOpToken:t,matchTokenType:f,requireTokenType:c,consumeToken:v,matchToken:m,requireToken:p,list:i,consumed:o,source:e,hasMore:T,currentToken:k,lastMatch:x,token:y,consumeUntil:h,consumeUntilWhitespace:E,lastWhitespace:d,sourceFor:g,lineFor:q}}function F(e){if(e.length>0){var r=e[e.length-1];if(r.type==="IDENTIFIER"||r.type==="CLASS_REF"||r.type==="ID_REF"){return false}if(r.op&&(r.value===">"||r.value===")")){return false}}return true}function e(e,r){var t=[];var n=e;var a=0;var i=0;var o=1;var u="";var s=0;function l(){return r&&s===0}while(a0){var i=r.shift();var o=a[i];if(o==null){o={};a[i]=o}a=o}a[t]=n}function C(e,r){var t=[];var n=e;while(n.meta.caller){n=n.meta.caller}if(n.meta.traceMap){return n.meta.traceMap.get(r,t)}}function R(e,r){var a=[];var t=null;while(e!=null){a.push(e);t=e;e=e.meta.caller}if(t.meta.traceMap==null){t.meta.traceMap=new Map}if(!t.meta.traceMap.get(r)){var n={trace:a,print:function(e){e=e||console.error;e("hypertrace /// ");var r=0;for(var t=0;t",n.meta.feature.displayName.padEnd(r+2),"-",n.meta.owner)}}};t.meta.traceMap.set(r,n)}}function S(e){return e.replace(/:/g,function(e){return"\\"+e})}function L(e,r){if(e==null){throw new Error(r.sourceFor()+" is null")}}function P(e){return e==undefined||e.length===0}var F="document"in _?document.currentScript.src:null;return{typeCheck:w,forEach:n,triggerEvent:o,matchesSelector:t,getScript:c,processNode:g,evaluate:x,parse:k,getScriptSelector:E,resolveSymbol:N,makeContext:d,findNext:I,unifiedEval:e,convertValue:T,unifiedExec:v,resolveProperty:O,assignToNamespace:A,registerHyperTrace:R,getHyperTrace:C,getInternalData:b,escapeSelector:S,nullCheck:L,isEmpty:P,hyperscriptUrl:F,HALT:l}}();{D.addLeafExpression("parenthesized",function(e,r,t){if(t.matchOpToken("(")){var n=e.requireElement("expression",t);t.requireOpToken(")");return{type:"parenthesized",expr:n,evaluate:function(e){return n.evaluate(e)}}}});D.addLeafExpression("string",function(e,r,t){var n=t.matchTokenType("STRING");if(n){var a=n.value;if(n.template){var i=j.tokenize(a,true);var o=e.parseStringTemplate(i)}else{var o=[]}return{type:"string",token:n,args:o,op:function(e){var r="";for(var t=1;t");var i=a.map(function(e){if(e.type==="STRING"){return'"'+e.value+'"'}else{return e.value}}).join("");return{type:"queryRef",css:i,evaluate:function(){return document.querySelectorAll(this.css)}}}});D.addGrammarElement("attributeRef",function(e,r,t){if(t.matchOpToken("[")){var n=t.consumeUntil("]");var a=n.map(function(e){return e.value}).join("");var i=a.split("=");var o=i[0];var u=i[1];t.requireOpToken("]");return{type:"attribute_expression",name:o,value:u,args:[u],op:function(e,r){if(this.value){return{name:this.name,value:r}}else{return{name:this.name}}},evaluate:function(e){return r.unifiedEval(this,e)}}}});D.addGrammarElement("objectKey",function(e,r,t){var n;if(n=t.matchTokenType("STRING")){return{type:"objectKey",key:n.value,evaluate:function(){return this.key}}}else if(t.matchOpToken("[")){var a=e.parseElement("expression",t);t.requireOpToken("]");return{type:"objectKey",expr:a,args:[a],op:function(e,r){return r},evaluate:function(e){return r.unifiedEval(this,e)}}}else{var i="";do{n=t.matchTokenType("IDENTIFIER")||t.matchOpToken("-");if(n)i+=n.value}while(n);return{type:"objectKey",key:i,evaluate:function(){return this.key}}}});D.addLeafExpression("objectLiteral",function(e,r,t){if(t.matchOpToken("{")){var n=[];var a=[];if(!t.matchOpToken("}")){do{var i=e.requireElement("objectKey",t);t.requireOpToken(":");var o=e.requireElement("expression",t);a.push(o);n.push(i)}while(t.matchOpToken(","));t.requireOpToken("}")}return{type:"objectLiteral",args:[n,a],op:function(e,r,t){var n={};for(var a=0;a");var i=e.requireElement("expression",t);return{type:"blockLiteral",args:n,expr:i,evaluate:function(r){var e=function(){for(var e=0;e0){return n}else{return null}},evaluate:function(e){return a.unifiedEval(this,e)}};return e.parseElement("indirectExpression",r,n)}});D.addIndirectExpression("asExpression",function(e,t,r,n){if(r.matchToken("as")){var a=e.requireElement("dotOrColonPath",r).evaluate();var i={type:"asExpression",root:n,args:[n],op:function(e,r){return t.convertValue(r,a)},evaluate:function(e){return t.unifiedEval(this,e)}};return e.parseElement("indirectExpression",r,i)}});D.addIndirectExpression("functionCall",function(e,a,r,i){if(r.matchOpToken("(")){var t=[];if(!r.matchOpToken(")")){do{t.push(e.requireElement("expression",r))}while(r.matchOpToken(","));r.requireOpToken(")")}if(i.root){var n={type:"functionCall",root:i,argExressions:t,args:[i.root,t],op:function(e,r,t){a.nullCheck(r,i.root);var n=r[i.prop.value];a.nullCheck(n,i);if(n.hyperfunc){t.push(e)}return n.apply(r,t)},evaluate:function(e){return a.unifiedEval(this,e)}}}else{var n={type:"functionCall",root:i,argExressions:t,args:[i,t],op:function(e,r,t){a.nullCheck(r,i);if(r.hyperfunc){t.push(e)}var n=r.apply(null,t);return n},evaluate:function(e){return a.unifiedEval(this,e)}}}return e.parseElement("indirectExpression",r,n)}});D.addIndirectExpression("arrayIndex",function(e,r,t,n){if(t.matchOpToken("[")){var a=false;var i=false;var o=null;var u=null;if(t.matchOpToken("..")){a=true;o=e.requireElement("expression",t)}else{o=e.requireElement("expression",t);if(t.matchOpToken("..")){i=true;var s=t.currentToken();if(s.type!=="R_BRACKET"){u=e.parseElement("expression",t)}}}t.requireOpToken("]");var l={type:"arrayIndex",root:n,firstIndex:o,secondIndex:u,args:[n,o,u],op:function(e,r,t,n){if(a){return r.slice(0,t+1)}else if(i){if(n!=null){return r.slice(t,n+1)}else{return r.slice(t)}}else{return r[t]}},evaluate:function(e){return G.unifiedEval(this,e,o,u)}};return D.parseElement("indirectExpression",t,l)}});D.addGrammarElement("postfixExpression",function(e,n,r){var t=e.parseElement("primaryExpression",r);if(r.matchOpToken(":")){var a=r.requireTokenType("IDENTIFIER");var i=!r.matchOpToken("!");return{type:"typeCheck",typeName:a,root:t,nullOk:i,args:[t],op:function(e,r){var t=n.typeCheck(r,this.typeName.value,this.nullOk);if(t){return r}else{throw new Error("Typecheck failed! Expected: "+this.typeName.value)}},evaluate:function(e){return n.unifiedEval(this,e)}}}else{return t}});D.addGrammarElement("logicalNot",function(e,r,t){if(t.matchToken("not")){var n=e.requireElement("unaryExpression",t);return{type:"logicalNot",root:n,args:[n],op:function(e,r){return!r},evaluate:function(e){return r.unifiedEval(this,e)}}}});D.addGrammarElement("noExpression",function(e,t,r){if(r.matchToken("no")){var n=e.requireElement("unaryExpression",r);return{type:"noExpression",root:n,args:[n],op:function(e,r){return t.isEmpty(r)},evaluate:function(e){return t.unifiedEval(this,e)}}}});D.addGrammarElement("negativeNumber",function(e,r,t){if(t.matchOpToken("-")){var n=e.requireElement("unaryExpression",t);return{type:"negativeNumber",root:n,args:[n],op:function(e,r){return-1*r},evaluate:function(e){return r.unifiedEval(this,e)}}}});D.addGrammarElement("unaryExpression",function(e,r,t){return e.parseAnyOf(["logicalNot","positionalExpression","noExpression","negativeNumber","postfixExpression"],t)});D.addGrammarElement("positionalExpression",function(e,r,t){var n=t.matchAnyToken("first","last","random");if(n){t.matchAnyToken("in","from","of");var a=e.requireElement("unaryExpression",t);return{type:"positionalExpression",rhs:a,operator:n.value,args:[a],op:function(e,r){if(!Array.isArray(r)){if(r.children){r=r.children}else{r=Array.from(r)}}if(this.operator==="first"){return r[0]}else if(this.operator==="last"){return r[r.length-1]}else if(this.operator==="random"){return r[Math.floor(Math.random()*r.length)]}},evaluate:function(e){return r.unifiedEval(this,e)}}}});D.addGrammarElement("mathOperator",function(e,r,t){var n=e.parseElement("unaryExpression",t);var a,i=null;a=t.matchAnyOpToken("+","-","*","/","%");while(a){i=i||a;var o=a.value;if(i.value!==o){e.raiseParseError(t,"You must parenthesize math operations with different operators")}var u=e.parseElement("unaryExpression",t);n={type:"mathOperator",lhs:n,rhs:u,operator:o,args:[n,u],op:function(e,r,t){if(this.operator==="+"){return r+t}else if(this.operator==="-"){return r-t}else if(this.operator==="*"){return r*t}else if(this.operator==="/"){return r/t}else if(this.operator==="%"){return r%t}},evaluate:function(e){return r.unifiedEval(this,e)}};a=t.matchAnyOpToken("+","-","*","/","%")}return n});D.addGrammarElement("mathExpression",function(e,r,t){return e.parseAnyOf(["mathOperator","unaryExpression"],t)});D.addGrammarElement("comparisonOperator",function(e,n,r){var t=e.parseElement("mathExpression",r);var a=r.matchAnyOpToken("<",">","<=",">=","==","===","!=","!==");var i=a?a.value:null;var o=true;var u=false;if(i==null){if(r.matchToken("is")||r.matchToken("am")){if(r.matchToken("not")){if(r.matchToken("in")){i="not in"}else if(r.matchToken("a")){i="not a";u=true}else if(r.matchToken("empty")){i="not empty";o=false}else{i="!="}}else if(r.matchToken("in")){i="in"}else if(r.matchToken("a")){i="a";u=true}else if(r.matchToken("empty")){i="empty";o=false}else{i="=="}}else if(r.matchToken("matches")||r.matchToken("match")){i="match"}else if(r.matchToken("contains")||r.matchToken("contain")){i="contain"}else if(r.matchToken("do")||r.matchToken("does")){r.requireToken("not");if(r.matchToken("matches")||r.matchToken("match")){i="not match"}else if(r.matchToken("contains")||r.matchToken("contain")){i="not contain"}else{e.raiseParseError(r,"Expected matches or contains")}}}if(i){if(u){var s=r.requireTokenType("IDENTIFIER");var l=!r.matchOpToken("!")}else if(o){var c=e.requireElement("mathExpression",r);if(i==="match"||i==="not match"){c=c.css?c.css:c}}t={type:"comparisonOperator",operator:i,typeName:s,nullOk:l,lhs:t,rhs:c,args:[t,c],op:function(e,r,t){if(this.operator==="=="){return r==t}else if(this.operator==="!="){return r!=t}if(this.operator==="in"){return t!=null&&Array.from(t).indexOf(r)>=0}if(this.operator==="not in"){return t==null||Array.from(t).indexOf(r)<0}if(this.operator==="match"){return r!=null&&r.matches(t)}if(this.operator==="not match"){return r==null||!r.matches(t)}if(this.operator==="contain"){return r!=null&&r.contains(t)}if(this.operator==="not contain"){return r==null||!r.contains(t)}if(this.operator==="==="){return r===t}else if(this.operator==="!=="){return r!==t}else if(this.operator==="<"){return r"){return r>t}else if(this.operator==="<="){return r<=t}else if(this.operator===">="){return r>=t}else if(this.operator==="empty"){return n.isEmpty(r)}else if(this.operator==="not empty"){return!n.isEmpty(r)}else if(this.operator==="a"){return n.typeCheck(r,this.typeName.value,this.nullOk)}else if(this.operator==="not a"){return!n.typeCheck(r,this.typeName.value,this.nullOk)}else{throw"Unknown comparison : "+this.operator}},evaluate:function(e){return n.unifiedEval(this,e)}}}return t});D.addGrammarElement("comparisonExpression",function(e,r,t){return e.parseAnyOf(["comparisonOperator","mathExpression"],t)});D.addGrammarElement("logicalOperator",function(e,r,t){var n=e.parseElement("comparisonExpression",t);var a,i=null;a=t.matchToken("and")||t.matchToken("or");while(a){i=i||a;if(i.value!==a.value){e.raiseParseError(t,"You must parenthesize logical operations with different operators")}var o=e.requireElement("comparisonExpression",t);n={type:"logicalOperator",operator:a.value,lhs:n,rhs:o,args:[n,o],op:function(e,r,t){if(this.operator==="and"){return r&&t}else{return r||t}},evaluate:function(e){return r.unifiedEval(this,e)}};a=t.matchToken("and")||t.matchToken("or")}return n});D.addGrammarElement("logicalExpression",function(e,r,t){return e.parseAnyOf(["logicalOperator","mathExpression"],t)});D.addGrammarElement("asyncExpression",function(e,r,t){if(t.matchToken("async")){var n=e.requireElement("logicalExpression",t);var a={type:"asyncExpression",value:n,evaluate:function(e){return{asyncWrapper:true,value:this.value.evaluate(e)}}};return a}else{return e.parseElement("logicalExpression",t)}});D.addGrammarElement("expression",function(e,r,t){t.matchToken("the");return e.parseElement("asyncExpression",t)});D.addGrammarElement("targetExpression",function(e,r,t){t.matchToken("the");var n=e.parseElement("primaryExpression",t);if(n.type==="symbol"||n.type==="idRef"||n.type==="inExpression"||n.type==="queryRef"||n.type==="classRef"||n.type==="ofExpression"||n.type==="propertyAccess"||n.type==="closestExpr"||n.type==="possessive"){return n}else{D.raiseParseError(t,"A target expression must be writable")}return n});D.addGrammarElement("hyperscript",function(e,r,t){var n=[];if(t.hasMore()){do{var a=e.requireElement("feature",t);n.push(a);t.matchToken("end")}while(e.featureStart(t.currentToken())||t.currentToken().value==="(");if(t.hasMore()){e.raiseParseError(t)}}return{type:"hyperscript",features:n,apply:function(r,t){G.forEach(n,function(e){e.install(r,t)})}}});var C=function(e){var r=[];if(e.token(0).value==="("&&(e.token(1).value===")"||e.token(2).value===","||e.token(2).value===")")){e.matchOpToken("(");do{r.push(e.requireTokenType("IDENTIFIER"))}while(e.matchOpToken(","));e.requireOpToken(")")}return r};D.addFeature("on",function(e,s,r){if(r.matchToken("on")){var t=false;if(r.matchToken("every")){t=true}var n=[];var a=null;do{var i=e.requireElement("dotOrColonPath",r,"Expected event name");var o=i.evaluate();if(a){a=a+" or "+o}else{a="on "+o}var u=C(r);var l=null;if(r.matchOpToken("[")){l=e.requireElement("expression",r);r.requireOpToken("]")}if(r.currentToken().type==="NUMBER"){var c=r.consumeToken();var f=parseInt(c.value);if(r.matchToken("to")){var p=r.consumeToken();var m=parseInt(p.value)}else if(r.matchToken("and")){var v=true;r.requireToken("on")}}var h=null;var d=false;if(r.matchToken("from")){if(r.matchToken("elsewhere")){d=true}else{h=e.parseElement("targetExpression",r);if(!h){e.raiseParseError('Expected either target value or "elsewhere".',r)}}}if(h===null&&d===false&&r.matchToken("elsewhere")){d=true}if(r.matchToken("in")){var E=e.parseAnyOf(["idRef","queryRef","classRef"],r)}if(r.matchToken("debounced")){r.requireToken("at");var T=e.requireElement("timeExpression",r);var y=T.evaluate({})}else if(r.matchToken("throttled")){r.requireToken("at");var T=e.requireElement("timeExpression",r);var k=T.evaluate({})}n.push({execCount:0,every:t,on:o,args:u,filter:l,from:h,inExpr:E,elsewhere:d,startCount:f,endCount:m,unbounded:v,debounceTime:y,throttleTime:k})}while(r.matchToken("or"));var x=[];var g=true;if(!t){if(r.matchToken("queue")){if(r.matchToken("all")){var q=true;var g=false}else if(r.matchToken("first")){var b=true}else if(r.matchToken("none")){var w=true}else{r.requireToken("last")}}}var N=e.requireElement("commandList",r);var I={type:"implicitReturn",op:function(e){e.meta.resolve();return s.HALT},execute:function(e){}};if(N){var O=N;while(O.next){O=O.next}O.next=I}else{N=I}var A={displayName:a,events:n,start:N,every:t,executing:false,execCount:0,queue:x,execute:function(n){if(this.executing&&this.every===false){if(w||b&&x.length>0){return}if(g){A.queue.length=0}A.queue.push(n);return}this.execCount++;this.executing=true;n.meta.resolve=function(){A.executing=false;var e=A.queue.shift();if(e){setTimeout(function(){A.execute(e)},1)}};n.meta.reject=function(e){console.error(e.message?e.message:e);var r=s.getHyperTrace(n,e);if(r){r.print()}s.triggerEvent(n.me,"exception",{error:e});A.executing=false;var t=A.queue.shift();if(t){setTimeout(function(){A.execute(t)},1)}};N.execute(n)},install:function(u,e){s.forEach(A.events,function(o){var e;if(o.elsewhere){e=[document]}else if(o.from){e=o.from.evaluate({me:u})}else{e=[u]}s.forEach(e,function(i){i.addEventListener(o.on,function(e){var r=s.makeContext(u,A,u,e);if(o.elsewhere&&u.contains(e.target)){return}if(o.from){r.result=i}s.forEach(o.args,function(e){r[e.value]=r.event[e.value]||(r.event.detail?r.event.detail[e.value]:null)});if(o.filter){var t=r.meta.context;r.meta.context=r.event;try{var n=o.filter.evaluate(r);if(n){}else{return}}finally{r.meta.context=t}}if(o.inExpr){var a=e.target;while(true){if(a.matches&&a.matches(o.inExpr.css)){r.result=a;break}else{a=a.parentElement;if(a==null){return}}}}o.execCount++;if(o.startCount){if(o.endCount){if(o.execCounto.endCount){return}}else if(o.unbounded){if(o.execCount - * @author owenm - * @license MIT - */ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global = global || self, global.Sortable = factory()); -}(this, (function () { 'use strict'; - - function ownKeys(object, enumerableOnly) { - var keys = Object.keys(object); - if (Object.getOwnPropertySymbols) { - var symbols = Object.getOwnPropertySymbols(object); - if (enumerableOnly) { - symbols = symbols.filter(function (sym) { - return Object.getOwnPropertyDescriptor(object, sym).enumerable; - }); - } - keys.push.apply(keys, symbols); - } - return keys; - } - function _objectSpread2(target) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i] != null ? arguments[i] : {}; - if (i % 2) { - ownKeys(Object(source), true).forEach(function (key) { - _defineProperty(target, key, source[key]); - }); - } else if (Object.getOwnPropertyDescriptors) { - Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); - } else { - ownKeys(Object(source)).forEach(function (key) { - Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); - }); - } - } - return target; - } - function _typeof(obj) { - "@babel/helpers - typeof"; - - if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { - _typeof = function (obj) { - return typeof obj; - }; - } else { - _typeof = function (obj) { - return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; - }; - } - return _typeof(obj); - } - function _defineProperty(obj, key, value) { - if (key in obj) { - Object.defineProperty(obj, key, { - value: value, - enumerable: true, - configurable: true, - writable: true - }); - } else { - obj[key] = value; - } - return obj; - } - function _extends() { - _extends = Object.assign || function (target) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i]; - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; - }; - return _extends.apply(this, arguments); - } - function _objectWithoutPropertiesLoose(source, excluded) { - if (source == null) return {}; - var target = {}; - var sourceKeys = Object.keys(source); - var key, i; - for (i = 0; i < sourceKeys.length; i++) { - key = sourceKeys[i]; - if (excluded.indexOf(key) >= 0) continue; - target[key] = source[key]; - } - return target; - } - function _objectWithoutProperties(source, excluded) { - if (source == null) return {}; - var target = _objectWithoutPropertiesLoose(source, excluded); - var key, i; - if (Object.getOwnPropertySymbols) { - var sourceSymbolKeys = Object.getOwnPropertySymbols(source); - for (i = 0; i < sourceSymbolKeys.length; i++) { - key = sourceSymbolKeys[i]; - if (excluded.indexOf(key) >= 0) continue; - if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; - target[key] = source[key]; - } - } - return target; - } - function _toConsumableArray(arr) { - return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); - } - function _arrayWithoutHoles(arr) { - if (Array.isArray(arr)) return _arrayLikeToArray(arr); - } - function _iterableToArray(iter) { - if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); - } - function _unsupportedIterableToArray(o, minLen) { - if (!o) return; - if (typeof o === "string") return _arrayLikeToArray(o, minLen); - var n = Object.prototype.toString.call(o).slice(8, -1); - if (n === "Object" && o.constructor) n = o.constructor.name; - if (n === "Map" || n === "Set") return Array.from(o); - if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); - } - function _arrayLikeToArray(arr, len) { - if (len == null || len > arr.length) len = arr.length; - for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; - return arr2; - } - function _nonIterableSpread() { - throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); - } - - var version = "1.15.2"; - - function userAgent(pattern) { - if (typeof window !== 'undefined' && window.navigator) { - return !! /*@__PURE__*/navigator.userAgent.match(pattern); - } - } - var IE11OrLess = userAgent(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i); - var Edge = userAgent(/Edge/i); - var FireFox = userAgent(/firefox/i); - var Safari = userAgent(/safari/i) && !userAgent(/chrome/i) && !userAgent(/android/i); - var IOS = userAgent(/iP(ad|od|hone)/i); - var ChromeForAndroid = userAgent(/chrome/i) && userAgent(/android/i); - - var captureMode = { - capture: false, - passive: false - }; - function on(el, event, fn) { - el.addEventListener(event, fn, !IE11OrLess && captureMode); - } - function off(el, event, fn) { - el.removeEventListener(event, fn, !IE11OrLess && captureMode); - } - function matches( /**HTMLElement*/el, /**String*/selector) { - if (!selector) return; - selector[0] === '>' && (selector = selector.substring(1)); - if (el) { - try { - if (el.matches) { - return el.matches(selector); - } else if (el.msMatchesSelector) { - return el.msMatchesSelector(selector); - } else if (el.webkitMatchesSelector) { - return el.webkitMatchesSelector(selector); - } - } catch (_) { - return false; - } - } - return false; - } - function getParentOrHost(el) { - return el.host && el !== document && el.host.nodeType ? el.host : el.parentNode; - } - function closest( /**HTMLElement*/el, /**String*/selector, /**HTMLElement*/ctx, includeCTX) { - if (el) { - ctx = ctx || document; - do { - if (selector != null && (selector[0] === '>' ? el.parentNode === ctx && matches(el, selector) : matches(el, selector)) || includeCTX && el === ctx) { - return el; - } - if (el === ctx) break; - /* jshint boss:true */ - } while (el = getParentOrHost(el)); - } - return null; - } - var R_SPACE = /\s+/g; - function toggleClass(el, name, state) { - if (el && name) { - if (el.classList) { - el.classList[state ? 'add' : 'remove'](name); - } else { - var className = (' ' + el.className + ' ').replace(R_SPACE, ' ').replace(' ' + name + ' ', ' '); - el.className = (className + (state ? ' ' + name : '')).replace(R_SPACE, ' '); - } - } - } - function css(el, prop, val) { - var style = el && el.style; - if (style) { - if (val === void 0) { - if (document.defaultView && document.defaultView.getComputedStyle) { - val = document.defaultView.getComputedStyle(el, ''); - } else if (el.currentStyle) { - val = el.currentStyle; - } - return prop === void 0 ? val : val[prop]; - } else { - if (!(prop in style) && prop.indexOf('webkit') === -1) { - prop = '-webkit-' + prop; - } - style[prop] = val + (typeof val === 'string' ? '' : 'px'); - } - } - } - function matrix(el, selfOnly) { - var appliedTransforms = ''; - if (typeof el === 'string') { - appliedTransforms = el; - } else { - do { - var transform = css(el, 'transform'); - if (transform && transform !== 'none') { - appliedTransforms = transform + ' ' + appliedTransforms; - } - /* jshint boss:true */ - } while (!selfOnly && (el = el.parentNode)); - } - var matrixFn = window.DOMMatrix || window.WebKitCSSMatrix || window.CSSMatrix || window.MSCSSMatrix; - /*jshint -W056 */ - return matrixFn && new matrixFn(appliedTransforms); - } - function find(ctx, tagName, iterator) { - if (ctx) { - var list = ctx.getElementsByTagName(tagName), - i = 0, - n = list.length; - if (iterator) { - for (; i < n; i++) { - iterator(list[i], i); - } - } - return list; - } - return []; - } - function getWindowScrollingElement() { - var scrollingElement = document.scrollingElement; - if (scrollingElement) { - return scrollingElement; - } else { - return document.documentElement; - } - } - - /** - * Returns the "bounding client rect" of given element - * @param {HTMLElement} el The element whose boundingClientRect is wanted - * @param {[Boolean]} relativeToContainingBlock Whether the rect should be relative to the containing block of (including) the container - * @param {[Boolean]} relativeToNonStaticParent Whether the rect should be relative to the relative parent of (including) the contaienr - * @param {[Boolean]} undoScale Whether the container's scale() should be undone - * @param {[HTMLElement]} container The parent the element will be placed in - * @return {Object} The boundingClientRect of el, with specified adjustments - */ - function getRect(el, relativeToContainingBlock, relativeToNonStaticParent, undoScale, container) { - if (!el.getBoundingClientRect && el !== window) return; - var elRect, top, left, bottom, right, height, width; - if (el !== window && el.parentNode && el !== getWindowScrollingElement()) { - elRect = el.getBoundingClientRect(); - top = elRect.top; - left = elRect.left; - bottom = elRect.bottom; - right = elRect.right; - height = elRect.height; - width = elRect.width; - } else { - top = 0; - left = 0; - bottom = window.innerHeight; - right = window.innerWidth; - height = window.innerHeight; - width = window.innerWidth; - } - if ((relativeToContainingBlock || relativeToNonStaticParent) && el !== window) { - // Adjust for translate() - container = container || el.parentNode; - - // solves #1123 (see: https://stackoverflow.com/a/37953806/6088312) - // Not needed on <= IE11 - if (!IE11OrLess) { - do { - if (container && container.getBoundingClientRect && (css(container, 'transform') !== 'none' || relativeToNonStaticParent && css(container, 'position') !== 'static')) { - var containerRect = container.getBoundingClientRect(); - - // Set relative to edges of padding box of container - top -= containerRect.top + parseInt(css(container, 'border-top-width')); - left -= containerRect.left + parseInt(css(container, 'border-left-width')); - bottom = top + elRect.height; - right = left + elRect.width; - break; - } - /* jshint boss:true */ - } while (container = container.parentNode); - } - } - if (undoScale && el !== window) { - // Adjust for scale() - var elMatrix = matrix(container || el), - scaleX = elMatrix && elMatrix.a, - scaleY = elMatrix && elMatrix.d; - if (elMatrix) { - top /= scaleY; - left /= scaleX; - width /= scaleX; - height /= scaleY; - bottom = top + height; - right = left + width; - } - } - return { - top: top, - left: left, - bottom: bottom, - right: right, - width: width, - height: height - }; - } - - /** - * Checks if a side of an element is scrolled past a side of its parents - * @param {HTMLElement} el The element who's side being scrolled out of view is in question - * @param {String} elSide Side of the element in question ('top', 'left', 'right', 'bottom') - * @param {String} parentSide Side of the parent in question ('top', 'left', 'right', 'bottom') - * @return {HTMLElement} The parent scroll element that the el's side is scrolled past, or null if there is no such element - */ - function isScrolledPast(el, elSide, parentSide) { - var parent = getParentAutoScrollElement(el, true), - elSideVal = getRect(el)[elSide]; - - /* jshint boss:true */ - while (parent) { - var parentSideVal = getRect(parent)[parentSide], - visible = void 0; - if (parentSide === 'top' || parentSide === 'left') { - visible = elSideVal >= parentSideVal; - } else { - visible = elSideVal <= parentSideVal; - } - if (!visible) return parent; - if (parent === getWindowScrollingElement()) break; - parent = getParentAutoScrollElement(parent, false); - } - return false; - } - - /** - * Gets nth child of el, ignoring hidden children, sortable's elements (does not ignore clone if it's visible) - * and non-draggable elements - * @param {HTMLElement} el The parent element - * @param {Number} childNum The index of the child - * @param {Object} options Parent Sortable's options - * @return {HTMLElement} The child at index childNum, or null if not found - */ - function getChild(el, childNum, options, includeDragEl) { - var currentChild = 0, - i = 0, - children = el.children; - while (i < children.length) { - if (children[i].style.display !== 'none' && children[i] !== Sortable.ghost && (includeDragEl || children[i] !== Sortable.dragged) && closest(children[i], options.draggable, el, false)) { - if (currentChild === childNum) { - return children[i]; - } - currentChild++; - } - i++; - } - return null; - } - - /** - * Gets the last child in the el, ignoring ghostEl or invisible elements (clones) - * @param {HTMLElement} el Parent element - * @param {selector} selector Any other elements that should be ignored - * @return {HTMLElement} The last child, ignoring ghostEl - */ - function lastChild(el, selector) { - var last = el.lastElementChild; - while (last && (last === Sortable.ghost || css(last, 'display') === 'none' || selector && !matches(last, selector))) { - last = last.previousElementSibling; - } - return last || null; - } - - /** - * Returns the index of an element within its parent for a selected set of - * elements - * @param {HTMLElement} el - * @param {selector} selector - * @return {number} - */ - function index(el, selector) { - var index = 0; - if (!el || !el.parentNode) { - return -1; - } - - /* jshint boss:true */ - while (el = el.previousElementSibling) { - if (el.nodeName.toUpperCase() !== 'TEMPLATE' && el !== Sortable.clone && (!selector || matches(el, selector))) { - index++; - } - } - return index; - } - - /** - * Returns the scroll offset of the given element, added with all the scroll offsets of parent elements. - * The value is returned in real pixels. - * @param {HTMLElement} el - * @return {Array} Offsets in the format of [left, top] - */ - function getRelativeScrollOffset(el) { - var offsetLeft = 0, - offsetTop = 0, - winScroller = getWindowScrollingElement(); - if (el) { - do { - var elMatrix = matrix(el), - scaleX = elMatrix.a, - scaleY = elMatrix.d; - offsetLeft += el.scrollLeft * scaleX; - offsetTop += el.scrollTop * scaleY; - } while (el !== winScroller && (el = el.parentNode)); - } - return [offsetLeft, offsetTop]; - } - - /** - * Returns the index of the object within the given array - * @param {Array} arr Array that may or may not hold the object - * @param {Object} obj An object that has a key-value pair unique to and identical to a key-value pair in the object you want to find - * @return {Number} The index of the object in the array, or -1 - */ - function indexOfObject(arr, obj) { - for (var i in arr) { - if (!arr.hasOwnProperty(i)) continue; - for (var key in obj) { - if (obj.hasOwnProperty(key) && obj[key] === arr[i][key]) return Number(i); - } - } - return -1; - } - function getParentAutoScrollElement(el, includeSelf) { - // skip to window - if (!el || !el.getBoundingClientRect) return getWindowScrollingElement(); - var elem = el; - var gotSelf = false; - do { - // we don't need to get elem css if it isn't even overflowing in the first place (performance) - if (elem.clientWidth < elem.scrollWidth || elem.clientHeight < elem.scrollHeight) { - var elemCSS = css(elem); - if (elem.clientWidth < elem.scrollWidth && (elemCSS.overflowX == 'auto' || elemCSS.overflowX == 'scroll') || elem.clientHeight < elem.scrollHeight && (elemCSS.overflowY == 'auto' || elemCSS.overflowY == 'scroll')) { - if (!elem.getBoundingClientRect || elem === document.body) return getWindowScrollingElement(); - if (gotSelf || includeSelf) return elem; - gotSelf = true; - } - } - /* jshint boss:true */ - } while (elem = elem.parentNode); - return getWindowScrollingElement(); - } - function extend(dst, src) { - if (dst && src) { - for (var key in src) { - if (src.hasOwnProperty(key)) { - dst[key] = src[key]; - } - } - } - return dst; - } - function isRectEqual(rect1, rect2) { - return Math.round(rect1.top) === Math.round(rect2.top) && Math.round(rect1.left) === Math.round(rect2.left) && Math.round(rect1.height) === Math.round(rect2.height) && Math.round(rect1.width) === Math.round(rect2.width); - } - var _throttleTimeout; - function throttle(callback, ms) { - return function () { - if (!_throttleTimeout) { - var args = arguments, - _this = this; - if (args.length === 1) { - callback.call(_this, args[0]); - } else { - callback.apply(_this, args); - } - _throttleTimeout = setTimeout(function () { - _throttleTimeout = void 0; - }, ms); - } - }; - } - function cancelThrottle() { - clearTimeout(_throttleTimeout); - _throttleTimeout = void 0; - } - function scrollBy(el, x, y) { - el.scrollLeft += x; - el.scrollTop += y; - } - function clone(el) { - var Polymer = window.Polymer; - var $ = window.jQuery || window.Zepto; - if (Polymer && Polymer.dom) { - return Polymer.dom(el).cloneNode(true); - } else if ($) { - return $(el).clone(true)[0]; - } else { - return el.cloneNode(true); - } - } - function setRect(el, rect) { - css(el, 'position', 'absolute'); - css(el, 'top', rect.top); - css(el, 'left', rect.left); - css(el, 'width', rect.width); - css(el, 'height', rect.height); - } - function unsetRect(el) { - css(el, 'position', ''); - css(el, 'top', ''); - css(el, 'left', ''); - css(el, 'width', ''); - css(el, 'height', ''); - } - function getChildContainingRectFromElement(container, options, ghostEl) { - var rect = {}; - Array.from(container.children).forEach(function (child) { - var _rect$left, _rect$top, _rect$right, _rect$bottom; - if (!closest(child, options.draggable, container, false) || child.animated || child === ghostEl) return; - var childRect = getRect(child); - rect.left = Math.min((_rect$left = rect.left) !== null && _rect$left !== void 0 ? _rect$left : Infinity, childRect.left); - rect.top = Math.min((_rect$top = rect.top) !== null && _rect$top !== void 0 ? _rect$top : Infinity, childRect.top); - rect.right = Math.max((_rect$right = rect.right) !== null && _rect$right !== void 0 ? _rect$right : -Infinity, childRect.right); - rect.bottom = Math.max((_rect$bottom = rect.bottom) !== null && _rect$bottom !== void 0 ? _rect$bottom : -Infinity, childRect.bottom); - }); - rect.width = rect.right - rect.left; - rect.height = rect.bottom - rect.top; - rect.x = rect.left; - rect.y = rect.top; - return rect; - } - var expando = 'Sortable' + new Date().getTime(); - - function AnimationStateManager() { - var animationStates = [], - animationCallbackId; - return { - captureAnimationState: function captureAnimationState() { - animationStates = []; - if (!this.options.animation) return; - var children = [].slice.call(this.el.children); - children.forEach(function (child) { - if (css(child, 'display') === 'none' || child === Sortable.ghost) return; - animationStates.push({ - target: child, - rect: getRect(child) - }); - var fromRect = _objectSpread2({}, animationStates[animationStates.length - 1].rect); - - // If animating: compensate for current animation - if (child.thisAnimationDuration) { - var childMatrix = matrix(child, true); - if (childMatrix) { - fromRect.top -= childMatrix.f; - fromRect.left -= childMatrix.e; - } - } - child.fromRect = fromRect; - }); - }, - addAnimationState: function addAnimationState(state) { - animationStates.push(state); - }, - removeAnimationState: function removeAnimationState(target) { - animationStates.splice(indexOfObject(animationStates, { - target: target - }), 1); - }, - animateAll: function animateAll(callback) { - var _this = this; - if (!this.options.animation) { - clearTimeout(animationCallbackId); - if (typeof callback === 'function') callback(); - return; - } - var animating = false, - animationTime = 0; - animationStates.forEach(function (state) { - var time = 0, - target = state.target, - fromRect = target.fromRect, - toRect = getRect(target), - prevFromRect = target.prevFromRect, - prevToRect = target.prevToRect, - animatingRect = state.rect, - targetMatrix = matrix(target, true); - if (targetMatrix) { - // Compensate for current animation - toRect.top -= targetMatrix.f; - toRect.left -= targetMatrix.e; - } - target.toRect = toRect; - if (target.thisAnimationDuration) { - // Could also check if animatingRect is between fromRect and toRect - if (isRectEqual(prevFromRect, toRect) && !isRectEqual(fromRect, toRect) && - // Make sure animatingRect is on line between toRect & fromRect - (animatingRect.top - toRect.top) / (animatingRect.left - toRect.left) === (fromRect.top - toRect.top) / (fromRect.left - toRect.left)) { - // If returning to same place as started from animation and on same axis - time = calculateRealTime(animatingRect, prevFromRect, prevToRect, _this.options); - } - } - - // if fromRect != toRect: animate - if (!isRectEqual(toRect, fromRect)) { - target.prevFromRect = fromRect; - target.prevToRect = toRect; - if (!time) { - time = _this.options.animation; - } - _this.animate(target, animatingRect, toRect, time); - } - if (time) { - animating = true; - animationTime = Math.max(animationTime, time); - clearTimeout(target.animationResetTimer); - target.animationResetTimer = setTimeout(function () { - target.animationTime = 0; - target.prevFromRect = null; - target.fromRect = null; - target.prevToRect = null; - target.thisAnimationDuration = null; - }, time); - target.thisAnimationDuration = time; - } - }); - clearTimeout(animationCallbackId); - if (!animating) { - if (typeof callback === 'function') callback(); - } else { - animationCallbackId = setTimeout(function () { - if (typeof callback === 'function') callback(); - }, animationTime); - } - animationStates = []; - }, - animate: function animate(target, currentRect, toRect, duration) { - if (duration) { - css(target, 'transition', ''); - css(target, 'transform', ''); - var elMatrix = matrix(this.el), - scaleX = elMatrix && elMatrix.a, - scaleY = elMatrix && elMatrix.d, - translateX = (currentRect.left - toRect.left) / (scaleX || 1), - translateY = (currentRect.top - toRect.top) / (scaleY || 1); - target.animatingX = !!translateX; - target.animatingY = !!translateY; - css(target, 'transform', 'translate3d(' + translateX + 'px,' + translateY + 'px,0)'); - this.forRepaintDummy = repaint(target); // repaint - - css(target, 'transition', 'transform ' + duration + 'ms' + (this.options.easing ? ' ' + this.options.easing : '')); - css(target, 'transform', 'translate3d(0,0,0)'); - typeof target.animated === 'number' && clearTimeout(target.animated); - target.animated = setTimeout(function () { - css(target, 'transition', ''); - css(target, 'transform', ''); - target.animated = false; - target.animatingX = false; - target.animatingY = false; - }, duration); - } - } - }; - } - function repaint(target) { - return target.offsetWidth; - } - function calculateRealTime(animatingRect, fromRect, toRect, options) { - return Math.sqrt(Math.pow(fromRect.top - animatingRect.top, 2) + Math.pow(fromRect.left - animatingRect.left, 2)) / Math.sqrt(Math.pow(fromRect.top - toRect.top, 2) + Math.pow(fromRect.left - toRect.left, 2)) * options.animation; - } - - var plugins = []; - var defaults = { - initializeByDefault: true - }; - var PluginManager = { - mount: function mount(plugin) { - // Set default static properties - for (var option in defaults) { - if (defaults.hasOwnProperty(option) && !(option in plugin)) { - plugin[option] = defaults[option]; - } - } - plugins.forEach(function (p) { - if (p.pluginName === plugin.pluginName) { - throw "Sortable: Cannot mount plugin ".concat(plugin.pluginName, " more than once"); - } - }); - plugins.push(plugin); - }, - pluginEvent: function pluginEvent(eventName, sortable, evt) { - var _this = this; - this.eventCanceled = false; - evt.cancel = function () { - _this.eventCanceled = true; - }; - var eventNameGlobal = eventName + 'Global'; - plugins.forEach(function (plugin) { - if (!sortable[plugin.pluginName]) return; - // Fire global events if it exists in this sortable - if (sortable[plugin.pluginName][eventNameGlobal]) { - sortable[plugin.pluginName][eventNameGlobal](_objectSpread2({ - sortable: sortable - }, evt)); - } - - // Only fire plugin event if plugin is enabled in this sortable, - // and plugin has event defined - if (sortable.options[plugin.pluginName] && sortable[plugin.pluginName][eventName]) { - sortable[plugin.pluginName][eventName](_objectSpread2({ - sortable: sortable - }, evt)); - } - }); - }, - initializePlugins: function initializePlugins(sortable, el, defaults, options) { - plugins.forEach(function (plugin) { - var pluginName = plugin.pluginName; - if (!sortable.options[pluginName] && !plugin.initializeByDefault) return; - var initialized = new plugin(sortable, el, sortable.options); - initialized.sortable = sortable; - initialized.options = sortable.options; - sortable[pluginName] = initialized; - - // Add default options from plugin - _extends(defaults, initialized.defaults); - }); - for (var option in sortable.options) { - if (!sortable.options.hasOwnProperty(option)) continue; - var modified = this.modifyOption(sortable, option, sortable.options[option]); - if (typeof modified !== 'undefined') { - sortable.options[option] = modified; - } - } - }, - getEventProperties: function getEventProperties(name, sortable) { - var eventProperties = {}; - plugins.forEach(function (plugin) { - if (typeof plugin.eventProperties !== 'function') return; - _extends(eventProperties, plugin.eventProperties.call(sortable[plugin.pluginName], name)); - }); - return eventProperties; - }, - modifyOption: function modifyOption(sortable, name, value) { - var modifiedValue; - plugins.forEach(function (plugin) { - // Plugin must exist on the Sortable - if (!sortable[plugin.pluginName]) return; - - // If static option listener exists for this option, call in the context of the Sortable's instance of this plugin - if (plugin.optionListeners && typeof plugin.optionListeners[name] === 'function') { - modifiedValue = plugin.optionListeners[name].call(sortable[plugin.pluginName], value); - } - }); - return modifiedValue; - } - }; - - function dispatchEvent(_ref) { - var sortable = _ref.sortable, - rootEl = _ref.rootEl, - name = _ref.name, - targetEl = _ref.targetEl, - cloneEl = _ref.cloneEl, - toEl = _ref.toEl, - fromEl = _ref.fromEl, - oldIndex = _ref.oldIndex, - newIndex = _ref.newIndex, - oldDraggableIndex = _ref.oldDraggableIndex, - newDraggableIndex = _ref.newDraggableIndex, - originalEvent = _ref.originalEvent, - putSortable = _ref.putSortable, - extraEventProperties = _ref.extraEventProperties; - sortable = sortable || rootEl && rootEl[expando]; - if (!sortable) return; - var evt, - options = sortable.options, - onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1); - // Support for new CustomEvent feature - if (window.CustomEvent && !IE11OrLess && !Edge) { - evt = new CustomEvent(name, { - bubbles: true, - cancelable: true - }); - } else { - evt = document.createEvent('Event'); - evt.initEvent(name, true, true); - } - evt.to = toEl || rootEl; - evt.from = fromEl || rootEl; - evt.item = targetEl || rootEl; - evt.clone = cloneEl; - evt.oldIndex = oldIndex; - evt.newIndex = newIndex; - evt.oldDraggableIndex = oldDraggableIndex; - evt.newDraggableIndex = newDraggableIndex; - evt.originalEvent = originalEvent; - evt.pullMode = putSortable ? putSortable.lastPutMode : undefined; - var allEventProperties = _objectSpread2(_objectSpread2({}, extraEventProperties), PluginManager.getEventProperties(name, sortable)); - for (var option in allEventProperties) { - evt[option] = allEventProperties[option]; - } - if (rootEl) { - rootEl.dispatchEvent(evt); - } - if (options[onName]) { - options[onName].call(sortable, evt); - } - } - - var _excluded = ["evt"]; - var pluginEvent = function pluginEvent(eventName, sortable) { - var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}, - originalEvent = _ref.evt, - data = _objectWithoutProperties(_ref, _excluded); - PluginManager.pluginEvent.bind(Sortable)(eventName, sortable, _objectSpread2({ - dragEl: dragEl, - parentEl: parentEl, - ghostEl: ghostEl, - rootEl: rootEl, - nextEl: nextEl, - lastDownEl: lastDownEl, - cloneEl: cloneEl, - cloneHidden: cloneHidden, - dragStarted: moved, - putSortable: putSortable, - activeSortable: Sortable.active, - originalEvent: originalEvent, - oldIndex: oldIndex, - oldDraggableIndex: oldDraggableIndex, - newIndex: newIndex, - newDraggableIndex: newDraggableIndex, - hideGhostForTarget: _hideGhostForTarget, - unhideGhostForTarget: _unhideGhostForTarget, - cloneNowHidden: function cloneNowHidden() { - cloneHidden = true; - }, - cloneNowShown: function cloneNowShown() { - cloneHidden = false; - }, - dispatchSortableEvent: function dispatchSortableEvent(name) { - _dispatchEvent({ - sortable: sortable, - name: name, - originalEvent: originalEvent - }); - } - }, data)); - }; - function _dispatchEvent(info) { - dispatchEvent(_objectSpread2({ - putSortable: putSortable, - cloneEl: cloneEl, - targetEl: dragEl, - rootEl: rootEl, - oldIndex: oldIndex, - oldDraggableIndex: oldDraggableIndex, - newIndex: newIndex, - newDraggableIndex: newDraggableIndex - }, info)); - } - var dragEl, - parentEl, - ghostEl, - rootEl, - nextEl, - lastDownEl, - cloneEl, - cloneHidden, - oldIndex, - newIndex, - oldDraggableIndex, - newDraggableIndex, - activeGroup, - putSortable, - awaitingDragStarted = false, - ignoreNextClick = false, - sortables = [], - tapEvt, - touchEvt, - lastDx, - lastDy, - tapDistanceLeft, - tapDistanceTop, - moved, - lastTarget, - lastDirection, - pastFirstInvertThresh = false, - isCircumstantialInvert = false, - targetMoveDistance, - // For positioning ghost absolutely - ghostRelativeParent, - ghostRelativeParentInitialScroll = [], - // (left, top) - - _silent = false, - savedInputChecked = []; - - /** @const */ - var documentExists = typeof document !== 'undefined', - PositionGhostAbsolutely = IOS, - CSSFloatProperty = Edge || IE11OrLess ? 'cssFloat' : 'float', - // This will not pass for IE9, because IE9 DnD only works on anchors - supportDraggable = documentExists && !ChromeForAndroid && !IOS && 'draggable' in document.createElement('div'), - supportCssPointerEvents = function () { - if (!documentExists) return; - // false when <= IE11 - if (IE11OrLess) { - return false; - } - var el = document.createElement('x'); - el.style.cssText = 'pointer-events:auto'; - return el.style.pointerEvents === 'auto'; - }(), - _detectDirection = function _detectDirection(el, options) { - var elCSS = css(el), - elWidth = parseInt(elCSS.width) - parseInt(elCSS.paddingLeft) - parseInt(elCSS.paddingRight) - parseInt(elCSS.borderLeftWidth) - parseInt(elCSS.borderRightWidth), - child1 = getChild(el, 0, options), - child2 = getChild(el, 1, options), - firstChildCSS = child1 && css(child1), - secondChildCSS = child2 && css(child2), - firstChildWidth = firstChildCSS && parseInt(firstChildCSS.marginLeft) + parseInt(firstChildCSS.marginRight) + getRect(child1).width, - secondChildWidth = secondChildCSS && parseInt(secondChildCSS.marginLeft) + parseInt(secondChildCSS.marginRight) + getRect(child2).width; - if (elCSS.display === 'flex') { - return elCSS.flexDirection === 'column' || elCSS.flexDirection === 'column-reverse' ? 'vertical' : 'horizontal'; - } - if (elCSS.display === 'grid') { - return elCSS.gridTemplateColumns.split(' ').length <= 1 ? 'vertical' : 'horizontal'; - } - if (child1 && firstChildCSS["float"] && firstChildCSS["float"] !== 'none') { - var touchingSideChild2 = firstChildCSS["float"] === 'left' ? 'left' : 'right'; - return child2 && (secondChildCSS.clear === 'both' || secondChildCSS.clear === touchingSideChild2) ? 'vertical' : 'horizontal'; - } - return child1 && (firstChildCSS.display === 'block' || firstChildCSS.display === 'flex' || firstChildCSS.display === 'table' || firstChildCSS.display === 'grid' || firstChildWidth >= elWidth && elCSS[CSSFloatProperty] === 'none' || child2 && elCSS[CSSFloatProperty] === 'none' && firstChildWidth + secondChildWidth > elWidth) ? 'vertical' : 'horizontal'; - }, - _dragElInRowColumn = function _dragElInRowColumn(dragRect, targetRect, vertical) { - var dragElS1Opp = vertical ? dragRect.left : dragRect.top, - dragElS2Opp = vertical ? dragRect.right : dragRect.bottom, - dragElOppLength = vertical ? dragRect.width : dragRect.height, - targetS1Opp = vertical ? targetRect.left : targetRect.top, - targetS2Opp = vertical ? targetRect.right : targetRect.bottom, - targetOppLength = vertical ? targetRect.width : targetRect.height; - return dragElS1Opp === targetS1Opp || dragElS2Opp === targetS2Opp || dragElS1Opp + dragElOppLength / 2 === targetS1Opp + targetOppLength / 2; - }, - /** - * Detects first nearest empty sortable to X and Y position using emptyInsertThreshold. - * @param {Number} x X position - * @param {Number} y Y position - * @return {HTMLElement} Element of the first found nearest Sortable - */ - _detectNearestEmptySortable = function _detectNearestEmptySortable(x, y) { - var ret; - sortables.some(function (sortable) { - var threshold = sortable[expando].options.emptyInsertThreshold; - if (!threshold || lastChild(sortable)) return; - var rect = getRect(sortable), - insideHorizontally = x >= rect.left - threshold && x <= rect.right + threshold, - insideVertically = y >= rect.top - threshold && y <= rect.bottom + threshold; - if (insideHorizontally && insideVertically) { - return ret = sortable; - } - }); - return ret; - }, - _prepareGroup = function _prepareGroup(options) { - function toFn(value, pull) { - return function (to, from, dragEl, evt) { - var sameGroup = to.options.group.name && from.options.group.name && to.options.group.name === from.options.group.name; - if (value == null && (pull || sameGroup)) { - // Default pull value - // Default pull and put value if same group - return true; - } else if (value == null || value === false) { - return false; - } else if (pull && value === 'clone') { - return value; - } else if (typeof value === 'function') { - return toFn(value(to, from, dragEl, evt), pull)(to, from, dragEl, evt); - } else { - var otherGroup = (pull ? to : from).options.group.name; - return value === true || typeof value === 'string' && value === otherGroup || value.join && value.indexOf(otherGroup) > -1; - } - }; - } - var group = {}; - var originalGroup = options.group; - if (!originalGroup || _typeof(originalGroup) != 'object') { - originalGroup = { - name: originalGroup - }; - } - group.name = originalGroup.name; - group.checkPull = toFn(originalGroup.pull, true); - group.checkPut = toFn(originalGroup.put); - group.revertClone = originalGroup.revertClone; - options.group = group; - }, - _hideGhostForTarget = function _hideGhostForTarget() { - if (!supportCssPointerEvents && ghostEl) { - css(ghostEl, 'display', 'none'); - } - }, - _unhideGhostForTarget = function _unhideGhostForTarget() { - if (!supportCssPointerEvents && ghostEl) { - css(ghostEl, 'display', ''); - } - }; - - // #1184 fix - Prevent click event on fallback if dragged but item not changed position - if (documentExists && !ChromeForAndroid) { - document.addEventListener('click', function (evt) { - if (ignoreNextClick) { - evt.preventDefault(); - evt.stopPropagation && evt.stopPropagation(); - evt.stopImmediatePropagation && evt.stopImmediatePropagation(); - ignoreNextClick = false; - return false; - } - }, true); - } - var nearestEmptyInsertDetectEvent = function nearestEmptyInsertDetectEvent(evt) { - if (dragEl) { - evt = evt.touches ? evt.touches[0] : evt; - var nearest = _detectNearestEmptySortable(evt.clientX, evt.clientY); - if (nearest) { - // Create imitation event - var event = {}; - for (var i in evt) { - if (evt.hasOwnProperty(i)) { - event[i] = evt[i]; - } - } - event.target = event.rootEl = nearest; - event.preventDefault = void 0; - event.stopPropagation = void 0; - nearest[expando]._onDragOver(event); - } - } - }; - var _checkOutsideTargetEl = function _checkOutsideTargetEl(evt) { - if (dragEl) { - dragEl.parentNode[expando]._isOutsideThisEl(evt.target); - } - }; - - /** - * @class Sortable - * @param {HTMLElement} el - * @param {Object} [options] - */ - function Sortable(el, options) { - if (!(el && el.nodeType && el.nodeType === 1)) { - throw "Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(el)); - } - this.el = el; // root element - this.options = options = _extends({}, options); - - // Export instance - el[expando] = this; - var defaults = { - group: null, - sort: true, - disabled: false, - store: null, - handle: null, - draggable: /^[uo]l$/i.test(el.nodeName) ? '>li' : '>*', - swapThreshold: 1, - // percentage; 0 <= x <= 1 - invertSwap: false, - // invert always - invertedSwapThreshold: null, - // will be set to same as swapThreshold if default - removeCloneOnHide: true, - direction: function direction() { - return _detectDirection(el, this.options); - }, - ghostClass: 'sortable-ghost', - chosenClass: 'sortable-chosen', - dragClass: 'sortable-drag', - ignore: 'a, img', - filter: null, - preventOnFilter: true, - animation: 0, - easing: null, - setData: function setData(dataTransfer, dragEl) { - dataTransfer.setData('Text', dragEl.textContent); - }, - dropBubble: false, - dragoverBubble: false, - dataIdAttr: 'data-id', - delay: 0, - delayOnTouchOnly: false, - touchStartThreshold: (Number.parseInt ? Number : window).parseInt(window.devicePixelRatio, 10) || 1, - forceFallback: false, - fallbackClass: 'sortable-fallback', - fallbackOnBody: false, - fallbackTolerance: 0, - fallbackOffset: { - x: 0, - y: 0 - }, - supportPointer: Sortable.supportPointer !== false && 'PointerEvent' in window && !Safari, - emptyInsertThreshold: 5 - }; - PluginManager.initializePlugins(this, el, defaults); - - // Set default options - for (var name in defaults) { - !(name in options) && (options[name] = defaults[name]); - } - _prepareGroup(options); - - // Bind all private methods - for (var fn in this) { - if (fn.charAt(0) === '_' && typeof this[fn] === 'function') { - this[fn] = this[fn].bind(this); - } - } - - // Setup drag mode - this.nativeDraggable = options.forceFallback ? false : supportDraggable; - if (this.nativeDraggable) { - // Touch start threshold cannot be greater than the native dragstart threshold - this.options.touchStartThreshold = 1; - } - - // Bind events - if (options.supportPointer) { - on(el, 'pointerdown', this._onTapStart); - } else { - on(el, 'mousedown', this._onTapStart); - on(el, 'touchstart', this._onTapStart); - } - if (this.nativeDraggable) { - on(el, 'dragover', this); - on(el, 'dragenter', this); - } - sortables.push(this.el); - - // Restore sorting - options.store && options.store.get && this.sort(options.store.get(this) || []); - - // Add animation state manager - _extends(this, AnimationStateManager()); - } - Sortable.prototype = /** @lends Sortable.prototype */{ - constructor: Sortable, - _isOutsideThisEl: function _isOutsideThisEl(target) { - if (!this.el.contains(target) && target !== this.el) { - lastTarget = null; - } - }, - _getDirection: function _getDirection(evt, target) { - return typeof this.options.direction === 'function' ? this.options.direction.call(this, evt, target, dragEl) : this.options.direction; - }, - _onTapStart: function _onTapStart( /** Event|TouchEvent */evt) { - if (!evt.cancelable) return; - var _this = this, - el = this.el, - options = this.options, - preventOnFilter = options.preventOnFilter, - type = evt.type, - touch = evt.touches && evt.touches[0] || evt.pointerType && evt.pointerType === 'touch' && evt, - target = (touch || evt).target, - originalTarget = evt.target.shadowRoot && (evt.path && evt.path[0] || evt.composedPath && evt.composedPath()[0]) || target, - filter = options.filter; - _saveInputCheckedState(el); - - // Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group. - if (dragEl) { - return; - } - if (/mousedown|pointerdown/.test(type) && evt.button !== 0 || options.disabled) { - return; // only left button and enabled - } - - // cancel dnd if original target is content editable - if (originalTarget.isContentEditable) { - return; - } - - // Safari ignores further event handling after mousedown - if (!this.nativeDraggable && Safari && target && target.tagName.toUpperCase() === 'SELECT') { - return; - } - target = closest(target, options.draggable, el, false); - if (target && target.animated) { - return; - } - if (lastDownEl === target) { - // Ignoring duplicate `down` - return; - } - - // Get the index of the dragged element within its parent - oldIndex = index(target); - oldDraggableIndex = index(target, options.draggable); - - // Check filter - if (typeof filter === 'function') { - if (filter.call(this, evt, target, this)) { - _dispatchEvent({ - sortable: _this, - rootEl: originalTarget, - name: 'filter', - targetEl: target, - toEl: el, - fromEl: el - }); - pluginEvent('filter', _this, { - evt: evt - }); - preventOnFilter && evt.cancelable && evt.preventDefault(); - return; // cancel dnd - } - } else if (filter) { - filter = filter.split(',').some(function (criteria) { - criteria = closest(originalTarget, criteria.trim(), el, false); - if (criteria) { - _dispatchEvent({ - sortable: _this, - rootEl: criteria, - name: 'filter', - targetEl: target, - fromEl: el, - toEl: el - }); - pluginEvent('filter', _this, { - evt: evt - }); - return true; - } - }); - if (filter) { - preventOnFilter && evt.cancelable && evt.preventDefault(); - return; // cancel dnd - } - } - if (options.handle && !closest(originalTarget, options.handle, el, false)) { - return; - } - - // Prepare `dragstart` - this._prepareDragStart(evt, touch, target); - }, - _prepareDragStart: function _prepareDragStart( /** Event */evt, /** Touch */touch, /** HTMLElement */target) { - var _this = this, - el = _this.el, - options = _this.options, - ownerDocument = el.ownerDocument, - dragStartFn; - if (target && !dragEl && target.parentNode === el) { - var dragRect = getRect(target); - rootEl = el; - dragEl = target; - parentEl = dragEl.parentNode; - nextEl = dragEl.nextSibling; - lastDownEl = target; - activeGroup = options.group; - Sortable.dragged = dragEl; - tapEvt = { - target: dragEl, - clientX: (touch || evt).clientX, - clientY: (touch || evt).clientY - }; - tapDistanceLeft = tapEvt.clientX - dragRect.left; - tapDistanceTop = tapEvt.clientY - dragRect.top; - this._lastX = (touch || evt).clientX; - this._lastY = (touch || evt).clientY; - dragEl.style['will-change'] = 'all'; - dragStartFn = function dragStartFn() { - pluginEvent('delayEnded', _this, { - evt: evt - }); - if (Sortable.eventCanceled) { - _this._onDrop(); - return; - } - // Delayed drag has been triggered - // we can re-enable the events: touchmove/mousemove - _this._disableDelayedDragEvents(); - if (!FireFox && _this.nativeDraggable) { - dragEl.draggable = true; - } - - // Bind the events: dragstart/dragend - _this._triggerDragStart(evt, touch); - - // Drag start event - _dispatchEvent({ - sortable: _this, - name: 'choose', - originalEvent: evt - }); - - // Chosen item - toggleClass(dragEl, options.chosenClass, true); - }; - - // Disable "draggable" - options.ignore.split(',').forEach(function (criteria) { - find(dragEl, criteria.trim(), _disableDraggable); - }); - on(ownerDocument, 'dragover', nearestEmptyInsertDetectEvent); - on(ownerDocument, 'mousemove', nearestEmptyInsertDetectEvent); - on(ownerDocument, 'touchmove', nearestEmptyInsertDetectEvent); - on(ownerDocument, 'mouseup', _this._onDrop); - on(ownerDocument, 'touchend', _this._onDrop); - on(ownerDocument, 'touchcancel', _this._onDrop); - - // Make dragEl draggable (must be before delay for FireFox) - if (FireFox && this.nativeDraggable) { - this.options.touchStartThreshold = 4; - dragEl.draggable = true; - } - pluginEvent('delayStart', this, { - evt: evt - }); - - // Delay is impossible for native DnD in Edge or IE - if (options.delay && (!options.delayOnTouchOnly || touch) && (!this.nativeDraggable || !(Edge || IE11OrLess))) { - if (Sortable.eventCanceled) { - this._onDrop(); - return; - } - // If the user moves the pointer or let go the click or touch - // before the delay has been reached: - // disable the delayed drag - on(ownerDocument, 'mouseup', _this._disableDelayedDrag); - on(ownerDocument, 'touchend', _this._disableDelayedDrag); - on(ownerDocument, 'touchcancel', _this._disableDelayedDrag); - on(ownerDocument, 'mousemove', _this._delayedDragTouchMoveHandler); - on(ownerDocument, 'touchmove', _this._delayedDragTouchMoveHandler); - options.supportPointer && on(ownerDocument, 'pointermove', _this._delayedDragTouchMoveHandler); - _this._dragStartTimer = setTimeout(dragStartFn, options.delay); - } else { - dragStartFn(); - } - } - }, - _delayedDragTouchMoveHandler: function _delayedDragTouchMoveHandler( /** TouchEvent|PointerEvent **/e) { - var touch = e.touches ? e.touches[0] : e; - if (Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) >= Math.floor(this.options.touchStartThreshold / (this.nativeDraggable && window.devicePixelRatio || 1))) { - this._disableDelayedDrag(); - } - }, - _disableDelayedDrag: function _disableDelayedDrag() { - dragEl && _disableDraggable(dragEl); - clearTimeout(this._dragStartTimer); - this._disableDelayedDragEvents(); - }, - _disableDelayedDragEvents: function _disableDelayedDragEvents() { - var ownerDocument = this.el.ownerDocument; - off(ownerDocument, 'mouseup', this._disableDelayedDrag); - off(ownerDocument, 'touchend', this._disableDelayedDrag); - off(ownerDocument, 'touchcancel', this._disableDelayedDrag); - off(ownerDocument, 'mousemove', this._delayedDragTouchMoveHandler); - off(ownerDocument, 'touchmove', this._delayedDragTouchMoveHandler); - off(ownerDocument, 'pointermove', this._delayedDragTouchMoveHandler); - }, - _triggerDragStart: function _triggerDragStart( /** Event */evt, /** Touch */touch) { - touch = touch || evt.pointerType == 'touch' && evt; - if (!this.nativeDraggable || touch) { - if (this.options.supportPointer) { - on(document, 'pointermove', this._onTouchMove); - } else if (touch) { - on(document, 'touchmove', this._onTouchMove); - } else { - on(document, 'mousemove', this._onTouchMove); - } - } else { - on(dragEl, 'dragend', this); - on(rootEl, 'dragstart', this._onDragStart); - } - try { - if (document.selection) { - // Timeout neccessary for IE9 - _nextTick(function () { - document.selection.empty(); - }); - } else { - window.getSelection().removeAllRanges(); - } - } catch (err) {} - }, - _dragStarted: function _dragStarted(fallback, evt) { - awaitingDragStarted = false; - if (rootEl && dragEl) { - pluginEvent('dragStarted', this, { - evt: evt - }); - if (this.nativeDraggable) { - on(document, 'dragover', _checkOutsideTargetEl); - } - var options = this.options; - - // Apply effect - !fallback && toggleClass(dragEl, options.dragClass, false); - toggleClass(dragEl, options.ghostClass, true); - Sortable.active = this; - fallback && this._appendGhost(); - - // Drag start event - _dispatchEvent({ - sortable: this, - name: 'start', - originalEvent: evt - }); - } else { - this._nulling(); - } - }, - _emulateDragOver: function _emulateDragOver() { - if (touchEvt) { - this._lastX = touchEvt.clientX; - this._lastY = touchEvt.clientY; - _hideGhostForTarget(); - var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY); - var parent = target; - while (target && target.shadowRoot) { - target = target.shadowRoot.elementFromPoint(touchEvt.clientX, touchEvt.clientY); - if (target === parent) break; - parent = target; - } - dragEl.parentNode[expando]._isOutsideThisEl(target); - if (parent) { - do { - if (parent[expando]) { - var inserted = void 0; - inserted = parent[expando]._onDragOver({ - clientX: touchEvt.clientX, - clientY: touchEvt.clientY, - target: target, - rootEl: parent - }); - if (inserted && !this.options.dragoverBubble) { - break; - } - } - target = parent; // store last element - } - /* jshint boss:true */ while (parent = parent.parentNode); - } - _unhideGhostForTarget(); - } - }, - _onTouchMove: function _onTouchMove( /**TouchEvent*/evt) { - if (tapEvt) { - var options = this.options, - fallbackTolerance = options.fallbackTolerance, - fallbackOffset = options.fallbackOffset, - touch = evt.touches ? evt.touches[0] : evt, - ghostMatrix = ghostEl && matrix(ghostEl, true), - scaleX = ghostEl && ghostMatrix && ghostMatrix.a, - scaleY = ghostEl && ghostMatrix && ghostMatrix.d, - relativeScrollOffset = PositionGhostAbsolutely && ghostRelativeParent && getRelativeScrollOffset(ghostRelativeParent), - dx = (touch.clientX - tapEvt.clientX + fallbackOffset.x) / (scaleX || 1) + (relativeScrollOffset ? relativeScrollOffset[0] - ghostRelativeParentInitialScroll[0] : 0) / (scaleX || 1), - dy = (touch.clientY - tapEvt.clientY + fallbackOffset.y) / (scaleY || 1) + (relativeScrollOffset ? relativeScrollOffset[1] - ghostRelativeParentInitialScroll[1] : 0) / (scaleY || 1); - - // only set the status to dragging, when we are actually dragging - if (!Sortable.active && !awaitingDragStarted) { - if (fallbackTolerance && Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) < fallbackTolerance) { - return; - } - this._onDragStart(evt, true); - } - if (ghostEl) { - if (ghostMatrix) { - ghostMatrix.e += dx - (lastDx || 0); - ghostMatrix.f += dy - (lastDy || 0); - } else { - ghostMatrix = { - a: 1, - b: 0, - c: 0, - d: 1, - e: dx, - f: dy - }; - } - var cssMatrix = "matrix(".concat(ghostMatrix.a, ",").concat(ghostMatrix.b, ",").concat(ghostMatrix.c, ",").concat(ghostMatrix.d, ",").concat(ghostMatrix.e, ",").concat(ghostMatrix.f, ")"); - css(ghostEl, 'webkitTransform', cssMatrix); - css(ghostEl, 'mozTransform', cssMatrix); - css(ghostEl, 'msTransform', cssMatrix); - css(ghostEl, 'transform', cssMatrix); - lastDx = dx; - lastDy = dy; - touchEvt = touch; - } - evt.cancelable && evt.preventDefault(); - } - }, - _appendGhost: function _appendGhost() { - // Bug if using scale(): https://stackoverflow.com/questions/2637058 - // Not being adjusted for - if (!ghostEl) { - var container = this.options.fallbackOnBody ? document.body : rootEl, - rect = getRect(dragEl, true, PositionGhostAbsolutely, true, container), - options = this.options; - - // Position absolutely - if (PositionGhostAbsolutely) { - // Get relatively positioned parent - ghostRelativeParent = container; - while (css(ghostRelativeParent, 'position') === 'static' && css(ghostRelativeParent, 'transform') === 'none' && ghostRelativeParent !== document) { - ghostRelativeParent = ghostRelativeParent.parentNode; - } - if (ghostRelativeParent !== document.body && ghostRelativeParent !== document.documentElement) { - if (ghostRelativeParent === document) ghostRelativeParent = getWindowScrollingElement(); - rect.top += ghostRelativeParent.scrollTop; - rect.left += ghostRelativeParent.scrollLeft; - } else { - ghostRelativeParent = getWindowScrollingElement(); - } - ghostRelativeParentInitialScroll = getRelativeScrollOffset(ghostRelativeParent); - } - ghostEl = dragEl.cloneNode(true); - toggleClass(ghostEl, options.ghostClass, false); - toggleClass(ghostEl, options.fallbackClass, true); - toggleClass(ghostEl, options.dragClass, true); - css(ghostEl, 'transition', ''); - css(ghostEl, 'transform', ''); - css(ghostEl, 'box-sizing', 'border-box'); - css(ghostEl, 'margin', 0); - css(ghostEl, 'top', rect.top); - css(ghostEl, 'left', rect.left); - css(ghostEl, 'width', rect.width); - css(ghostEl, 'height', rect.height); - css(ghostEl, 'opacity', '0.8'); - css(ghostEl, 'position', PositionGhostAbsolutely ? 'absolute' : 'fixed'); - css(ghostEl, 'zIndex', '100000'); - css(ghostEl, 'pointerEvents', 'none'); - Sortable.ghost = ghostEl; - container.appendChild(ghostEl); - - // Set transform-origin - css(ghostEl, 'transform-origin', tapDistanceLeft / parseInt(ghostEl.style.width) * 100 + '% ' + tapDistanceTop / parseInt(ghostEl.style.height) * 100 + '%'); - } - }, - _onDragStart: function _onDragStart( /**Event*/evt, /**boolean*/fallback) { - var _this = this; - var dataTransfer = evt.dataTransfer; - var options = _this.options; - pluginEvent('dragStart', this, { - evt: evt - }); - if (Sortable.eventCanceled) { - this._onDrop(); - return; - } - pluginEvent('setupClone', this); - if (!Sortable.eventCanceled) { - cloneEl = clone(dragEl); - cloneEl.removeAttribute("id"); - cloneEl.draggable = false; - cloneEl.style['will-change'] = ''; - this._hideClone(); - toggleClass(cloneEl, this.options.chosenClass, false); - Sortable.clone = cloneEl; - } - - // #1143: IFrame support workaround - _this.cloneId = _nextTick(function () { - pluginEvent('clone', _this); - if (Sortable.eventCanceled) return; - if (!_this.options.removeCloneOnHide) { - rootEl.insertBefore(cloneEl, dragEl); - } - _this._hideClone(); - _dispatchEvent({ - sortable: _this, - name: 'clone' - }); - }); - !fallback && toggleClass(dragEl, options.dragClass, true); - - // Set proper drop events - if (fallback) { - ignoreNextClick = true; - _this._loopId = setInterval(_this._emulateDragOver, 50); - } else { - // Undo what was set in _prepareDragStart before drag started - off(document, 'mouseup', _this._onDrop); - off(document, 'touchend', _this._onDrop); - off(document, 'touchcancel', _this._onDrop); - if (dataTransfer) { - dataTransfer.effectAllowed = 'move'; - options.setData && options.setData.call(_this, dataTransfer, dragEl); - } - on(document, 'drop', _this); - - // #1276 fix: - css(dragEl, 'transform', 'translateZ(0)'); - } - awaitingDragStarted = true; - _this._dragStartId = _nextTick(_this._dragStarted.bind(_this, fallback, evt)); - on(document, 'selectstart', _this); - moved = true; - if (Safari) { - css(document.body, 'user-select', 'none'); - } - }, - // Returns true - if no further action is needed (either inserted or another condition) - _onDragOver: function _onDragOver( /**Event*/evt) { - var el = this.el, - target = evt.target, - dragRect, - targetRect, - revert, - options = this.options, - group = options.group, - activeSortable = Sortable.active, - isOwner = activeGroup === group, - canSort = options.sort, - fromSortable = putSortable || activeSortable, - vertical, - _this = this, - completedFired = false; - if (_silent) return; - function dragOverEvent(name, extra) { - pluginEvent(name, _this, _objectSpread2({ - evt: evt, - isOwner: isOwner, - axis: vertical ? 'vertical' : 'horizontal', - revert: revert, - dragRect: dragRect, - targetRect: targetRect, - canSort: canSort, - fromSortable: fromSortable, - target: target, - completed: completed, - onMove: function onMove(target, after) { - return _onMove(rootEl, el, dragEl, dragRect, target, getRect(target), evt, after); - }, - changed: changed - }, extra)); - } - - // Capture animation state - function capture() { - dragOverEvent('dragOverAnimationCapture'); - _this.captureAnimationState(); - if (_this !== fromSortable) { - fromSortable.captureAnimationState(); - } - } - - // Return invocation when dragEl is inserted (or completed) - function completed(insertion) { - dragOverEvent('dragOverCompleted', { - insertion: insertion - }); - if (insertion) { - // Clones must be hidden before folding animation to capture dragRectAbsolute properly - if (isOwner) { - activeSortable._hideClone(); - } else { - activeSortable._showClone(_this); - } - if (_this !== fromSortable) { - // Set ghost class to new sortable's ghost class - toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : activeSortable.options.ghostClass, false); - toggleClass(dragEl, options.ghostClass, true); - } - if (putSortable !== _this && _this !== Sortable.active) { - putSortable = _this; - } else if (_this === Sortable.active && putSortable) { - putSortable = null; - } - - // Animation - if (fromSortable === _this) { - _this._ignoreWhileAnimating = target; - } - _this.animateAll(function () { - dragOverEvent('dragOverAnimationComplete'); - _this._ignoreWhileAnimating = null; - }); - if (_this !== fromSortable) { - fromSortable.animateAll(); - fromSortable._ignoreWhileAnimating = null; - } - } - - // Null lastTarget if it is not inside a previously swapped element - if (target === dragEl && !dragEl.animated || target === el && !target.animated) { - lastTarget = null; - } - - // no bubbling and not fallback - if (!options.dragoverBubble && !evt.rootEl && target !== document) { - dragEl.parentNode[expando]._isOutsideThisEl(evt.target); - - // Do not detect for empty insert if already inserted - !insertion && nearestEmptyInsertDetectEvent(evt); - } - !options.dragoverBubble && evt.stopPropagation && evt.stopPropagation(); - return completedFired = true; - } - - // Call when dragEl has been inserted - function changed() { - newIndex = index(dragEl); - newDraggableIndex = index(dragEl, options.draggable); - _dispatchEvent({ - sortable: _this, - name: 'change', - toEl: el, - newIndex: newIndex, - newDraggableIndex: newDraggableIndex, - originalEvent: evt - }); - } - if (evt.preventDefault !== void 0) { - evt.cancelable && evt.preventDefault(); - } - target = closest(target, options.draggable, el, true); - dragOverEvent('dragOver'); - if (Sortable.eventCanceled) return completedFired; - if (dragEl.contains(evt.target) || target.animated && target.animatingX && target.animatingY || _this._ignoreWhileAnimating === target) { - return completed(false); - } - ignoreNextClick = false; - if (activeSortable && !options.disabled && (isOwner ? canSort || (revert = parentEl !== rootEl) // Reverting item into the original list - : putSortable === this || (this.lastPutMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && group.checkPut(this, activeSortable, dragEl, evt))) { - vertical = this._getDirection(evt, target) === 'vertical'; - dragRect = getRect(dragEl); - dragOverEvent('dragOverValid'); - if (Sortable.eventCanceled) return completedFired; - if (revert) { - parentEl = rootEl; // actualization - capture(); - this._hideClone(); - dragOverEvent('revert'); - if (!Sortable.eventCanceled) { - if (nextEl) { - rootEl.insertBefore(dragEl, nextEl); - } else { - rootEl.appendChild(dragEl); - } - } - return completed(true); - } - var elLastChild = lastChild(el, options.draggable); - if (!elLastChild || _ghostIsLast(evt, vertical, this) && !elLastChild.animated) { - // Insert to end of list - - // If already at end of list: Do not insert - if (elLastChild === dragEl) { - return completed(false); - } - - // if there is a last element, it is the target - if (elLastChild && el === evt.target) { - target = elLastChild; - } - if (target) { - targetRect = getRect(target); - } - if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, !!target) !== false) { - capture(); - if (elLastChild && elLastChild.nextSibling) { - // the last draggable element is not the last node - el.insertBefore(dragEl, elLastChild.nextSibling); - } else { - el.appendChild(dragEl); - } - parentEl = el; // actualization - - changed(); - return completed(true); - } - } else if (elLastChild && _ghostIsFirst(evt, vertical, this)) { - // Insert to start of list - var firstChild = getChild(el, 0, options, true); - if (firstChild === dragEl) { - return completed(false); - } - target = firstChild; - targetRect = getRect(target); - if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, false) !== false) { - capture(); - el.insertBefore(dragEl, firstChild); - parentEl = el; // actualization - - changed(); - return completed(true); - } - } else if (target.parentNode === el) { - targetRect = getRect(target); - var direction = 0, - targetBeforeFirstSwap, - differentLevel = dragEl.parentNode !== el, - differentRowCol = !_dragElInRowColumn(dragEl.animated && dragEl.toRect || dragRect, target.animated && target.toRect || targetRect, vertical), - side1 = vertical ? 'top' : 'left', - scrolledPastTop = isScrolledPast(target, 'top', 'top') || isScrolledPast(dragEl, 'top', 'top'), - scrollBefore = scrolledPastTop ? scrolledPastTop.scrollTop : void 0; - if (lastTarget !== target) { - targetBeforeFirstSwap = targetRect[side1]; - pastFirstInvertThresh = false; - isCircumstantialInvert = !differentRowCol && options.invertSwap || differentLevel; - } - direction = _getSwapDirection(evt, target, targetRect, vertical, differentRowCol ? 1 : options.swapThreshold, options.invertedSwapThreshold == null ? options.swapThreshold : options.invertedSwapThreshold, isCircumstantialInvert, lastTarget === target); - var sibling; - if (direction !== 0) { - // Check if target is beside dragEl in respective direction (ignoring hidden elements) - var dragIndex = index(dragEl); - do { - dragIndex -= direction; - sibling = parentEl.children[dragIndex]; - } while (sibling && (css(sibling, 'display') === 'none' || sibling === ghostEl)); - } - // If dragEl is already beside target: Do not insert - if (direction === 0 || sibling === target) { - return completed(false); - } - lastTarget = target; - lastDirection = direction; - var nextSibling = target.nextElementSibling, - after = false; - after = direction === 1; - var moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, after); - if (moveVector !== false) { - if (moveVector === 1 || moveVector === -1) { - after = moveVector === 1; - } - _silent = true; - setTimeout(_unsilent, 30); - capture(); - if (after && !nextSibling) { - el.appendChild(dragEl); - } else { - target.parentNode.insertBefore(dragEl, after ? nextSibling : target); - } - - // Undo chrome's scroll adjustment (has no effect on other browsers) - if (scrolledPastTop) { - scrollBy(scrolledPastTop, 0, scrollBefore - scrolledPastTop.scrollTop); - } - parentEl = dragEl.parentNode; // actualization - - // must be done before animation - if (targetBeforeFirstSwap !== undefined && !isCircumstantialInvert) { - targetMoveDistance = Math.abs(targetBeforeFirstSwap - getRect(target)[side1]); - } - changed(); - return completed(true); - } - } - if (el.contains(dragEl)) { - return completed(false); - } - } - return false; - }, - _ignoreWhileAnimating: null, - _offMoveEvents: function _offMoveEvents() { - off(document, 'mousemove', this._onTouchMove); - off(document, 'touchmove', this._onTouchMove); - off(document, 'pointermove', this._onTouchMove); - off(document, 'dragover', nearestEmptyInsertDetectEvent); - off(document, 'mousemove', nearestEmptyInsertDetectEvent); - off(document, 'touchmove', nearestEmptyInsertDetectEvent); - }, - _offUpEvents: function _offUpEvents() { - var ownerDocument = this.el.ownerDocument; - off(ownerDocument, 'mouseup', this._onDrop); - off(ownerDocument, 'touchend', this._onDrop); - off(ownerDocument, 'pointerup', this._onDrop); - off(ownerDocument, 'touchcancel', this._onDrop); - off(document, 'selectstart', this); - }, - _onDrop: function _onDrop( /**Event*/evt) { - var el = this.el, - options = this.options; - - // Get the index of the dragged element within its parent - newIndex = index(dragEl); - newDraggableIndex = index(dragEl, options.draggable); - pluginEvent('drop', this, { - evt: evt - }); - parentEl = dragEl && dragEl.parentNode; - - // Get again after plugin event - newIndex = index(dragEl); - newDraggableIndex = index(dragEl, options.draggable); - if (Sortable.eventCanceled) { - this._nulling(); - return; - } - awaitingDragStarted = false; - isCircumstantialInvert = false; - pastFirstInvertThresh = false; - clearInterval(this._loopId); - clearTimeout(this._dragStartTimer); - _cancelNextTick(this.cloneId); - _cancelNextTick(this._dragStartId); - - // Unbind events - if (this.nativeDraggable) { - off(document, 'drop', this); - off(el, 'dragstart', this._onDragStart); - } - this._offMoveEvents(); - this._offUpEvents(); - if (Safari) { - css(document.body, 'user-select', ''); - } - css(dragEl, 'transform', ''); - if (evt) { - if (moved) { - evt.cancelable && evt.preventDefault(); - !options.dropBubble && evt.stopPropagation(); - } - ghostEl && ghostEl.parentNode && ghostEl.parentNode.removeChild(ghostEl); - if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') { - // Remove clone(s) - cloneEl && cloneEl.parentNode && cloneEl.parentNode.removeChild(cloneEl); - } - if (dragEl) { - if (this.nativeDraggable) { - off(dragEl, 'dragend', this); - } - _disableDraggable(dragEl); - dragEl.style['will-change'] = ''; - - // Remove classes - // ghostClass is added in dragStarted - if (moved && !awaitingDragStarted) { - toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : this.options.ghostClass, false); - } - toggleClass(dragEl, this.options.chosenClass, false); - - // Drag stop event - _dispatchEvent({ - sortable: this, - name: 'unchoose', - toEl: parentEl, - newIndex: null, - newDraggableIndex: null, - originalEvent: evt - }); - if (rootEl !== parentEl) { - if (newIndex >= 0) { - // Add event - _dispatchEvent({ - rootEl: parentEl, - name: 'add', - toEl: parentEl, - fromEl: rootEl, - originalEvent: evt - }); - - // Remove event - _dispatchEvent({ - sortable: this, - name: 'remove', - toEl: parentEl, - originalEvent: evt - }); - - // drag from one list and drop into another - _dispatchEvent({ - rootEl: parentEl, - name: 'sort', - toEl: parentEl, - fromEl: rootEl, - originalEvent: evt - }); - _dispatchEvent({ - sortable: this, - name: 'sort', - toEl: parentEl, - originalEvent: evt - }); - } - putSortable && putSortable.save(); - } else { - if (newIndex !== oldIndex) { - if (newIndex >= 0) { - // drag & drop within the same list - _dispatchEvent({ - sortable: this, - name: 'update', - toEl: parentEl, - originalEvent: evt - }); - _dispatchEvent({ - sortable: this, - name: 'sort', - toEl: parentEl, - originalEvent: evt - }); - } - } - } - if (Sortable.active) { - /* jshint eqnull:true */ - if (newIndex == null || newIndex === -1) { - newIndex = oldIndex; - newDraggableIndex = oldDraggableIndex; - } - _dispatchEvent({ - sortable: this, - name: 'end', - toEl: parentEl, - originalEvent: evt - }); - - // Save sorting - this.save(); - } - } - } - this._nulling(); - }, - _nulling: function _nulling() { - pluginEvent('nulling', this); - rootEl = dragEl = parentEl = ghostEl = nextEl = cloneEl = lastDownEl = cloneHidden = tapEvt = touchEvt = moved = newIndex = newDraggableIndex = oldIndex = oldDraggableIndex = lastTarget = lastDirection = putSortable = activeGroup = Sortable.dragged = Sortable.ghost = Sortable.clone = Sortable.active = null; - savedInputChecked.forEach(function (el) { - el.checked = true; - }); - savedInputChecked.length = lastDx = lastDy = 0; - }, - handleEvent: function handleEvent( /**Event*/evt) { - switch (evt.type) { - case 'drop': - case 'dragend': - this._onDrop(evt); - break; - case 'dragenter': - case 'dragover': - if (dragEl) { - this._onDragOver(evt); - _globalDragOver(evt); - } - break; - case 'selectstart': - evt.preventDefault(); - break; - } - }, - /** - * Serializes the item into an array of string. - * @returns {String[]} - */ - toArray: function toArray() { - var order = [], - el, - children = this.el.children, - i = 0, - n = children.length, - options = this.options; - for (; i < n; i++) { - el = children[i]; - if (closest(el, options.draggable, this.el, false)) { - order.push(el.getAttribute(options.dataIdAttr) || _generateId(el)); - } - } - return order; - }, - /** - * Sorts the elements according to the array. - * @param {String[]} order order of the items - */ - sort: function sort(order, useAnimation) { - var items = {}, - rootEl = this.el; - this.toArray().forEach(function (id, i) { - var el = rootEl.children[i]; - if (closest(el, this.options.draggable, rootEl, false)) { - items[id] = el; - } - }, this); - useAnimation && this.captureAnimationState(); - order.forEach(function (id) { - if (items[id]) { - rootEl.removeChild(items[id]); - rootEl.appendChild(items[id]); - } - }); - useAnimation && this.animateAll(); - }, - /** - * Save the current sorting - */ - save: function save() { - var store = this.options.store; - store && store.set && store.set(this); - }, - /** - * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. - * @param {HTMLElement} el - * @param {String} [selector] default: `options.draggable` - * @returns {HTMLElement|null} - */ - closest: function closest$1(el, selector) { - return closest(el, selector || this.options.draggable, this.el, false); - }, - /** - * Set/get option - * @param {string} name - * @param {*} [value] - * @returns {*} - */ - option: function option(name, value) { - var options = this.options; - if (value === void 0) { - return options[name]; - } else { - var modifiedValue = PluginManager.modifyOption(this, name, value); - if (typeof modifiedValue !== 'undefined') { - options[name] = modifiedValue; - } else { - options[name] = value; - } - if (name === 'group') { - _prepareGroup(options); - } - } - }, - /** - * Destroy - */ - destroy: function destroy() { - pluginEvent('destroy', this); - var el = this.el; - el[expando] = null; - off(el, 'mousedown', this._onTapStart); - off(el, 'touchstart', this._onTapStart); - off(el, 'pointerdown', this._onTapStart); - if (this.nativeDraggable) { - off(el, 'dragover', this); - off(el, 'dragenter', this); - } - // Remove draggable attributes - Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) { - el.removeAttribute('draggable'); - }); - this._onDrop(); - this._disableDelayedDragEvents(); - sortables.splice(sortables.indexOf(this.el), 1); - this.el = el = null; - }, - _hideClone: function _hideClone() { - if (!cloneHidden) { - pluginEvent('hideClone', this); - if (Sortable.eventCanceled) return; - css(cloneEl, 'display', 'none'); - if (this.options.removeCloneOnHide && cloneEl.parentNode) { - cloneEl.parentNode.removeChild(cloneEl); - } - cloneHidden = true; - } - }, - _showClone: function _showClone(putSortable) { - if (putSortable.lastPutMode !== 'clone') { - this._hideClone(); - return; - } - if (cloneHidden) { - pluginEvent('showClone', this); - if (Sortable.eventCanceled) return; - - // show clone at dragEl or original position - if (dragEl.parentNode == rootEl && !this.options.group.revertClone) { - rootEl.insertBefore(cloneEl, dragEl); - } else if (nextEl) { - rootEl.insertBefore(cloneEl, nextEl); - } else { - rootEl.appendChild(cloneEl); - } - if (this.options.group.revertClone) { - this.animate(dragEl, cloneEl); - } - css(cloneEl, 'display', ''); - cloneHidden = false; - } - } - }; - function _globalDragOver( /**Event*/evt) { - if (evt.dataTransfer) { - evt.dataTransfer.dropEffect = 'move'; - } - evt.cancelable && evt.preventDefault(); - } - function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect, originalEvent, willInsertAfter) { - var evt, - sortable = fromEl[expando], - onMoveFn = sortable.options.onMove, - retVal; - // Support for new CustomEvent feature - if (window.CustomEvent && !IE11OrLess && !Edge) { - evt = new CustomEvent('move', { - bubbles: true, - cancelable: true - }); - } else { - evt = document.createEvent('Event'); - evt.initEvent('move', true, true); - } - evt.to = toEl; - evt.from = fromEl; - evt.dragged = dragEl; - evt.draggedRect = dragRect; - evt.related = targetEl || toEl; - evt.relatedRect = targetRect || getRect(toEl); - evt.willInsertAfter = willInsertAfter; - evt.originalEvent = originalEvent; - fromEl.dispatchEvent(evt); - if (onMoveFn) { - retVal = onMoveFn.call(sortable, evt, originalEvent); - } - return retVal; - } - function _disableDraggable(el) { - el.draggable = false; - } - function _unsilent() { - _silent = false; - } - function _ghostIsFirst(evt, vertical, sortable) { - var firstElRect = getRect(getChild(sortable.el, 0, sortable.options, true)); - var childContainingRect = getChildContainingRectFromElement(sortable.el, sortable.options, ghostEl); - var spacer = 10; - return vertical ? evt.clientX < childContainingRect.left - spacer || evt.clientY < firstElRect.top && evt.clientX < firstElRect.right : evt.clientY < childContainingRect.top - spacer || evt.clientY < firstElRect.bottom && evt.clientX < firstElRect.left; - } - function _ghostIsLast(evt, vertical, sortable) { - var lastElRect = getRect(lastChild(sortable.el, sortable.options.draggable)); - var childContainingRect = getChildContainingRectFromElement(sortable.el, sortable.options, ghostEl); - var spacer = 10; - return vertical ? evt.clientX > childContainingRect.right + spacer || evt.clientY > lastElRect.bottom && evt.clientX > lastElRect.left : evt.clientY > childContainingRect.bottom + spacer || evt.clientX > lastElRect.right && evt.clientY > lastElRect.top; - } - function _getSwapDirection(evt, target, targetRect, vertical, swapThreshold, invertedSwapThreshold, invertSwap, isLastTarget) { - var mouseOnAxis = vertical ? evt.clientY : evt.clientX, - targetLength = vertical ? targetRect.height : targetRect.width, - targetS1 = vertical ? targetRect.top : targetRect.left, - targetS2 = vertical ? targetRect.bottom : targetRect.right, - invert = false; - if (!invertSwap) { - // Never invert or create dragEl shadow when target movemenet causes mouse to move past the end of regular swapThreshold - if (isLastTarget && targetMoveDistance < targetLength * swapThreshold) { - // multiplied only by swapThreshold because mouse will already be inside target by (1 - threshold) * targetLength / 2 - // check if past first invert threshold on side opposite of lastDirection - if (!pastFirstInvertThresh && (lastDirection === 1 ? mouseOnAxis > targetS1 + targetLength * invertedSwapThreshold / 2 : mouseOnAxis < targetS2 - targetLength * invertedSwapThreshold / 2)) { - // past first invert threshold, do not restrict inverted threshold to dragEl shadow - pastFirstInvertThresh = true; - } - if (!pastFirstInvertThresh) { - // dragEl shadow (target move distance shadow) - if (lastDirection === 1 ? mouseOnAxis < targetS1 + targetMoveDistance // over dragEl shadow - : mouseOnAxis > targetS2 - targetMoveDistance) { - return -lastDirection; - } - } else { - invert = true; - } - } else { - // Regular - if (mouseOnAxis > targetS1 + targetLength * (1 - swapThreshold) / 2 && mouseOnAxis < targetS2 - targetLength * (1 - swapThreshold) / 2) { - return _getInsertDirection(target); - } - } - } - invert = invert || invertSwap; - if (invert) { - // Invert of regular - if (mouseOnAxis < targetS1 + targetLength * invertedSwapThreshold / 2 || mouseOnAxis > targetS2 - targetLength * invertedSwapThreshold / 2) { - return mouseOnAxis > targetS1 + targetLength / 2 ? 1 : -1; - } - } - return 0; - } - - /** - * Gets the direction dragEl must be swapped relative to target in order to make it - * seem that dragEl has been "inserted" into that element's position - * @param {HTMLElement} target The target whose position dragEl is being inserted at - * @return {Number} Direction dragEl must be swapped - */ - function _getInsertDirection(target) { - if (index(dragEl) < index(target)) { - return 1; - } else { - return -1; - } - } - - /** - * Generate id - * @param {HTMLElement} el - * @returns {String} - * @private - */ - function _generateId(el) { - var str = el.tagName + el.className + el.src + el.href + el.textContent, - i = str.length, - sum = 0; - while (i--) { - sum += str.charCodeAt(i); - } - return sum.toString(36); - } - function _saveInputCheckedState(root) { - savedInputChecked.length = 0; - var inputs = root.getElementsByTagName('input'); - var idx = inputs.length; - while (idx--) { - var el = inputs[idx]; - el.checked && savedInputChecked.push(el); - } - } - function _nextTick(fn) { - return setTimeout(fn, 0); - } - function _cancelNextTick(id) { - return clearTimeout(id); - } - - // Fixed #973: - if (documentExists) { - on(document, 'touchmove', function (evt) { - if ((Sortable.active || awaitingDragStarted) && evt.cancelable) { - evt.preventDefault(); - } - }); - } - - // Export utils - Sortable.utils = { - on: on, - off: off, - css: css, - find: find, - is: function is(el, selector) { - return !!closest(el, selector, el, false); - }, - extend: extend, - throttle: throttle, - closest: closest, - toggleClass: toggleClass, - clone: clone, - index: index, - nextTick: _nextTick, - cancelNextTick: _cancelNextTick, - detectDirection: _detectDirection, - getChild: getChild - }; - - /** - * Get the Sortable instance of an element - * @param {HTMLElement} element The element - * @return {Sortable|undefined} The instance of Sortable - */ - Sortable.get = function (element) { - return element[expando]; - }; - - /** - * Mount a plugin to Sortable - * @param {...SortablePlugin|SortablePlugin[]} plugins Plugins being mounted - */ - Sortable.mount = function () { - for (var _len = arguments.length, plugins = new Array(_len), _key = 0; _key < _len; _key++) { - plugins[_key] = arguments[_key]; - } - if (plugins[0].constructor === Array) plugins = plugins[0]; - plugins.forEach(function (plugin) { - if (!plugin.prototype || !plugin.prototype.constructor) { - throw "Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(plugin)); - } - if (plugin.utils) Sortable.utils = _objectSpread2(_objectSpread2({}, Sortable.utils), plugin.utils); - PluginManager.mount(plugin); - }); - }; - - /** - * Create sortable instance - * @param {HTMLElement} el - * @param {Object} [options] - */ - Sortable.create = function (el, options) { - return new Sortable(el, options); - }; - - // Export - Sortable.version = version; - - var autoScrolls = [], - scrollEl, - scrollRootEl, - scrolling = false, - lastAutoScrollX, - lastAutoScrollY, - touchEvt$1, - pointerElemChangedInterval; - function AutoScrollPlugin() { - function AutoScroll() { - this.defaults = { - scroll: true, - forceAutoScrollFallback: false, - scrollSensitivity: 30, - scrollSpeed: 10, - bubbleScroll: true - }; - - // Bind all private methods - for (var fn in this) { - if (fn.charAt(0) === '_' && typeof this[fn] === 'function') { - this[fn] = this[fn].bind(this); - } - } - } - AutoScroll.prototype = { - dragStarted: function dragStarted(_ref) { - var originalEvent = _ref.originalEvent; - if (this.sortable.nativeDraggable) { - on(document, 'dragover', this._handleAutoScroll); - } else { - if (this.options.supportPointer) { - on(document, 'pointermove', this._handleFallbackAutoScroll); - } else if (originalEvent.touches) { - on(document, 'touchmove', this._handleFallbackAutoScroll); - } else { - on(document, 'mousemove', this._handleFallbackAutoScroll); - } - } - }, - dragOverCompleted: function dragOverCompleted(_ref2) { - var originalEvent = _ref2.originalEvent; - // For when bubbling is canceled and using fallback (fallback 'touchmove' always reached) - if (!this.options.dragOverBubble && !originalEvent.rootEl) { - this._handleAutoScroll(originalEvent); - } - }, - drop: function drop() { - if (this.sortable.nativeDraggable) { - off(document, 'dragover', this._handleAutoScroll); - } else { - off(document, 'pointermove', this._handleFallbackAutoScroll); - off(document, 'touchmove', this._handleFallbackAutoScroll); - off(document, 'mousemove', this._handleFallbackAutoScroll); - } - clearPointerElemChangedInterval(); - clearAutoScrolls(); - cancelThrottle(); - }, - nulling: function nulling() { - touchEvt$1 = scrollRootEl = scrollEl = scrolling = pointerElemChangedInterval = lastAutoScrollX = lastAutoScrollY = null; - autoScrolls.length = 0; - }, - _handleFallbackAutoScroll: function _handleFallbackAutoScroll(evt) { - this._handleAutoScroll(evt, true); - }, - _handleAutoScroll: function _handleAutoScroll(evt, fallback) { - var _this = this; - var x = (evt.touches ? evt.touches[0] : evt).clientX, - y = (evt.touches ? evt.touches[0] : evt).clientY, - elem = document.elementFromPoint(x, y); - touchEvt$1 = evt; - - // IE does not seem to have native autoscroll, - // Edge's autoscroll seems too conditional, - // MACOS Safari does not have autoscroll, - // Firefox and Chrome are good - if (fallback || this.options.forceAutoScrollFallback || Edge || IE11OrLess || Safari) { - autoScroll(evt, this.options, elem, fallback); - - // Listener for pointer element change - var ogElemScroller = getParentAutoScrollElement(elem, true); - if (scrolling && (!pointerElemChangedInterval || x !== lastAutoScrollX || y !== lastAutoScrollY)) { - pointerElemChangedInterval && clearPointerElemChangedInterval(); - // Detect for pointer elem change, emulating native DnD behaviour - pointerElemChangedInterval = setInterval(function () { - var newElem = getParentAutoScrollElement(document.elementFromPoint(x, y), true); - if (newElem !== ogElemScroller) { - ogElemScroller = newElem; - clearAutoScrolls(); - } - autoScroll(evt, _this.options, newElem, fallback); - }, 10); - lastAutoScrollX = x; - lastAutoScrollY = y; - } - } else { - // if DnD is enabled (and browser has good autoscrolling), first autoscroll will already scroll, so get parent autoscroll of first autoscroll - if (!this.options.bubbleScroll || getParentAutoScrollElement(elem, true) === getWindowScrollingElement()) { - clearAutoScrolls(); - return; - } - autoScroll(evt, this.options, getParentAutoScrollElement(elem, false), false); - } - } - }; - return _extends(AutoScroll, { - pluginName: 'scroll', - initializeByDefault: true - }); - } - function clearAutoScrolls() { - autoScrolls.forEach(function (autoScroll) { - clearInterval(autoScroll.pid); - }); - autoScrolls = []; - } - function clearPointerElemChangedInterval() { - clearInterval(pointerElemChangedInterval); - } - var autoScroll = throttle(function (evt, options, rootEl, isFallback) { - // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521 - if (!options.scroll) return; - var x = (evt.touches ? evt.touches[0] : evt).clientX, - y = (evt.touches ? evt.touches[0] : evt).clientY, - sens = options.scrollSensitivity, - speed = options.scrollSpeed, - winScroller = getWindowScrollingElement(); - var scrollThisInstance = false, - scrollCustomFn; - - // New scroll root, set scrollEl - if (scrollRootEl !== rootEl) { - scrollRootEl = rootEl; - clearAutoScrolls(); - scrollEl = options.scroll; - scrollCustomFn = options.scrollFn; - if (scrollEl === true) { - scrollEl = getParentAutoScrollElement(rootEl, true); - } - } - var layersOut = 0; - var currentParent = scrollEl; - do { - var el = currentParent, - rect = getRect(el), - top = rect.top, - bottom = rect.bottom, - left = rect.left, - right = rect.right, - width = rect.width, - height = rect.height, - canScrollX = void 0, - canScrollY = void 0, - scrollWidth = el.scrollWidth, - scrollHeight = el.scrollHeight, - elCSS = css(el), - scrollPosX = el.scrollLeft, - scrollPosY = el.scrollTop; - if (el === winScroller) { - canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll' || elCSS.overflowX === 'visible'); - canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll' || elCSS.overflowY === 'visible'); - } else { - canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll'); - canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll'); - } - var vx = canScrollX && (Math.abs(right - x) <= sens && scrollPosX + width < scrollWidth) - (Math.abs(left - x) <= sens && !!scrollPosX); - var vy = canScrollY && (Math.abs(bottom - y) <= sens && scrollPosY + height < scrollHeight) - (Math.abs(top - y) <= sens && !!scrollPosY); - if (!autoScrolls[layersOut]) { - for (var i = 0; i <= layersOut; i++) { - if (!autoScrolls[i]) { - autoScrolls[i] = {}; - } - } - } - if (autoScrolls[layersOut].vx != vx || autoScrolls[layersOut].vy != vy || autoScrolls[layersOut].el !== el) { - autoScrolls[layersOut].el = el; - autoScrolls[layersOut].vx = vx; - autoScrolls[layersOut].vy = vy; - clearInterval(autoScrolls[layersOut].pid); - if (vx != 0 || vy != 0) { - scrollThisInstance = true; - /* jshint loopfunc:true */ - autoScrolls[layersOut].pid = setInterval(function () { - // emulate drag over during autoscroll (fallback), emulating native DnD behaviour - if (isFallback && this.layer === 0) { - Sortable.active._onTouchMove(touchEvt$1); // To move ghost if it is positioned absolutely - } - var scrollOffsetY = autoScrolls[this.layer].vy ? autoScrolls[this.layer].vy * speed : 0; - var scrollOffsetX = autoScrolls[this.layer].vx ? autoScrolls[this.layer].vx * speed : 0; - if (typeof scrollCustomFn === 'function') { - if (scrollCustomFn.call(Sortable.dragged.parentNode[expando], scrollOffsetX, scrollOffsetY, evt, touchEvt$1, autoScrolls[this.layer].el) !== 'continue') { - return; - } - } - scrollBy(autoScrolls[this.layer].el, scrollOffsetX, scrollOffsetY); - }.bind({ - layer: layersOut - }), 24); - } - } - layersOut++; - } while (options.bubbleScroll && currentParent !== winScroller && (currentParent = getParentAutoScrollElement(currentParent, false))); - scrolling = scrollThisInstance; // in case another function catches scrolling as false in between when it is not - }, 30); - - var drop = function drop(_ref) { - var originalEvent = _ref.originalEvent, - putSortable = _ref.putSortable, - dragEl = _ref.dragEl, - activeSortable = _ref.activeSortable, - dispatchSortableEvent = _ref.dispatchSortableEvent, - hideGhostForTarget = _ref.hideGhostForTarget, - unhideGhostForTarget = _ref.unhideGhostForTarget; - if (!originalEvent) return; - var toSortable = putSortable || activeSortable; - hideGhostForTarget(); - var touch = originalEvent.changedTouches && originalEvent.changedTouches.length ? originalEvent.changedTouches[0] : originalEvent; - var target = document.elementFromPoint(touch.clientX, touch.clientY); - unhideGhostForTarget(); - if (toSortable && !toSortable.el.contains(target)) { - dispatchSortableEvent('spill'); - this.onSpill({ - dragEl: dragEl, - putSortable: putSortable - }); - } - }; - function Revert() {} - Revert.prototype = { - startIndex: null, - dragStart: function dragStart(_ref2) { - var oldDraggableIndex = _ref2.oldDraggableIndex; - this.startIndex = oldDraggableIndex; - }, - onSpill: function onSpill(_ref3) { - var dragEl = _ref3.dragEl, - putSortable = _ref3.putSortable; - this.sortable.captureAnimationState(); - if (putSortable) { - putSortable.captureAnimationState(); - } - var nextSibling = getChild(this.sortable.el, this.startIndex, this.options); - if (nextSibling) { - this.sortable.el.insertBefore(dragEl, nextSibling); - } else { - this.sortable.el.appendChild(dragEl); - } - this.sortable.animateAll(); - if (putSortable) { - putSortable.animateAll(); - } - }, - drop: drop - }; - _extends(Revert, { - pluginName: 'revertOnSpill' - }); - function Remove() {} - Remove.prototype = { - onSpill: function onSpill(_ref4) { - var dragEl = _ref4.dragEl, - putSortable = _ref4.putSortable; - var parentSortable = putSortable || this.sortable; - parentSortable.captureAnimationState(); - dragEl.parentNode && dragEl.parentNode.removeChild(dragEl); - parentSortable.animateAll(); - }, - drop: drop - }; - _extends(Remove, { - pluginName: 'removeOnSpill' - }); - - var lastSwapEl; - function SwapPlugin() { - function Swap() { - this.defaults = { - swapClass: 'sortable-swap-highlight' - }; - } - Swap.prototype = { - dragStart: function dragStart(_ref) { - var dragEl = _ref.dragEl; - lastSwapEl = dragEl; - }, - dragOverValid: function dragOverValid(_ref2) { - var completed = _ref2.completed, - target = _ref2.target, - onMove = _ref2.onMove, - activeSortable = _ref2.activeSortable, - changed = _ref2.changed, - cancel = _ref2.cancel; - if (!activeSortable.options.swap) return; - var el = this.sortable.el, - options = this.options; - if (target && target !== el) { - var prevSwapEl = lastSwapEl; - if (onMove(target) !== false) { - toggleClass(target, options.swapClass, true); - lastSwapEl = target; - } else { - lastSwapEl = null; - } - if (prevSwapEl && prevSwapEl !== lastSwapEl) { - toggleClass(prevSwapEl, options.swapClass, false); - } - } - changed(); - completed(true); - cancel(); - }, - drop: function drop(_ref3) { - var activeSortable = _ref3.activeSortable, - putSortable = _ref3.putSortable, - dragEl = _ref3.dragEl; - var toSortable = putSortable || this.sortable; - var options = this.options; - lastSwapEl && toggleClass(lastSwapEl, options.swapClass, false); - if (lastSwapEl && (options.swap || putSortable && putSortable.options.swap)) { - if (dragEl !== lastSwapEl) { - toSortable.captureAnimationState(); - if (toSortable !== activeSortable) activeSortable.captureAnimationState(); - swapNodes(dragEl, lastSwapEl); - toSortable.animateAll(); - if (toSortable !== activeSortable) activeSortable.animateAll(); - } - } - }, - nulling: function nulling() { - lastSwapEl = null; - } - }; - return _extends(Swap, { - pluginName: 'swap', - eventProperties: function eventProperties() { - return { - swapItem: lastSwapEl - }; - } - }); - } - function swapNodes(n1, n2) { - var p1 = n1.parentNode, - p2 = n2.parentNode, - i1, - i2; - if (!p1 || !p2 || p1.isEqualNode(n2) || p2.isEqualNode(n1)) return; - i1 = index(n1); - i2 = index(n2); - if (p1.isEqualNode(p2) && i1 < i2) { - i2++; - } - p1.insertBefore(n2, p1.children[i1]); - p2.insertBefore(n1, p2.children[i2]); - } - - var multiDragElements = [], - multiDragClones = [], - lastMultiDragSelect, - // for selection with modifier key down (SHIFT) - multiDragSortable, - initialFolding = false, - // Initial multi-drag fold when drag started - folding = false, - // Folding any other time - dragStarted = false, - dragEl$1, - clonesFromRect, - clonesHidden; - function MultiDragPlugin() { - function MultiDrag(sortable) { - // Bind all private methods - for (var fn in this) { - if (fn.charAt(0) === '_' && typeof this[fn] === 'function') { - this[fn] = this[fn].bind(this); - } - } - if (!sortable.options.avoidImplicitDeselect) { - if (sortable.options.supportPointer) { - on(document, 'pointerup', this._deselectMultiDrag); - } else { - on(document, 'mouseup', this._deselectMultiDrag); - on(document, 'touchend', this._deselectMultiDrag); - } - } - on(document, 'keydown', this._checkKeyDown); - on(document, 'keyup', this._checkKeyUp); - this.defaults = { - selectedClass: 'sortable-selected', - multiDragKey: null, - avoidImplicitDeselect: false, - setData: function setData(dataTransfer, dragEl) { - var data = ''; - if (multiDragElements.length && multiDragSortable === sortable) { - multiDragElements.forEach(function (multiDragElement, i) { - data += (!i ? '' : ', ') + multiDragElement.textContent; - }); - } else { - data = dragEl.textContent; - } - dataTransfer.setData('Text', data); - } - }; - } - MultiDrag.prototype = { - multiDragKeyDown: false, - isMultiDrag: false, - delayStartGlobal: function delayStartGlobal(_ref) { - var dragged = _ref.dragEl; - dragEl$1 = dragged; - }, - delayEnded: function delayEnded() { - this.isMultiDrag = ~multiDragElements.indexOf(dragEl$1); - }, - setupClone: function setupClone(_ref2) { - var sortable = _ref2.sortable, - cancel = _ref2.cancel; - if (!this.isMultiDrag) return; - for (var i = 0; i < multiDragElements.length; i++) { - multiDragClones.push(clone(multiDragElements[i])); - multiDragClones[i].sortableIndex = multiDragElements[i].sortableIndex; - multiDragClones[i].draggable = false; - multiDragClones[i].style['will-change'] = ''; - toggleClass(multiDragClones[i], this.options.selectedClass, false); - multiDragElements[i] === dragEl$1 && toggleClass(multiDragClones[i], this.options.chosenClass, false); - } - sortable._hideClone(); - cancel(); - }, - clone: function clone(_ref3) { - var sortable = _ref3.sortable, - rootEl = _ref3.rootEl, - dispatchSortableEvent = _ref3.dispatchSortableEvent, - cancel = _ref3.cancel; - if (!this.isMultiDrag) return; - if (!this.options.removeCloneOnHide) { - if (multiDragElements.length && multiDragSortable === sortable) { - insertMultiDragClones(true, rootEl); - dispatchSortableEvent('clone'); - cancel(); - } - } - }, - showClone: function showClone(_ref4) { - var cloneNowShown = _ref4.cloneNowShown, - rootEl = _ref4.rootEl, - cancel = _ref4.cancel; - if (!this.isMultiDrag) return; - insertMultiDragClones(false, rootEl); - multiDragClones.forEach(function (clone) { - css(clone, 'display', ''); - }); - cloneNowShown(); - clonesHidden = false; - cancel(); - }, - hideClone: function hideClone(_ref5) { - var _this = this; - var sortable = _ref5.sortable, - cloneNowHidden = _ref5.cloneNowHidden, - cancel = _ref5.cancel; - if (!this.isMultiDrag) return; - multiDragClones.forEach(function (clone) { - css(clone, 'display', 'none'); - if (_this.options.removeCloneOnHide && clone.parentNode) { - clone.parentNode.removeChild(clone); - } - }); - cloneNowHidden(); - clonesHidden = true; - cancel(); - }, - dragStartGlobal: function dragStartGlobal(_ref6) { - var sortable = _ref6.sortable; - if (!this.isMultiDrag && multiDragSortable) { - multiDragSortable.multiDrag._deselectMultiDrag(); - } - multiDragElements.forEach(function (multiDragElement) { - multiDragElement.sortableIndex = index(multiDragElement); - }); - - // Sort multi-drag elements - multiDragElements = multiDragElements.sort(function (a, b) { - return a.sortableIndex - b.sortableIndex; - }); - dragStarted = true; - }, - dragStarted: function dragStarted(_ref7) { - var _this2 = this; - var sortable = _ref7.sortable; - if (!this.isMultiDrag) return; - if (this.options.sort) { - // Capture rects, - // hide multi drag elements (by positioning them absolute), - // set multi drag elements rects to dragRect, - // show multi drag elements, - // animate to rects, - // unset rects & remove from DOM - - sortable.captureAnimationState(); - if (this.options.animation) { - multiDragElements.forEach(function (multiDragElement) { - if (multiDragElement === dragEl$1) return; - css(multiDragElement, 'position', 'absolute'); - }); - var dragRect = getRect(dragEl$1, false, true, true); - multiDragElements.forEach(function (multiDragElement) { - if (multiDragElement === dragEl$1) return; - setRect(multiDragElement, dragRect); - }); - folding = true; - initialFolding = true; - } - } - sortable.animateAll(function () { - folding = false; - initialFolding = false; - if (_this2.options.animation) { - multiDragElements.forEach(function (multiDragElement) { - unsetRect(multiDragElement); - }); - } - - // Remove all auxiliary multidrag items from el, if sorting enabled - if (_this2.options.sort) { - removeMultiDragElements(); - } - }); - }, - dragOver: function dragOver(_ref8) { - var target = _ref8.target, - completed = _ref8.completed, - cancel = _ref8.cancel; - if (folding && ~multiDragElements.indexOf(target)) { - completed(false); - cancel(); - } - }, - revert: function revert(_ref9) { - var fromSortable = _ref9.fromSortable, - rootEl = _ref9.rootEl, - sortable = _ref9.sortable, - dragRect = _ref9.dragRect; - if (multiDragElements.length > 1) { - // Setup unfold animation - multiDragElements.forEach(function (multiDragElement) { - sortable.addAnimationState({ - target: multiDragElement, - rect: folding ? getRect(multiDragElement) : dragRect - }); - unsetRect(multiDragElement); - multiDragElement.fromRect = dragRect; - fromSortable.removeAnimationState(multiDragElement); - }); - folding = false; - insertMultiDragElements(!this.options.removeCloneOnHide, rootEl); - } - }, - dragOverCompleted: function dragOverCompleted(_ref10) { - var sortable = _ref10.sortable, - isOwner = _ref10.isOwner, - insertion = _ref10.insertion, - activeSortable = _ref10.activeSortable, - parentEl = _ref10.parentEl, - putSortable = _ref10.putSortable; - var options = this.options; - if (insertion) { - // Clones must be hidden before folding animation to capture dragRectAbsolute properly - if (isOwner) { - activeSortable._hideClone(); - } - initialFolding = false; - // If leaving sort:false root, or already folding - Fold to new location - if (options.animation && multiDragElements.length > 1 && (folding || !isOwner && !activeSortable.options.sort && !putSortable)) { - // Fold: Set all multi drag elements's rects to dragEl's rect when multi-drag elements are invisible - var dragRectAbsolute = getRect(dragEl$1, false, true, true); - multiDragElements.forEach(function (multiDragElement) { - if (multiDragElement === dragEl$1) return; - setRect(multiDragElement, dragRectAbsolute); - - // Move element(s) to end of parentEl so that it does not interfere with multi-drag clones insertion if they are inserted - // while folding, and so that we can capture them again because old sortable will no longer be fromSortable - parentEl.appendChild(multiDragElement); - }); - folding = true; - } - - // Clones must be shown (and check to remove multi drags) after folding when interfering multiDragElements are moved out - if (!isOwner) { - // Only remove if not folding (folding will remove them anyways) - if (!folding) { - removeMultiDragElements(); - } - if (multiDragElements.length > 1) { - var clonesHiddenBefore = clonesHidden; - activeSortable._showClone(sortable); - - // Unfold animation for clones if showing from hidden - if (activeSortable.options.animation && !clonesHidden && clonesHiddenBefore) { - multiDragClones.forEach(function (clone) { - activeSortable.addAnimationState({ - target: clone, - rect: clonesFromRect - }); - clone.fromRect = clonesFromRect; - clone.thisAnimationDuration = null; - }); - } - } else { - activeSortable._showClone(sortable); - } - } - } - }, - dragOverAnimationCapture: function dragOverAnimationCapture(_ref11) { - var dragRect = _ref11.dragRect, - isOwner = _ref11.isOwner, - activeSortable = _ref11.activeSortable; - multiDragElements.forEach(function (multiDragElement) { - multiDragElement.thisAnimationDuration = null; - }); - if (activeSortable.options.animation && !isOwner && activeSortable.multiDrag.isMultiDrag) { - clonesFromRect = _extends({}, dragRect); - var dragMatrix = matrix(dragEl$1, true); - clonesFromRect.top -= dragMatrix.f; - clonesFromRect.left -= dragMatrix.e; - } - }, - dragOverAnimationComplete: function dragOverAnimationComplete() { - if (folding) { - folding = false; - removeMultiDragElements(); - } - }, - drop: function drop(_ref12) { - var evt = _ref12.originalEvent, - rootEl = _ref12.rootEl, - parentEl = _ref12.parentEl, - sortable = _ref12.sortable, - dispatchSortableEvent = _ref12.dispatchSortableEvent, - oldIndex = _ref12.oldIndex, - putSortable = _ref12.putSortable; - var toSortable = putSortable || this.sortable; - if (!evt) return; - var options = this.options, - children = parentEl.children; - - // Multi-drag selection - if (!dragStarted) { - if (options.multiDragKey && !this.multiDragKeyDown) { - this._deselectMultiDrag(); - } - toggleClass(dragEl$1, options.selectedClass, !~multiDragElements.indexOf(dragEl$1)); - if (!~multiDragElements.indexOf(dragEl$1)) { - multiDragElements.push(dragEl$1); - dispatchEvent({ - sortable: sortable, - rootEl: rootEl, - name: 'select', - targetEl: dragEl$1, - originalEvent: evt - }); - - // Modifier activated, select from last to dragEl - if (evt.shiftKey && lastMultiDragSelect && sortable.el.contains(lastMultiDragSelect)) { - var lastIndex = index(lastMultiDragSelect), - currentIndex = index(dragEl$1); - if (~lastIndex && ~currentIndex && lastIndex !== currentIndex) { - // Must include lastMultiDragSelect (select it), in case modified selection from no selection - // (but previous selection existed) - var n, i; - if (currentIndex > lastIndex) { - i = lastIndex; - n = currentIndex; - } else { - i = currentIndex; - n = lastIndex + 1; - } - for (; i < n; i++) { - if (~multiDragElements.indexOf(children[i])) continue; - toggleClass(children[i], options.selectedClass, true); - multiDragElements.push(children[i]); - dispatchEvent({ - sortable: sortable, - rootEl: rootEl, - name: 'select', - targetEl: children[i], - originalEvent: evt - }); - } - } - } else { - lastMultiDragSelect = dragEl$1; - } - multiDragSortable = toSortable; - } else { - multiDragElements.splice(multiDragElements.indexOf(dragEl$1), 1); - lastMultiDragSelect = null; - dispatchEvent({ - sortable: sortable, - rootEl: rootEl, - name: 'deselect', - targetEl: dragEl$1, - originalEvent: evt - }); - } - } - - // Multi-drag drop - if (dragStarted && this.isMultiDrag) { - folding = false; - // Do not "unfold" after around dragEl if reverted - if ((parentEl[expando].options.sort || parentEl !== rootEl) && multiDragElements.length > 1) { - var dragRect = getRect(dragEl$1), - multiDragIndex = index(dragEl$1, ':not(.' + this.options.selectedClass + ')'); - if (!initialFolding && options.animation) dragEl$1.thisAnimationDuration = null; - toSortable.captureAnimationState(); - if (!initialFolding) { - if (options.animation) { - dragEl$1.fromRect = dragRect; - multiDragElements.forEach(function (multiDragElement) { - multiDragElement.thisAnimationDuration = null; - if (multiDragElement !== dragEl$1) { - var rect = folding ? getRect(multiDragElement) : dragRect; - multiDragElement.fromRect = rect; - - // Prepare unfold animation - toSortable.addAnimationState({ - target: multiDragElement, - rect: rect - }); - } - }); - } - - // Multi drag elements are not necessarily removed from the DOM on drop, so to reinsert - // properly they must all be removed - removeMultiDragElements(); - multiDragElements.forEach(function (multiDragElement) { - if (children[multiDragIndex]) { - parentEl.insertBefore(multiDragElement, children[multiDragIndex]); - } else { - parentEl.appendChild(multiDragElement); - } - multiDragIndex++; - }); - - // If initial folding is done, the elements may have changed position because they are now - // unfolding around dragEl, even though dragEl may not have his index changed, so update event - // must be fired here as Sortable will not. - if (oldIndex === index(dragEl$1)) { - var update = false; - multiDragElements.forEach(function (multiDragElement) { - if (multiDragElement.sortableIndex !== index(multiDragElement)) { - update = true; - return; - } - }); - if (update) { - dispatchSortableEvent('update'); - dispatchSortableEvent('sort'); - } - } - } - - // Must be done after capturing individual rects (scroll bar) - multiDragElements.forEach(function (multiDragElement) { - unsetRect(multiDragElement); - }); - toSortable.animateAll(); - } - multiDragSortable = toSortable; - } - - // Remove clones if necessary - if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') { - multiDragClones.forEach(function (clone) { - clone.parentNode && clone.parentNode.removeChild(clone); - }); - } - }, - nullingGlobal: function nullingGlobal() { - this.isMultiDrag = dragStarted = false; - multiDragClones.length = 0; - }, - destroyGlobal: function destroyGlobal() { - this._deselectMultiDrag(); - off(document, 'pointerup', this._deselectMultiDrag); - off(document, 'mouseup', this._deselectMultiDrag); - off(document, 'touchend', this._deselectMultiDrag); - off(document, 'keydown', this._checkKeyDown); - off(document, 'keyup', this._checkKeyUp); - }, - _deselectMultiDrag: function _deselectMultiDrag(evt) { - if (typeof dragStarted !== "undefined" && dragStarted) return; - - // Only deselect if selection is in this sortable - if (multiDragSortable !== this.sortable) return; - - // Only deselect if target is not item in this sortable - if (evt && closest(evt.target, this.options.draggable, this.sortable.el, false)) return; - - // Only deselect if left click - if (evt && evt.button !== 0) return; - while (multiDragElements.length) { - var el = multiDragElements[0]; - toggleClass(el, this.options.selectedClass, false); - multiDragElements.shift(); - dispatchEvent({ - sortable: this.sortable, - rootEl: this.sortable.el, - name: 'deselect', - targetEl: el, - originalEvent: evt - }); - } - }, - _checkKeyDown: function _checkKeyDown(evt) { - if (evt.key === this.options.multiDragKey) { - this.multiDragKeyDown = true; - } - }, - _checkKeyUp: function _checkKeyUp(evt) { - if (evt.key === this.options.multiDragKey) { - this.multiDragKeyDown = false; - } - } - }; - return _extends(MultiDrag, { - // Static methods & properties - pluginName: 'multiDrag', - utils: { - /** - * Selects the provided multi-drag item - * @param {HTMLElement} el The element to be selected - */ - select: function select(el) { - var sortable = el.parentNode[expando]; - if (!sortable || !sortable.options.multiDrag || ~multiDragElements.indexOf(el)) return; - if (multiDragSortable && multiDragSortable !== sortable) { - multiDragSortable.multiDrag._deselectMultiDrag(); - multiDragSortable = sortable; - } - toggleClass(el, sortable.options.selectedClass, true); - multiDragElements.push(el); - }, - /** - * Deselects the provided multi-drag item - * @param {HTMLElement} el The element to be deselected - */ - deselect: function deselect(el) { - var sortable = el.parentNode[expando], - index = multiDragElements.indexOf(el); - if (!sortable || !sortable.options.multiDrag || !~index) return; - toggleClass(el, sortable.options.selectedClass, false); - multiDragElements.splice(index, 1); - } - }, - eventProperties: function eventProperties() { - var _this3 = this; - var oldIndicies = [], - newIndicies = []; - multiDragElements.forEach(function (multiDragElement) { - oldIndicies.push({ - multiDragElement: multiDragElement, - index: multiDragElement.sortableIndex - }); - - // multiDragElements will already be sorted if folding - var newIndex; - if (folding && multiDragElement !== dragEl$1) { - newIndex = -1; - } else if (folding) { - newIndex = index(multiDragElement, ':not(.' + _this3.options.selectedClass + ')'); - } else { - newIndex = index(multiDragElement); - } - newIndicies.push({ - multiDragElement: multiDragElement, - index: newIndex - }); - }); - return { - items: _toConsumableArray(multiDragElements), - clones: [].concat(multiDragClones), - oldIndicies: oldIndicies, - newIndicies: newIndicies - }; - }, - optionListeners: { - multiDragKey: function multiDragKey(key) { - key = key.toLowerCase(); - if (key === 'ctrl') { - key = 'Control'; - } else if (key.length > 1) { - key = key.charAt(0).toUpperCase() + key.substr(1); - } - return key; - } - } - }); - } - function insertMultiDragElements(clonesInserted, rootEl) { - multiDragElements.forEach(function (multiDragElement, i) { - var target = rootEl.children[multiDragElement.sortableIndex + (clonesInserted ? Number(i) : 0)]; - if (target) { - rootEl.insertBefore(multiDragElement, target); - } else { - rootEl.appendChild(multiDragElement); - } - }); - } - - /** - * Insert multi-drag clones - * @param {[Boolean]} elementsInserted Whether the multi-drag elements are inserted - * @param {HTMLElement} rootEl - */ - function insertMultiDragClones(elementsInserted, rootEl) { - multiDragClones.forEach(function (clone, i) { - var target = rootEl.children[clone.sortableIndex + (elementsInserted ? Number(i) : 0)]; - if (target) { - rootEl.insertBefore(clone, target); - } else { - rootEl.appendChild(clone); - } - }); - } - function removeMultiDragElements() { - multiDragElements.forEach(function (multiDragElement) { - if (multiDragElement === dragEl$1) return; - multiDragElement.parentNode && multiDragElement.parentNode.removeChild(multiDragElement); - }); - } - - Sortable.mount(new AutoScrollPlugin()); - Sortable.mount(Remove, Revert); - - Sortable.mount(new SwapPlugin()); - Sortable.mount(new MultiDragPlugin()); - - return Sortable; - -}))); diff --git a/amt/site/templates/header.html.j2 b/amt/site/templates/header.html.j2 index f8e39064..e8a9f64d 100644 --- a/amt/site/templates/header.html.j2 +++ b/amt/site/templates/header.html.j2 @@ -1,10 +1,10 @@
-
- +
+ {% trans %}Algorithm Management Toolkit{% endtrans %} ({{ version }})
-
-
+
+ -
+
{% trans %}Language{% endtrans %}: {% for available_translation in available_translations %} diff --git a/amt/site/templates/layouts/base.html.j2 b/amt/site/templates/layouts/base.html.j2.webpack similarity index 64% rename from amt/site/templates/layouts/base.html.j2 rename to amt/site/templates/layouts/base.html.j2.webpack index f45d9caa..8dc98d4f 100644 --- a/amt/site/templates/layouts/base.html.j2 +++ b/amt/site/templates/layouts/base.html.j2.webpack @@ -12,16 +12,20 @@ {% endblock %} {% block scripts %} - - - + <% for (const js of htmlWebpackPlugin.files.js) { %> + + <% } %> - + {% endblock %} {% block styles %} - - + + + <% for (const css of htmlWebpackPlugin.files.css) { %> + + <% } %> + {% endblock %} diff --git a/amt/site/templates/macros/render.html.j2 b/amt/site/templates/macros/render.html.j2 index b5b63b78..21398b9f 100644 --- a/amt/site/templates/macros/render.html.j2 +++ b/amt/site/templates/macros/render.html.j2 @@ -14,7 +14,7 @@ {% trans %}Unknown{% endtrans %} {% endif %}

-
+
{% if project is defined %} {% for task in tasks_service.get_tasks_for_project(project.id, status) %} {{ render_task_card_full(task) }} @@ -29,7 +29,7 @@ {% endmacro -%} {% macro render_task_card_full(task) -%} -
{{ render_task_card_content(task) }}
@@ -40,8 +40,9 @@

{{ task.title | truncate(100)}}

{{ task.description }}
{% if task.user_id %} -
- Assigned to Avatar +
+ Assigned to Avatar
{% endif %}
diff --git a/amt/site/templates/pages/index.html.j2 b/amt/site/templates/pages/index.html.j2 index 3ddfe82b..967d6659 100644 --- a/amt/site/templates/pages/index.html.j2 +++ b/amt/site/templates/pages/index.html.j2 @@ -26,7 +26,7 @@ -

+

{% if project is defined %} {{ project.name | default('Unknown', true) }} {% else %} diff --git a/amt/site/templates/projects/index.html.j2 b/amt/site/templates/projects/index.html.j2 index c4909e24..e1a5a7ba 100644 --- a/amt/site/templates/projects/index.html.j2 +++ b/amt/site/templates/projects/index.html.j2 @@ -1,7 +1,7 @@ {% extends 'layouts/base.html.j2' %} {% block content %} -

{% trans %}Projects{% endtrans %}

+

{% trans %}Projects{% endtrans %}