diff --git a/.dev_scripts/test_regression_txt2img_dream_v1_4.sh b/.dev_scripts/test_regression_txt2img_dream_v1_4.sh index 11cbf8f14b..9326d3c311 100644 --- a/.dev_scripts/test_regression_txt2img_dream_v1_4.sh +++ b/.dev_scripts/test_regression_txt2img_dream_v1_4.sh @@ -5,8 +5,7 @@ SAMPLES_DIR=${OUT_DIR} python scripts/dream.py \ --from_file ${PROMPT_FILE} \ --outdir ${OUT_DIR} \ - --sampler plms \ - --full_precision + --sampler plms # original output by CompVis/stable-diffusion IMAGE1=".dev_scripts/images/v1_4_astronaut_rides_horse_plms_step50_seed42.png" diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000..8a0ebc5069 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +* +!environment*.yml +!docker-build diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000..8d93c26b19 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,4 @@ +ldm/invoke/pngwriter.py @CapableWeb +ldm/invoke/server_legacy.py @CapableWeb +scripts/legacy_api.py @CapableWeb +tests/legacy_tests.sh @CapableWeb diff --git a/.github/ISSUE_TEMPLATE/BUG_REPORT.yml b/.github/ISSUE_TEMPLATE/BUG_REPORT.yml new file mode 100644 index 0000000000..82b2ab1de0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/BUG_REPORT.yml @@ -0,0 +1,102 @@ +name: 🐞 Bug Report + +description: File a bug report + +title: '[bug]: ' + +labels: ['bug'] + +# assignees: +# - moderator_bot +# - lstein + +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this Bug Report! + + - type: checkboxes + attributes: + label: Is there an existing issue for this? + description: | + Please use the [search function](https://github.com/invoke-ai/InvokeAI/issues?q=is%3Aissue+is%3Aopen+label%3Abug) + irst to see if an issue already exists for the bug you encountered. + options: + - label: I have searched the existing issues + required: true + + - type: markdown + attributes: + value: __Describe your environment__ + + - type: dropdown + id: os_dropdown + attributes: + label: OS + description: Which operating System did you use when the bug occured + multiple: false + options: + - 'Linux' + - 'Windows' + - 'macOS' + validations: + required: true + + - type: dropdown + id: gpu_dropdown + attributes: + label: GPU + description: Which kind of Graphic-Adapter is your System using + multiple: false + options: + - 'cuda' + - 'amd' + - 'mps' + - 'cpu' + validations: + required: true + + - type: input + id: vram + attributes: + label: VRAM + description: Size of the VRAM if known + placeholder: 8GB + validations: + required: false + + - type: textarea + id: what-happened + attributes: + label: What happened? + description: | + Briefly describe what happened, what you expected to happen and how to reproduce this bug. + placeholder: When using the webinterface and right-clicking on button X instead of the popup-menu there error Y appears + validations: + required: true + + - type: textarea + attributes: + label: Screenshots + description: If applicable, add screenshots to help explain your problem + placeholder: this is what the result looked like + validations: + required: false + + - type: textarea + attributes: + label: Additional context + description: Add any other context about the problem here + placeholder: Only happens when there is full moon and Friday the 13th on Christmas Eve 🎅🏻 + validations: + required: false + + - type: input + id: contact + attributes: + label: Contact Details + description: __OPTIONAL__ How can we get in touch with you if we need more info (besides this issue)? + placeholder: ex. email@example.com, discordname, twitter, ... + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yml b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yml new file mode 100644 index 0000000000..6fb80be593 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yml @@ -0,0 +1,56 @@ +name: Feature Request +description: Commit a idea or Request a new feature +title: '[enhancement]: ' +labels: ['enhancement'] +# assignees: +# - lstein +# - tildebyte +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this Feature request! + + - type: checkboxes + attributes: + label: Is there an existing issue for this? + description: | + Please make use of the [search function](https://github.com/invoke-ai/InvokeAI/labels/enhancement) + to see if a simmilar issue already exists for the feature you want to request + options: + - label: I have searched the existing issues + required: true + + - type: input + id: contact + attributes: + label: Contact Details + description: __OPTIONAL__ How could we get in touch with you if we need more info (besides this issue)? + placeholder: ex. email@example.com, discordname, twitter, ... + validations: + required: false + + - type: textarea + id: whatisexpected + attributes: + label: What should this feature add? + description: Please try to explain the functionality this feature should add + placeholder: | + Instead of one huge textfield, it would be nice to have forms for bug-reports, feature-requests, ... + Great benefits with automatic labeling, assigning and other functionalitys not available in that form + via old-fashioned markdown-templates. I would also love to see the use of a moderator bot 🤖 like + https://github.com/marketplace/actions/issue-moderator-with-commands to auto close old issues and other things + validations: + required: true + + - type: textarea + attributes: + label: Alternatives + description: Describe alternatives you've considered + placeholder: A clear and concise description of any alternative solutions or features you've considered. + + - type: textarea + attributes: + label: Aditional Content + description: Add any other context or screenshots about the feature request here. + placeholder: This is a Mockup of the design how I imagine it diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 5758867874..0000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve -title: '' -labels: '' -assignees: '' - ---- - -**Describe your environment** -- GPU: [cuda/amd/mps/cpu] -- VRAM: [if known] -- CPU arch: [x86/arm] -- OS: [Linux/Windows/macOS] -- Python: [Anaconda/miniconda/miniforge/pyenv/other (explain)] -- Branch: [if `git status` says anything other than "On branch main" paste it here] -- Commit: [run `git show` and paste the line that starts with "Merge" here] - -**Describe the bug** -A clear and concise description of what the bug is. - -**To Reproduce** -Steps to reproduce the behavior: -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Screenshots** -If applicable, add screenshots to help explain your problem. - -**Additional context** -Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000..306483bfaa --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,14 @@ +blank_issues_enabled: false +contact_links: + - name: Project-Documentation + url: https://invoke-ai.github.io/InvokeAI/ + about: Should be your first place to go when looking for manuals/FAQs regarding our InvokeAI Toolkit + - name: Discord + url: https://discord.gg/ZmtBAhwWhy + about: Our Discord Community could maybe help you out via live-chat + - name: GitHub Community Support + url: https://github.com/orgs/community/discussions + about: Please ask and answer questions regarding the GitHub Platform here. + - name: GitHub Security Bug Bounty + url: https://bounty.github.com/ + about: Please report security vulnerabilities of the GitHub Platform here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index bbcbbe7d61..0000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: '' -labels: '' -assignees: '' - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. diff --git a/.github/workflows/build-container.yml b/.github/workflows/build-container.yml new file mode 100644 index 0000000000..b9b7053aba --- /dev/null +++ b/.github/workflows/build-container.yml @@ -0,0 +1,48 @@ +# Building the Image without pushing to confirm it is still buildable +# confirum functionality would unfortunately need way more resources +name: build container image +on: + push: + branches: + - 'main' + - 'development' + +jobs: + docker: + strategy: + fail-fast: false + matrix: + arch: + - x86_64 + - aarch64 + include: + - arch: x86_64 + conda-env-file: environment.yml + - arch: aarch64 + conda-env-file: environment-linux-aarch64.yml + runs-on: ubuntu-latest + name: ${{ matrix.arch }} + steps: + - name: prepare docker-tag + env: + repository: ${{ github.repository }} + run: echo "dockertag=${repository,,}" >> $GITHUB_ENV + - name: Checkout + uses: actions/checkout@v3 + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + - name: Build container + uses: docker/build-push-action@v3 + with: + context: . + file: docker-build/Dockerfile + platforms: Linux/${{ matrix.arch }} + push: false + tags: ${{ env.dockertag }}:${{ matrix.arch }} + build-args: | + conda_env_file=${{ matrix.conda-env-file }} + conda_version=py39_4.12.0-Linux-${{ matrix.arch }} + invokeai_git=${{ github.repository }} + invokeai_branch=${{ github.ref_name }} diff --git a/.github/workflows/create-caches.yml b/.github/workflows/create-caches.yml index 951718af1b..946025d78b 100644 --- a/.github/workflows/create-caches.yml +++ b/.github/workflows/create-caches.yml @@ -1,26 +1,43 @@ name: Create Caches -on: - workflow_dispatch + +on: workflow_dispatch + jobs: - build: + os_matrix: strategy: matrix: - os: [ ubuntu-latest, macos-12 ] - name: Create Caches on ${{ matrix.os }} conda + os: [ubuntu-latest, macos-latest] + include: + - os: ubuntu-latest + environment-file: environment.yml + default-shell: bash -l {0} + - os: macos-latest + environment-file: environment-mac.yml + default-shell: bash -l {0} + name: Test invoke.py on ${{ matrix.os }} with conda runs-on: ${{ matrix.os }} + defaults: + run: + shell: ${{ matrix.default-shell }} steps: - - name: Set platform variables - id: vars - run: | - if [ "$RUNNER_OS" = "macOS" ]; then - echo "::set-output name=ENV_FILE::environment-mac.yaml" - echo "::set-output name=PYTHON_BIN::/usr/local/miniconda/envs/ldm/bin/python" - elif [ "$RUNNER_OS" = "Linux" ]; then - echo "::set-output name=ENV_FILE::environment.yaml" - echo "::set-output name=PYTHON_BIN::/usr/share/miniconda/envs/ldm/bin/python" - fi - name: Checkout sources uses: actions/checkout@v3 + + - name: setup miniconda + uses: conda-incubator/setup-miniconda@v2 + with: + auto-activate-base: false + auto-update-conda: false + miniconda-version: latest + + - name: set environment + run: | + [[ "$GITHUB_REF" == 'refs/heads/main' ]] \ + && echo "TEST_PROMPTS=tests/preflight_prompts.txt" >> $GITHUB_ENV \ + || echo "TEST_PROMPTS=tests/dev_prompts.txt" >> $GITHUB_ENV + echo "CONDA_ROOT=$CONDA" >> $GITHUB_ENV + echo "CONDA_ENV_NAME=invokeai" >> $GITHUB_ENV + - name: Use Cached Stable Diffusion v1.4 Model id: cache-sd-v1-4 uses: actions/cache@v3 @@ -29,42 +46,35 @@ jobs: with: path: models/ldm/stable-diffusion-v1/model.ckpt key: ${{ env.cache-name }} - restore-keys: | - ${{ env.cache-name }} + restore-keys: ${{ env.cache-name }} + - name: Download Stable Diffusion v1.4 Model if: ${{ steps.cache-sd-v1-4.outputs.cache-hit != 'true' }} run: | - if [ ! -e models/ldm/stable-diffusion-v1 ]; then - mkdir -p models/ldm/stable-diffusion-v1 - fi - if [ ! -e models/ldm/stable-diffusion-v1/model.ckpt ]; then - curl -o models/ldm/stable-diffusion-v1/model.ckpt ${{ secrets.SD_V1_4_URL }} - fi - - name: Use Cached Dependencies - id: cache-conda-env-ldm - uses: actions/cache@v3 - env: - cache-name: cache-conda-env-ldm + [[ -d models/ldm/stable-diffusion-v1 ]] \ + || mkdir -p models/ldm/stable-diffusion-v1 + [[ -r models/ldm/stable-diffusion-v1/model.ckpt ]] \ + || curl \ + -H "Authorization: Bearer ${{ secrets.HUGGINGFACE_TOKEN }}" \ + -o models/ldm/stable-diffusion-v1/model.ckpt \ + -L https://huggingface.co/CompVis/stable-diffusion-v-1-4-original/resolve/main/sd-v1-4.ckpt + + - name: Activate Conda Env + uses: conda-incubator/setup-miniconda@v2 with: - path: ~/.conda/envs/ldm - key: ${{ env.cache-name }} - restore-keys: | - ${{ env.cache-name }}-${{ runner.os }}-${{ hashFiles(steps.vars.outputs.ENV_FILE) }} - - name: Install Dependencies - if: ${{ steps.cache-conda-env-ldm.outputs.cache-hit != 'true' }} - run: | - conda env create -f ${{ steps.vars.outputs.ENV_FILE }} + activate-environment: ${{ env.CONDA_ENV_NAME }} + environment-file: ${{ matrix.environment-file }} + - name: Use Cached Huggingface and Torch models - id: cache-huggingface-torch + id: cache-hugginface-torch uses: actions/cache@v3 env: - cache-name: cache-huggingface-torch + cache-name: cache-hugginface-torch with: path: ~/.cache key: ${{ env.cache-name }} restore-keys: | ${{ env.cache-name }}-${{ hashFiles('scripts/preload_models.py') }} - - name: Download Huggingface and Torch models - if: ${{ steps.cache-huggingface-torch.outputs.cache-hit != 'true' }} - run: | - ${{ steps.vars.outputs.PYTHON_BIN }} scripts/preload_models.py + + - name: run preload_models.py + run: python scripts/preload_models.py diff --git a/.github/workflows/mkdocs-material.yml b/.github/workflows/mkdocs-material.yml new file mode 100644 index 0000000000..8d3c262e47 --- /dev/null +++ b/.github/workflows/mkdocs-material.yml @@ -0,0 +1,40 @@ +name: mkdocs-material +on: + push: + branches: + - 'main' + - 'development' + +jobs: + mkdocs-material: + runs-on: ubuntu-latest + steps: + - name: checkout sources + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: setup python + uses: actions/setup-python@v4 + with: + python-version: '3.10' + + - name: install requirements + run: | + python -m \ + pip install -r requirements-mkdocs.txt + + - name: confirm buildability + run: | + python -m \ + mkdocs build \ + --clean \ + --verbose + + - name: deploy to gh-pages + if: ${{ github.ref == 'refs/heads/main' }} + run: | + python -m \ + mkdocs gh-deploy \ + --clean \ + --force diff --git a/.github/workflows/test-dream-conda.yml b/.github/workflows/test-dream-conda.yml deleted file mode 100644 index 3bd9b24582..0000000000 --- a/.github/workflows/test-dream-conda.yml +++ /dev/null @@ -1,97 +0,0 @@ -name: Test Dream with Conda -on: - push: - branches: - - 'main' - - 'development' -jobs: - os_matrix: - strategy: - matrix: - os: [ ubuntu-latest, macos-12 ] - name: Test dream.py on ${{ matrix.os }} with conda - runs-on: ${{ matrix.os }} - steps: - - run: | - echo The PR was merged - - name: Set platform variables - id: vars - run: | - # Note, can't "activate" via github action; specifying the env's python has the same effect - if [ "$RUNNER_OS" = "macOS" ]; then - echo "::set-output name=ENV_FILE::environment-mac.yaml" - echo "::set-output name=PYTHON_BIN::/usr/local/miniconda/envs/ldm/bin/python" - elif [ "$RUNNER_OS" = "Linux" ]; then - echo "::set-output name=ENV_FILE::environment.yaml" - echo "::set-output name=PYTHON_BIN::/usr/share/miniconda/envs/ldm/bin/python" - fi - - name: Checkout sources - uses: actions/checkout@v3 - - name: Use Cached Stable Diffusion v1.4 Model - id: cache-sd-v1-4 - uses: actions/cache@v3 - env: - cache-name: cache-sd-v1-4 - with: - path: models/ldm/stable-diffusion-v1/model.ckpt - key: ${{ env.cache-name }} - restore-keys: | - ${{ env.cache-name }} - - name: Download Stable Diffusion v1.4 Model - if: ${{ steps.cache-sd-v1-4.outputs.cache-hit != 'true' }} - run: | - if [ ! -e models/ldm/stable-diffusion-v1 ]; then - mkdir -p models/ldm/stable-diffusion-v1 - fi - if [ ! -e models/ldm/stable-diffusion-v1/model.ckpt ]; then - curl -o models/ldm/stable-diffusion-v1/model.ckpt ${{ secrets.SD_V1_4_URL }} - fi - - name: Use Cached Dependencies - id: cache-conda-env-ldm - uses: actions/cache@v3 - env: - cache-name: cache-conda-env-ldm - with: - path: ~/.conda/envs/ldm - key: ${{ env.cache-name }} - restore-keys: | - ${{ env.cache-name }}-${{ runner.os }}-${{ hashFiles(steps.vars.outputs.ENV_FILE) }} - - name: Install Dependencies - if: ${{ steps.cache-conda-env-ldm.outputs.cache-hit != 'true' }} - run: | - conda env create -f ${{ steps.vars.outputs.ENV_FILE }} - - name: Use Cached Huggingface and Torch models - id: cache-hugginface-torch - uses: actions/cache@v3 - env: - cache-name: cache-hugginface-torch - with: - path: ~/.cache - key: ${{ env.cache-name }} - restore-keys: | - ${{ env.cache-name }}-${{ hashFiles('scripts/preload_models.py') }} - - name: Download Huggingface and Torch models - if: ${{ steps.cache-hugginface-torch.outputs.cache-hit != 'true' }} - run: | - ${{ steps.vars.outputs.PYTHON_BIN }} scripts/preload_models.py -# - name: Run tmate -# uses: mxschmitt/action-tmate@v3 -# timeout-minutes: 30 - - name: Run the tests - run: | - # Note, can't "activate" via github action; specifying the env's python has the same effect - if [ $(uname) = "Darwin" ]; then - export PYTORCH_ENABLE_MPS_FALLBACK=1 - fi - # Utterly hacky, but I don't know how else to do this - if [[ ${{ github.ref }} == 'refs/heads/master' ]]; then - time ${{ steps.vars.outputs.PYTHON_BIN }} scripts/dream.py --from_file tests/preflight_prompts.txt --full_precision - elif [[ ${{ github.ref }} == 'refs/heads/development' ]]; then - time ${{ steps.vars.outputs.PYTHON_BIN }} scripts/dream.py --from_file tests/dev_prompts.txt --full_precision - fi - mkdir -p outputs/img-samples - - name: Archive results - uses: actions/upload-artifact@v3 - with: - name: results - path: outputs/img-samples diff --git a/.github/workflows/test-invoke-conda.yml b/.github/workflows/test-invoke-conda.yml new file mode 100644 index 0000000000..a144303cc3 --- /dev/null +++ b/.github/workflows/test-invoke-conda.yml @@ -0,0 +1,123 @@ +name: Test invoke.py +on: + push: + branches: + - 'main' + - 'development' + - 'fix-gh-actions-fork' + pull_request: + branches: + - 'main' + - 'development' + +jobs: + matrix: + strategy: + fail-fast: false + matrix: + stable-diffusion-model: + # - 'https://huggingface.co/CompVis/stable-diffusion-v-1-4-original/resolve/main/sd-v1-4.ckpt' + - 'https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.ckpt' + os: + - ubuntu-latest + - macOS-12 + include: + - os: ubuntu-latest + environment-file: environment.yml + default-shell: bash -l {0} + - os: macOS-12 + environment-file: environment-mac.yml + default-shell: bash -l {0} + # - stable-diffusion-model: https://huggingface.co/CompVis/stable-diffusion-v-1-4-original/resolve/main/sd-v1-4.ckpt + # stable-diffusion-model-dl-path: models/ldm/stable-diffusion-v1/sd-v1-4.ckpt + # stable-diffusion-model-switch: stable-diffusion-1.4 + - stable-diffusion-model: https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.ckpt + stable-diffusion-model-dl-path: models/ldm/stable-diffusion-v1/v1-5-pruned-emaonly.ckpt + stable-diffusion-model-switch: stable-diffusion-1.5 + name: ${{ matrix.os }} with ${{ matrix.stable-diffusion-model-switch }} + runs-on: ${{ matrix.os }} + env: + CONDA_ENV_NAME: invokeai + defaults: + run: + shell: ${{ matrix.default-shell }} + steps: + - name: Checkout sources + id: checkout-sources + uses: actions/checkout@v3 + + - name: create models.yaml from example + run: cp configs/models.yaml.example configs/models.yaml + + - name: Use cached conda packages + id: use-cached-conda-packages + uses: actions/cache@v3 + with: + path: ~/conda_pkgs_dir + key: conda-pkgs-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles(matrix.environment-file) }} + + - name: Activate Conda Env + id: activate-conda-env + uses: conda-incubator/setup-miniconda@v2 + with: + activate-environment: ${{ env.CONDA_ENV_NAME }} + environment-file: ${{ matrix.environment-file }} + miniconda-version: latest + + - name: set test prompt to main branch validation + if: ${{ github.ref == 'refs/heads/main' }} + run: echo "TEST_PROMPTS=tests/preflight_prompts.txt" >> $GITHUB_ENV + + - name: set test prompt to development branch validation + if: ${{ github.ref == 'refs/heads/development' }} + run: echo "TEST_PROMPTS=tests/dev_prompts.txt" >> $GITHUB_ENV + + - name: set test prompt to Pull Request validation + if: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/development' }} + run: echo "TEST_PROMPTS=tests/validate_pr_prompt.txt" >> $GITHUB_ENV + + - name: Use Cached Stable Diffusion Model + id: cache-sd-model + uses: actions/cache@v3 + env: + cache-name: cache-${{ matrix.stable-diffusion-model-switch }} + with: + path: ${{ matrix.stable-diffusion-model-dl-path }} + key: ${{ env.cache-name }} + + - name: Download ${{ matrix.stable-diffusion-model-switch }} + id: download-stable-diffusion-model + if: ${{ steps.cache-sd-model.outputs.cache-hit != 'true' }} + run: | + [[ -d models/ldm/stable-diffusion-v1 ]] \ + || mkdir -p models/ldm/stable-diffusion-v1 + curl \ + -H "Authorization: Bearer ${{ secrets.HUGGINGFACE_TOKEN }}" \ + -o ${{ matrix.stable-diffusion-model-dl-path }} \ + -L ${{ matrix.stable-diffusion-model }} + + - name: run preload_models.py + id: run-preload-models + run: | + python scripts/preload_models.py \ + --no-interactive + + - name: Run the tests + id: run-tests + run: | + time python scripts/invoke.py \ + --model ${{ matrix.stable-diffusion-model-switch }} \ + --from_file ${{ env.TEST_PROMPTS }} + + - name: export conda env + id: export-conda-env + run: | + mkdir -p outputs/img-samples + conda env export --name ${{ env.CONDA_ENV_NAME }} > outputs/img-samples/environment-${{ runner.os }}-${{ runner.arch }}.yml + + - name: Archive results + id: archive-results + uses: actions/upload-artifact@v3 + with: + name: results_${{ matrix.os }}_${{ matrix.stable-diffusion-model-switch }} + path: outputs/img-samples diff --git a/.gitignore b/.gitignore index df1e55ee6d..54433c86dc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,14 @@ # ignore default image save location and model symbolic link outputs/ models/ldm/stable-diffusion-v1/model.ckpt +**/restoration/codeformer/weights + +# ignore user models config +configs/models.user.yaml +config/models.user.yml + +# ignore the Anaconda/Miniconda installer used while building Docker image +anaconda.sh # ignore a directory which serves as a place for initial images inputs/ @@ -77,9 +85,6 @@ db.sqlite3-journal instance/ .webassets-cache -# WebUI temp files: -img2img-tmp.png - # Scrapy stuff: .scrapy @@ -179,10 +184,28 @@ src **/__pycache__/ outputs -# Logs and associated folders +# Logs and associated folders # created from generated embeddings. logs testtube checkpoints # If it's a Mac .DS_Store + +# Let the frontend manage its own gitignore +!frontend/* + +# Scratch folder +.scratch/ +.vscode/ +gfpgan/ +models/ldm/stable-diffusion-v1/*.sha256 + +# GFPGAN model files +gfpgan/ + +# config file (will be created by installer) +configs/models.yaml + +# weights (will be created by installer) +models/ldm/stable-diffusion-v1/*.ckpt \ No newline at end of file diff --git a/.prettierrc.yaml b/.prettierrc.yaml new file mode 100644 index 0000000000..ce4b99a07b --- /dev/null +++ b/.prettierrc.yaml @@ -0,0 +1,13 @@ +endOfLine: lf +tabWidth: 2 +useTabs: false +singleQuote: true +quoteProps: as-needed +embeddedLanguageFormatting: auto +overrides: + - files: '*.md' + options: + proseWrap: always + printWidth: 80 + parser: markdown + cursorOffset: -1 diff --git a/LICENSE b/LICENSE index b01fca9fad..cb9631b9f6 100644 --- a/LICENSE +++ b/LICENSE @@ -1,17 +1,6 @@ MIT License -Copyright (c) 2022 Lincoln D. Stein (https://github.com/lstein) - -This software is derived from a fork of the source code available from -https://github.com/pesser/stable-diffusion and -https://github.com/CompViz/stable-diffusion. They carry the following -copyrights: - -Copyright (c) 2022 Machine Vision and Learning Group, LMU Munich -Copyright (c) 2022 Robin Rombach and Patrick Esser and contributors - -Please see individual source code files for copyright and authorship -attributions. +Copyright (c) 2022 InvokeAI Team Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 3da18a5d02..808e5e69fe 100644 --- a/README.md +++ b/README.md @@ -1,64 +1,95 @@ -

InvokeAI: A Stable Diffusion Toolkit

+
-

- -

+# InvokeAI: A Stable Diffusion Toolkit -

- last-commit - stars -
- issues - pull-requests -

+_Formerly known as lstein/stable-diffusion_ + +![project logo](docs/assets/logo.png) + +[![discord badge]][discord link] + +[![latest release badge]][latest release link] [![github stars badge]][github stars link] [![github forks badge]][github forks link] + +[![CI checks on main badge]][CI checks on main link] [![CI checks on dev badge]][CI checks on dev link] [![latest commit to dev badge]][latest commit to dev link] + +[![github open issues badge]][github open issues link] [![github open prs badge]][github open prs link] + +[CI checks on dev badge]: https://flat.badgen.net/github/checks/invoke-ai/InvokeAI/development?label=CI%20status%20on%20dev&cache=900&icon=github +[CI checks on dev link]: https://github.com/invoke-ai/InvokeAI/actions?query=branch%3Adevelopment +[CI checks on main badge]: https://flat.badgen.net/github/checks/invoke-ai/InvokeAI/main?label=CI%20status%20on%20main&cache=900&icon=github +[CI checks on main link]: https://github.com/invoke-ai/InvokeAI/actions/workflows/test-invoke-conda.yml +[discord badge]: https://flat.badgen.net/discord/members/ZmtBAhwWhy?icon=discord +[discord link]: https://discord.gg/ZmtBAhwWhy +[github forks badge]: https://flat.badgen.net/github/forks/invoke-ai/InvokeAI?icon=github +[github forks link]: https://useful-forks.github.io/?repo=invoke-ai%2FInvokeAI +[github open issues badge]: https://flat.badgen.net/github/open-issues/invoke-ai/InvokeAI?icon=github +[github open issues link]: https://github.com/invoke-ai/InvokeAI/issues?q=is%3Aissue+is%3Aopen +[github open prs badge]: https://flat.badgen.net/github/open-prs/invoke-ai/InvokeAI?icon=github +[github open prs link]: https://github.com/invoke-ai/InvokeAI/pulls?q=is%3Apr+is%3Aopen +[github stars badge]: https://flat.badgen.net/github/stars/invoke-ai/InvokeAI?icon=github +[github stars link]: https://github.com/invoke-ai/InvokeAI/stargazers +[latest commit to dev badge]: https://flat.badgen.net/github/last-commit/invoke-ai/InvokeAI/development?icon=github&color=yellow&label=last%20dev%20commit&cache=900 +[latest commit to dev link]: https://github.com/invoke-ai/InvokeAI/commits/development +[latest release badge]: https://flat.badgen.net/github/release/invoke-ai/InvokeAI/development?icon=github +[latest release link]: https://github.com/invoke-ai/InvokeAI/releases +
This is a fork of [CompVis/stable-diffusion](https://github.com/CompVis/stable-diffusion), the open source text-to-image generator. It provides a streamlined process with various new features and options to aid the image -generation process. It runs on Windows, Mac and Linux machines, -and runs on GPU cards with as little as 4 GB or RAM. +generation process. It runs on Windows, Mac and Linux machines, with +GPU cards with as little as 4 GB of RAM. It provides both a polished +Web interface (see below), and an easy-to-use command-line interface. + +**Quick links**: [Discord Server] [Documentation and Tutorials] [Code and Downloads] [Bug Reports] [Discussion, Ideas & Q&A] + +
+ _Note: This fork is rapidly evolving. Please use the -[Issues](https://github.com/invoke-ai/InvokeAI/issues) tab to -report bugs and make feature requests. Be sure to use the provided -templates. They will help aid diagnose issues faster._ +[Issues](https://github.com/invoke-ai/InvokeAI/issues) tab to report bugs and make feature +requests. Be sure to use the provided templates. They will help aid diagnose issues faster._ -_This repository was formally known as lstein/stable-diffusion_ - -# **Table of Contents** +## Table of Contents 1. [Installation](#installation) -2. [Major Features](#features) -3. [Changelog](#latest-changes) -4. [Troubleshooting](#troubleshooting) -5. [Contributing](#contributing) -6. [Support](#support) +2. [Hardware Requirements](#hardware-requirements) +3. [Features](#features) +4. [Latest Changes](#latest-changes) +5. [Troubleshooting](#troubleshooting) +6. [Contributing](#contributing) +7. [Contributors](#contributors) +8. [Support](#support) +9. [Further Reading](#further-reading) -# Installation +### Installation -This fork is supported across multiple platforms. You can find individual installation instructions below. +This fork is supported across multiple platforms. You can find individual installation instructions +below. -- ## [Linux](docs/installation/INSTALL_LINUX.md) -- ## [Windows](docs/installation/INSTALL_WINDOWS.md) -- ## [Macintosh](docs/installation/INSTALL_MAC.md) +- #### [Linux](https://invoke-ai.github.io/InvokeAI/installation/INSTALL_LINUX/) -## **Hardware Requirements** +- #### [Windows](https://invoke-ai.github.io/InvokeAI/installation/INSTALL_WINDOWS/) -**System** +- #### [Macintosh](https://invoke-ai.github.io/InvokeAI/installation/INSTALL_MAC/) + +### Hardware Requirements + +#### System You wil need one of the following: - An NVIDIA-based graphics card with 4 GB or more VRAM memory. - An Apple computer with an M1 chip. -**Memory** +#### Memory - At least 12 GB Main Memory RAM. -**Disk** +#### Disk -- At least 6 GB of free disk space for the machine learning model, Python, and all its dependencies. +- At least 12 GB of free disk space for the machine learning model, Python, and all its dependencies. **Note** @@ -67,99 +98,107 @@ run the dream script in full-precision mode as shown below. Similarly, specify full-precision mode on Apple M1 hardware. -To run in full-precision mode, start `dream.py` with the -`--full_precision` flag: +Precision is auto configured based on the device. If however you encounter +errors like 'expected type Float but found Half' or 'not implemented for Half' +you can try starting `invoke.py` with the `--precision=float32` flag: -``` -(ldm) ~/stable-diffusion$ python scripts/dream.py --full_precision +```bash +(invokeai) ~/InvokeAI$ python scripts/invoke.py --precision=float32 ``` -# Features +### Features -## **Major Features** +#### Major Features -- ## [Interactive Command Line Interface](docs/features/CLI.md) +- [Web Server](https://invoke-ai.github.io/InvokeAI/features/WEB/) +- [Interactive Command Line Interface](https://invoke-ai.github.io/InvokeAI/features/CLI/) +- [Image To Image](https://invoke-ai.github.io/InvokeAI/features/IMG2IMG/) +- [Inpainting Support](https://invoke-ai.github.io/InvokeAI/features/INPAINTING/) +- [Outpainting Support](https://invoke-ai.github.io/InvokeAI/features/OUTPAINTING/) +- [Upscaling, face-restoration and outpainting](https://invoke-ai.github.io/InvokeAI/features/POSTPROCESS/) +- [Reading Prompts From File](https://invoke-ai.github.io/InvokeAI/features/PROMPTS/#reading-prompts-from-a-file) +- [Prompt Blending](https://invoke-ai.github.io/InvokeAI/features/PROMPTS/#prompt-blending) +- [Thresholding and Perlin Noise Initialization Options](https://invoke-ai.github.io/InvokeAI/features/OTHER/#thresholding-and-perlin-noise-initialization-options) +- [Negative/Unconditioned Prompts](https://invoke-ai.github.io/InvokeAI/features/PROMPTS/#negative-and-unconditioned-prompts) +- [Variations](https://invoke-ai.github.io/InvokeAI/features/VARIATIONS/) +- [Personalizing Text-to-Image Generation](https://invoke-ai.github.io/InvokeAI/features/TEXTUAL_INVERSION/) +- [Simplified API for text to image generation](https://invoke-ai.github.io/InvokeAI/features/OTHER/#simplified-api) -- ## [Image To Image](docs/features/IMG2IMG.md) +#### Other Features -- ## [Inpainting Support](docs/features/INPAINTING.md) +- [Google Colab](https://invoke-ai.github.io/InvokeAI/features/OTHER/#google-colab) +- [Seamless Tiling](https://invoke-ai.github.io/InvokeAI/features/OTHER/#seamless-tiling) +- [Shortcut: Reusing Seeds](https://invoke-ai.github.io/InvokeAI/features/OTHER/#shortcuts-reusing-seeds) +- [Preload Models](https://invoke-ai.github.io/InvokeAI/features/OTHER/#preload-models) -- ## [GFPGAN and Real-ESRGAN Support](docs/features/UPSCALE.md) +### Latest Changes -- ## [Seamless Tiling](docs/features/OTHER.md#seamless-tiling) +- v2.0.1 (13 October 2022) + - fix noisy images at high step count when using k* samplers + - dream.py script now calls invoke.py module directly rather than + via a new python process (which could break the environment) -- ## [Google Colab](docs/features/OTHER.md#google-colab) +- v2.0.0 (9 October 2022) -- ## [Web Server](docs/features/WEB.md) + - `dream.py` script renamed `invoke.py`. A `dream.py` script wrapper remains + for backward compatibility. + - Completely new WebGUI - launch with `python3 scripts/invoke.py --web` + - Support for inpainting and outpainting + - img2img runs on all k* samplers + - Support for negative prompts + - Support for CodeFormer face reconstruction + - Support for Textual Inversion on Macintoshes + - Support in both WebGUI and CLI for post-processing of previously-generated images + using facial reconstruction, ESRGAN upscaling, outcropping (similar to DALL-E infinite canvas), + and "embiggen" upscaling. See the `!fix` command. + - New `--hires` option on `invoke>` line allows larger images to be created without duplicating elements, at the cost of some performance. + - New `--perlin` and `--threshold` options allow you to add and control variation + during image generation (see Thresholding and Perlin Noise Initialization + - Extensive metadata now written into PNG files, allowing reliable regeneration of images + and tweaking of previous settings. + - Command-line completion in `invoke.py` now works on Windows, Linux and Mac platforms. + - Improved command-line completion behavior. + New commands added: + - List command-line history with `!history` + - Search command-line history with `!search` + - Clear history with `!clear` + - Deprecated `--full_precision` / `-F`. Simply omit it and `invoke.py` will auto + configure. To switch away from auto use the new flag like `--precision=float32`. -- ## [Reading Prompts From File](docs/features/OTHER.md#reading-prompts-from-a-file) +For older changelogs, please visit the **[CHANGELOG](https://invoke-ai.github.io/InvokeAI/CHANGELOG#v114-11-september-2022)**. -- ## [Shortcut: Reusing Seeds](docs/features/OTHER.md#shortcuts-reusing-seeds) +### Troubleshooting -- ## [Weighted Prompts](docs/features/OTHER.md#weighted-prompts) - -- ## [Variations](docs/features/VARIATIONS.md) - -- ## [Personalizing Text-to-Image Generation](docs/features/TEXTUAL_INVERSION.md) - -- ## [Simplified API for text to image generation](docs/features/OTHER.md#simplified-api) - -## **Other Features** - -- ### [Creating Transparent Regions for Inpainting](docs/features/INPAINTING.md#creating-transparent-regions-for-inpainting) - -- ### [Preload Models](docs/features/OTHER.md#preload-models) - -# Latest Changes - -- v1.14 (11 September 2022) - - - Memory optimizations for small-RAM cards. 512x512 now possible on 4 GB GPUs. - - Full support for Apple hardware with M1 or M2 chips. - - Add "seamless mode" for circular tiling of image. Generates beautiful effects. ([prixt](https://github.com/prixt)). - - Inpainting support. - - Improved web server GUI. - - Lots of code and documentation cleanups. - -- v1.13 (3 September 2022 - - - Support image variations (see [VARIATIONS](docs/features/VARIATIONS.md) ([Kevin Gibbons](https://github.com/bakkot) and many contributors and reviewers) - - Supports a Google Colab notebook for a standalone server running on Google hardware [Arturo Mendivil](https://github.com/artmen1516) - - WebUI supports GFPGAN/ESRGAN facial reconstruction and upscaling [Kevin Gibbons](https://github.com/bakkot) - - WebUI supports incremental display of in-progress images during generation [Kevin Gibbons](https://github.com/bakkot) - - A new configuration file scheme that allows new models (including upcoming stable-diffusion-v1.5) - to be added without altering the code. ([David Wager](https://github.com/maddavid12)) - - Can specify --grid on dream.py command line as the default. - - Miscellaneous internal bug and stability fixes. - - Works on M1 Apple hardware. - - Multiple bug fixes. - -For older changelogs, please visit **[CHANGELOGS](docs/CHANGELOG.md)**. - -# Troubleshooting - -Please check out our **[Q&A](docs/help/TROUBLESHOOT.md)** to get solutions for common installation problems and other issues. +Please check out our **[Q&A](https://invoke-ai.github.io/InvokeAI/help/TROUBLESHOOT/#faq)** to get solutions for common installation +problems and other issues. # Contributing -Anyone who wishes to contribute to this project, whether documentation, features, bug fixes, code cleanup, testing, or code reviews, is very much encouraged to do so. If you are unfamiliar with -how to contribute to GitHub projects, here is a [Getting Started Guide](https://opensource.com/article/19/7/create-pull-request-github). +Anyone who wishes to contribute to this project, whether documentation, features, bug fixes, code +cleanup, testing, or code reviews, is very much encouraged to do so. If you are unfamiliar with how +to contribute to GitHub projects, here is a +[Getting Started Guide](https://opensource.com/article/19/7/create-pull-request-github). -A full set of contribution guidelines, along with templates, are in progress, but for now the most important thing is to **make your pull request against the "development" branch**, and not against "main". This will help keep public breakage to a minimum and will allow you to propose more radical changes. +A full set of contribution guidelines, along with templates, are in progress, but for now the most +important thing is to **make your pull request against the "development" branch**, and not against +"main". This will help keep public breakage to a minimum and will allow you to propose more radical +changes. -## **Contributors** +### Contributors -This fork is a combined effort of various people from across the world. [Check out the list of all these amazing people](docs/CONTRIBUTORS.md). We thank them for their time, hard work and effort. +This fork is a combined effort of various people from across the world. +[Check out the list of all these amazing people](https://invoke-ai.github.io/InvokeAI/other/CONTRIBUTORS/). We thank them for +their time, hard work and effort. -# Support +### Support -For support, -please use this repository's GitHub Issues tracking service. Feel free -to send me an email if you use and like the script. +For support, please use this repository's GitHub Issues tracking service. Feel free to send me an +email if you use and like the script. -Original portions of the software are Copyright (c) 2020 Lincoln D. Stein (https://github.com/lstein) +Original portions of the software are Copyright (c) 2020 +[Lincoln D. Stein](https://github.com/lstein) -# Further Reading +### Further Reading -Please see the original README for more information on this software -and underlying algorithm, located in the file [README-CompViz.md](docs/README-CompViz.md). +Please see the original README for more information on this software and underlying algorithm, +located in the file [README-CompViz.md](https://invoke-ai.github.io/InvokeAI/other/README-CompViz/). diff --git a/assets/caution.png b/assets/caution.png new file mode 100644 index 0000000000..91d43bf86e Binary files /dev/null and b/assets/caution.png differ diff --git a/backend/invoke_ai_web_server.py b/backend/invoke_ai_web_server.py new file mode 100644 index 0000000000..0ca94a6318 --- /dev/null +++ b/backend/invoke_ai_web_server.py @@ -0,0 +1,1264 @@ +import eventlet +import glob +import os +import shutil +import mimetypes +import traceback +import math +import io +import base64 + +from flask import Flask, redirect, send_from_directory +from flask_socketio import SocketIO +from PIL import Image +from uuid import uuid4 +from threading import Event + +from ldm.invoke.args import Args, APP_ID, APP_VERSION, calculate_init_img_hash +from ldm.invoke.pngwriter import PngWriter, retrieve_metadata +from ldm.invoke.prompt_parser import split_weighted_subprompts + +from backend.modules.parameters import parameters_to_command + + +# Loading Arguments +opt = Args() +args = opt.parse_args() + + +class InvokeAIWebServer: + def __init__(self, generate, gfpgan, codeformer, esrgan) -> None: + self.host = args.host + self.port = args.port + + self.generate = generate + self.gfpgan = gfpgan + self.codeformer = codeformer + self.esrgan = esrgan + + self.canceled = Event() + + def run(self): + self.setup_app() + self.setup_flask() + + def setup_flask(self): + # Fix missing mimetypes on Windows + mimetypes.add_type("application/javascript", ".js") + mimetypes.add_type("text/css", ".css") + # Socket IO + logger = True if args.web_verbose else False + engineio_logger = True if args.web_verbose else False + max_http_buffer_size = 10000000 + + socketio_args = { + "logger": logger, + "engineio_logger": engineio_logger, + "max_http_buffer_size": max_http_buffer_size, + "ping_interval": (50, 50), + "ping_timeout": 60, + } + + if opt.cors: + socketio_args["cors_allowed_origins"] = opt.cors + + self.app = Flask( + __name__, static_url_path="", static_folder="../frontend/dist/" + ) + + self.socketio = SocketIO(self.app, **socketio_args) + + # Keep Server Alive Route + @self.app.route("/flaskwebgui-keep-server-alive") + def keep_alive(): + return {"message": "Server Running"} + + # Outputs Route + self.app.config["OUTPUTS_FOLDER"] = os.path.abspath(args.outdir) + + @self.app.route("/outputs/") + def outputs(file_path): + return send_from_directory(self.app.config["OUTPUTS_FOLDER"], file_path) + + # Base Route + @self.app.route("/") + def serve(): + if args.web_develop: + return redirect("http://127.0.0.1:5173") + else: + return send_from_directory(self.app.static_folder, "index.html") + + self.load_socketio_listeners(self.socketio) + + if args.gui: + print(">> Launching Invoke AI GUI") + close_server_on_exit = True + if args.web_develop: + close_server_on_exit = False + try: + from flaskwebgui import FlaskUI + + FlaskUI( + app=self.app, + socketio=self.socketio, + start_server="flask-socketio", + host=self.host, + port=self.port, + width=1600, + height=1000, + idle_interval=10, + close_server_on_exit=close_server_on_exit, + ).run() + except KeyboardInterrupt: + import sys + + sys.exit(0) + else: + print(">> Started Invoke AI Web Server!") + if self.host == "0.0.0.0": + print( + f"Point your browser at http://localhost:{self.port} or use the host's DNS name or IP address." + ) + else: + print( + ">> Default host address now 127.0.0.1 (localhost). Use --host 0.0.0.0 to bind any address." + ) + print(f">> Point your browser at http://{self.host}:{self.port}") + self.socketio.run(app=self.app, host=self.host, port=self.port) + + def setup_app(self): + self.result_url = "outputs/" + self.init_image_url = "outputs/init-images/" + self.mask_image_url = "outputs/mask-images/" + self.intermediate_url = "outputs/intermediates/" + # location for "finished" images + self.result_path = args.outdir + # temporary path for intermediates + self.intermediate_path = os.path.join(self.result_path, "intermediates/") + # path for user-uploaded init images and masks + self.init_image_path = os.path.join(self.result_path, "init-images/") + self.mask_image_path = os.path.join(self.result_path, "mask-images/") + # txt log + self.log_path = os.path.join(self.result_path, "invoke_log.txt") + # make all output paths + [ + os.makedirs(path, exist_ok=True) + for path in [ + self.result_path, + self.intermediate_path, + self.init_image_path, + self.mask_image_path, + ] + ] + + def load_socketio_listeners(self, socketio): + @socketio.on("requestSystemConfig") + def handle_request_capabilities(): + print(f">> System config requested") + config = self.get_system_config() + socketio.emit("systemConfig", config) + + @socketio.on("requestModelChange") + def handle_set_model(model_name: str): + try: + print(f">> Model change requested: {model_name}") + model = self.generate.set_model(model_name) + model_list = self.generate.model_cache.list_models() + if model is None: + socketio.emit( + "modelChangeFailed", + {"model_name": model_name, "model_list": model_list}, + ) + else: + socketio.emit( + "modelChanged", + {"model_name": model_name, "model_list": model_list}, + ) + except Exception as e: + self.socketio.emit("error", {"message": (str(e))}) + print("\n") + + traceback.print_exc() + print("\n") + + @socketio.on("requestLatestImages") + def handle_request_latest_images(category, latest_mtime): + try: + base_path = ( + self.result_path if category == "result" else self.init_image_path + ) + + paths = [] + for ext in ("*.png", "*.jpg", "*.jpeg"): + paths.extend(glob.glob(os.path.join(base_path, ext))) + + image_paths = sorted( + paths, key=lambda x: os.path.getmtime(x), reverse=True + ) + + image_paths = list( + filter( + lambda x: os.path.getmtime(x) > latest_mtime, + image_paths, + ) + ) + + image_array = [] + + for path in image_paths: + if os.path.splitext(path)[1] == ".png": + metadata = retrieve_metadata(path) + sd_metadata = metadata["sd-metadata"] + else: + sd_metadata = {} + + (width, height) = Image.open(path).size + + image_array.append( + { + "url": self.get_url_from_image_path(path), + "mtime": os.path.getmtime(path), + "metadata": sd_metadata, + "width": width, + "height": height, + "category": category, + } + ) + + socketio.emit( + "galleryImages", + {"images": image_array, "category": category}, + ) + except Exception as e: + self.socketio.emit("error", {"message": (str(e))}) + print("\n") + + traceback.print_exc() + print("\n") + + @socketio.on("requestImages") + def handle_request_images(category, earliest_mtime=None): + try: + page_size = 50 + + base_path = ( + self.result_path if category == "result" else self.init_image_path + ) + + paths = [] + for ext in ("*.png", "*.jpg", "*.jpeg"): + paths.extend(glob.glob(os.path.join(base_path, ext))) + + image_paths = sorted( + paths, key=lambda x: os.path.getmtime(x), reverse=True + ) + + if earliest_mtime: + image_paths = list( + filter( + lambda x: os.path.getmtime(x) < earliest_mtime, + image_paths, + ) + ) + + areMoreImagesAvailable = len(image_paths) >= page_size + image_paths = image_paths[slice(0, page_size)] + + image_array = [] + for path in image_paths: + if os.path.splitext(path)[1] == ".png": + metadata = retrieve_metadata(path) + sd_metadata = metadata["sd-metadata"] + else: + sd_metadata = {} + + (width, height) = Image.open(path).size + + image_array.append( + { + "url": self.get_url_from_image_path(path), + "mtime": os.path.getmtime(path), + "metadata": sd_metadata, + "width": width, + "height": height, + "category": category, + } + ) + + socketio.emit( + "galleryImages", + { + "images": image_array, + "areMoreImagesAvailable": areMoreImagesAvailable, + "category": category, + }, + ) + except Exception as e: + self.socketio.emit("error", {"message": (str(e))}) + print("\n") + + traceback.print_exc() + print("\n") + + @socketio.on("generateImage") + def handle_generate_image_event( + generation_parameters, esrgan_parameters, facetool_parameters + ): + try: + # truncate long init_mask base64 if needed + if "init_mask" in generation_parameters: + printable_parameters = { + **generation_parameters, + "init_mask": generation_parameters["init_mask"][:20] + "...", + } + print( + f">> Image generation requested: {printable_parameters}\nESRGAN parameters: {esrgan_parameters}\nFacetool parameters: {facetool_parameters}" + ) + else: + print( + f">> Image generation requested: {generation_parameters}\nESRGAN parameters: {esrgan_parameters}\nFacetool parameters: {facetool_parameters}" + ) + self.generate_images( + generation_parameters, + esrgan_parameters, + facetool_parameters, + ) + except Exception as e: + self.socketio.emit("error", {"message": (str(e))}) + print("\n") + + traceback.print_exc() + print("\n") + + @socketio.on("runPostprocessing") + def handle_run_postprocessing(original_image, postprocessing_parameters): + try: + print( + f'>> Postprocessing requested for "{original_image["url"]}": {postprocessing_parameters}' + ) + + progress = Progress() + + socketio.emit("progressUpdate", progress.to_formatted_dict()) + eventlet.sleep(0) + + original_image_path = self.get_image_path_from_url( + original_image["url"] + ) + + image = Image.open(original_image_path) + + seed = ( + original_image["metadata"]["seed"] + if "metadata" in original_image + and "seed" in original_image["metadata"] + else "unknown_seed" + ) + + if postprocessing_parameters["type"] == "esrgan": + progress.set_current_status("Upscaling (ESRGAN)") + elif postprocessing_parameters["type"] == "gfpgan": + progress.set_current_status("Restoring Faces (GFPGAN)") + elif postprocessing_parameters["type"] == "codeformer": + progress.set_current_status("Restoring Faces (Codeformer)") + + socketio.emit("progressUpdate", progress.to_formatted_dict()) + eventlet.sleep(0) + + if postprocessing_parameters["type"] == "esrgan": + image = self.esrgan.process( + image=image, + upsampler_scale=postprocessing_parameters["upscale"][0], + strength=postprocessing_parameters["upscale"][1], + seed=seed, + ) + elif postprocessing_parameters["type"] == "gfpgan": + image = self.gfpgan.process( + image=image, + strength=postprocessing_parameters["facetool_strength"], + seed=seed, + ) + elif postprocessing_parameters["type"] == "codeformer": + image = self.codeformer.process( + image=image, + strength=postprocessing_parameters["facetool_strength"], + fidelity=postprocessing_parameters["codeformer_fidelity"], + seed=seed, + device="cpu" + if str(self.generate.device) == "mps" + else self.generate.device, + ) + else: + raise TypeError( + f'{postprocessing_parameters["type"]} is not a valid postprocessing type' + ) + + progress.set_current_status("Saving Image") + socketio.emit("progressUpdate", progress.to_formatted_dict()) + eventlet.sleep(0) + + postprocessing_parameters["seed"] = seed + metadata = self.parameters_to_post_processed_image_metadata( + parameters=postprocessing_parameters, + original_image_path=original_image_path, + ) + + command = parameters_to_command(postprocessing_parameters) + + (width, height) = image.size + + path = self.save_result_image( + image, + command, + metadata, + self.result_path, + postprocessing=postprocessing_parameters["type"], + ) + + self.write_log_message( + f'[Postprocessed] "{original_image_path}" > "{path}": {postprocessing_parameters}' + ) + + progress.mark_complete() + socketio.emit("progressUpdate", progress.to_formatted_dict()) + eventlet.sleep(0) + + socketio.emit( + "postprocessingResult", + { + "url": self.get_url_from_image_path(path), + "mtime": os.path.getmtime(path), + "metadata": metadata, + "width": width, + "height": height, + }, + ) + except Exception as e: + self.socketio.emit("error", {"message": (str(e))}) + print("\n") + + traceback.print_exc() + print("\n") + + @socketio.on("cancel") + def handle_cancel(): + print(f">> Cancel processing requested") + self.canceled.set() + + # TODO: I think this needs a safety mechanism. + @socketio.on("deleteImage") + def handle_delete_image(url, uuid, category): + try: + print(f'>> Delete requested "{url}"') + from send2trash import send2trash + + path = self.get_image_path_from_url(url) + print(path) + send2trash(path) + socketio.emit( + "imageDeleted", + {"url": url, "uuid": uuid, "category": category}, + ) + except Exception as e: + self.socketio.emit("error", {"message": (str(e))}) + print("\n") + + traceback.print_exc() + print("\n") + + # TODO: I think this needs a safety mechanism. + @socketio.on("uploadImage") + def handle_upload_image(bytes, name, destination): + try: + print(f'>> Image upload requested "{name}"') + file_path = self.save_file_unique_uuid_name( + bytes=bytes, name=name, path=self.init_image_path + ) + mtime = os.path.getmtime(file_path) + (width, height) = Image.open(file_path).size + print(file_path) + socketio.emit( + "imageUploaded", + { + "url": self.get_url_from_image_path(file_path), + "mtime": mtime, + "width": width, + "height": height, + "category": "user", + "destination": destination, + }, + ) + except Exception as e: + self.socketio.emit("error", {"message": (str(e))}) + print("\n") + + traceback.print_exc() + print("\n") + + # TODO: I think this needs a safety mechanism. + @socketio.on("uploadMaskImage") + def handle_upload_mask_image(bytes, name): + try: + print(f'>> Mask image upload requested "{name}"') + + file_path = self.save_file_unique_uuid_name( + bytes=bytes, name=name, path=self.mask_image_path + ) + + socketio.emit( + "maskImageUploaded", + { + "url": self.get_url_from_image_path(file_path), + }, + ) + except Exception as e: + self.socketio.emit("error", {"message": (str(e))}) + print("\n") + + traceback.print_exc() + print("\n") + + # App Functions + def get_system_config(self): + model_list = self.generate.model_cache.list_models() + return { + "model": "stable diffusion", + "model_id": args.model, + "model_hash": self.generate.model_hash, + "app_id": APP_ID, + "app_version": APP_VERSION, + "model_list": model_list, + } + + def generate_images( + self, generation_parameters, esrgan_parameters, facetool_parameters + ): + try: + self.canceled.clear() + + step_index = 1 + prior_variations = ( + generation_parameters["with_variations"] + if "with_variations" in generation_parameters + else [] + ) + + """ + TODO: + If a result image is used as an init image, and then deleted, we will want to be + able to use it as an init image in the future. Need to handle this case. + """ + + # We need to give absolute paths to the generator, stash the URLs for later + init_img_url = None + mask_img_url = None + + if "init_img" in generation_parameters: + init_img_url = generation_parameters["init_img"] + init_img_path = self.get_image_path_from_url(init_img_url) + generation_parameters["init_img"] = init_img_path + + # if 'init_mask' in generation_parameters: + # mask_img_url = generation_parameters['init_mask'] + # generation_parameters[ + # 'init_mask' + # ] = self.get_image_path_from_url( + # generation_parameters['init_mask'] + # ) + + if "init_mask" in generation_parameters: + # grab an Image of the init image + original_image = Image.open(init_img_path) + + # copy a region from it which we will inpaint + cropped_init_image = copy_image_from_bounding_box( + original_image, **generation_parameters["bounding_box"] + ) + generation_parameters["init_img"] = cropped_init_image + + if generation_parameters["is_mask_empty"]: + generation_parameters["init_mask"] = None + else: + # grab an Image of the mask + mask_image = Image.open( + io.BytesIO( + base64.decodebytes( + bytes(generation_parameters["init_mask"], "utf-8") + ) + ) + ) + generation_parameters["init_mask"] = mask_image + + totalSteps = self.calculate_real_steps( + steps=generation_parameters["steps"], + strength=generation_parameters["strength"] + if "strength" in generation_parameters + else None, + has_init_image="init_img" in generation_parameters, + ) + + progress = Progress(generation_parameters=generation_parameters) + + self.socketio.emit("progressUpdate", progress.to_formatted_dict()) + eventlet.sleep(0) + + def image_progress(sample, step): + if self.canceled.is_set(): + raise CanceledException + + nonlocal step_index + nonlocal generation_parameters + nonlocal progress + + progress.set_current_step(step + 1) + progress.set_current_status("Generating") + progress.set_current_status_has_steps(True) + + if ( + generation_parameters["progress_images"] + and step % generation_parameters['save_intermediates'] == 0 + and step < generation_parameters["steps"] - 1 + ): + image = self.generate.sample_to_image(sample) + metadata = self.parameters_to_generated_image_metadata( + generation_parameters + ) + command = parameters_to_command(generation_parameters) + + (width, height) = image.size + + path = self.save_result_image( + image, + command, + metadata, + self.intermediate_path, + step_index=step_index, + postprocessing=False, + ) + + step_index += 1 + self.socketio.emit( + "intermediateResult", + { + "url": self.get_url_from_image_path(path), + "mtime": os.path.getmtime(path), + "metadata": metadata, + "width": width, + "height": height, + }, + ) + + if generation_parameters["progress_latents"]: + image = self.generate.sample_to_lowres_estimated_image(sample) + (width, height) = image.size + width *= 8 + height *= 8 + buffered = io.BytesIO() + image.save(buffered, format="PNG") + img_base64 = "data:image/png;base64," + base64.b64encode( + buffered.getvalue() + ).decode("UTF-8") + self.socketio.emit( + "intermediateResult", + { + "url": img_base64, + "isBase64": True, + "mtime": 0, + "metadata": {}, + "width": width, + "height": height, + }, + ) + + self.socketio.emit("progressUpdate", progress.to_formatted_dict()) + eventlet.sleep(0) + + def image_done(image, seed, first_seed): + if self.canceled.is_set(): + raise CanceledException + + nonlocal generation_parameters + nonlocal esrgan_parameters + nonlocal facetool_parameters + nonlocal progress + + step_index = 1 + nonlocal prior_variations + + # paste the inpainting image back onto the original + if "init_mask" in generation_parameters: + image = paste_image_into_bounding_box( + Image.open(init_img_path), + image, + **generation_parameters["bounding_box"], + ) + + progress.set_current_status("Generation Complete") + + self.socketio.emit("progressUpdate", progress.to_formatted_dict()) + eventlet.sleep(0) + + all_parameters = generation_parameters + postprocessing = False + + if ( + "variation_amount" in all_parameters + and all_parameters["variation_amount"] > 0 + ): + first_seed = first_seed or seed + this_variation = [[seed, all_parameters["variation_amount"]]] + all_parameters["with_variations"] = ( + prior_variations + this_variation + ) + all_parameters["seed"] = first_seed + elif "with_variations" in all_parameters: + all_parameters["seed"] = first_seed + else: + all_parameters["seed"] = seed + + if self.canceled.is_set(): + raise CanceledException + + if esrgan_parameters: + progress.set_current_status("Upscaling") + progress.set_current_status_has_steps(False) + self.socketio.emit("progressUpdate", progress.to_formatted_dict()) + eventlet.sleep(0) + + image = self.esrgan.process( + image=image, + upsampler_scale=esrgan_parameters["level"], + strength=esrgan_parameters["strength"], + seed=seed, + ) + + postprocessing = True + all_parameters["upscale"] = [ + esrgan_parameters["level"], + esrgan_parameters["strength"], + ] + + if self.canceled.is_set(): + raise CanceledException + + if facetool_parameters: + if facetool_parameters["type"] == "gfpgan": + progress.set_current_status("Restoring Faces (GFPGAN)") + elif facetool_parameters["type"] == "codeformer": + progress.set_current_status("Restoring Faces (Codeformer)") + + progress.set_current_status_has_steps(False) + self.socketio.emit("progressUpdate", progress.to_formatted_dict()) + eventlet.sleep(0) + + if facetool_parameters["type"] == "gfpgan": + image = self.gfpgan.process( + image=image, + strength=facetool_parameters["strength"], + seed=seed, + ) + elif facetool_parameters["type"] == "codeformer": + image = self.codeformer.process( + image=image, + strength=facetool_parameters["strength"], + fidelity=facetool_parameters["codeformer_fidelity"], + seed=seed, + device="cpu" + if str(self.generate.device) == "mps" + else self.generate.device, + ) + all_parameters["codeformer_fidelity"] = facetool_parameters[ + "codeformer_fidelity" + ] + + postprocessing = True + all_parameters["facetool_strength"] = facetool_parameters[ + "strength" + ] + all_parameters["facetool_type"] = facetool_parameters["type"] + + progress.set_current_status("Saving Image") + self.socketio.emit("progressUpdate", progress.to_formatted_dict()) + eventlet.sleep(0) + + # restore the stashed URLS and discard the paths, we are about to send the result to client + if "init_img" in all_parameters: + all_parameters["init_img"] = init_img_url + + if "init_mask" in all_parameters: + all_parameters["init_mask"] = "" # TODO: store the mask in metadata + + metadata = self.parameters_to_generated_image_metadata(all_parameters) + + command = parameters_to_command(all_parameters) + + (width, height) = image.size + + path = self.save_result_image( + image, + command, + metadata, + self.result_path, + postprocessing=postprocessing, + ) + + print(f'>> Image generated: "{path}"') + self.write_log_message(f'[Generated] "{path}": {command}') + + if progress.total_iterations > progress.current_iteration: + progress.set_current_step(1) + progress.set_current_status("Iteration complete") + progress.set_current_status_has_steps(False) + else: + progress.mark_complete() + + self.socketio.emit("progressUpdate", progress.to_formatted_dict()) + eventlet.sleep(0) + + self.socketio.emit( + "generationResult", + { + "url": self.get_url_from_image_path(path), + "mtime": os.path.getmtime(path), + "metadata": metadata, + "width": width, + "height": height, + }, + ) + eventlet.sleep(0) + + progress.set_current_iteration(progress.current_iteration + 1) + + self.generate.prompt2image( + **generation_parameters, + step_callback=image_progress, + image_callback=image_done, + ) + + except KeyboardInterrupt: + self.socketio.emit("processingCanceled") + raise + except CanceledException: + self.socketio.emit("processingCanceled") + pass + except Exception as e: + print(e) + self.socketio.emit("error", {"message": (str(e))}) + print("\n") + + traceback.print_exc() + print("\n") + + def parameters_to_generated_image_metadata(self, parameters): + try: + # top-level metadata minus `image` or `images` + metadata = self.get_system_config() + # remove any image keys not mentioned in RFC #266 + rfc266_img_fields = [ + "type", + "postprocessing", + "sampler", + "prompt", + "seed", + "variations", + "steps", + "cfg_scale", + "threshold", + "perlin", + "step_number", + "width", + "height", + "extra", + "seamless", + "hires_fix", + ] + + rfc_dict = {} + + for item in parameters.items(): + key, value = item + if key in rfc266_img_fields: + rfc_dict[key] = value + + postprocessing = [] + + # 'postprocessing' is either null or an + if "facetool_strength" in parameters: + facetool_parameters = { + "type": str(parameters["facetool_type"]), + "strength": float(parameters["facetool_strength"]), + } + + if parameters["facetool_type"] == "codeformer": + facetool_parameters["fidelity"] = float( + parameters["codeformer_fidelity"] + ) + + postprocessing.append(facetool_parameters) + + if "upscale" in parameters: + postprocessing.append( + { + "type": "esrgan", + "scale": int(parameters["upscale"][0]), + "strength": float(parameters["upscale"][1]), + } + ) + + rfc_dict["postprocessing"] = ( + postprocessing if len(postprocessing) > 0 else None + ) + + # semantic drift + rfc_dict["sampler"] = parameters["sampler_name"] + + # display weighted subprompts (liable to change) + subprompts = split_weighted_subprompts( + parameters["prompt"], skip_normalize=True + ) + subprompts = [{"prompt": x[0], "weight": x[1]} for x in subprompts] + rfc_dict["prompt"] = subprompts + + # 'variations' should always exist and be an array, empty or consisting of {'seed': seed, 'weight': weight} pairs + variations = [] + + if "with_variations" in parameters: + variations = [ + {"seed": x[0], "weight": x[1]} + for x in parameters["with_variations"] + ] + + rfc_dict["variations"] = variations + + if "init_img" in parameters: + rfc_dict["type"] = "img2img" + rfc_dict["strength"] = parameters["strength"] + rfc_dict["fit"] = parameters["fit"] # TODO: Noncompliant + rfc_dict["orig_hash"] = calculate_init_img_hash( + self.get_image_path_from_url(parameters["init_img"]) + ) + rfc_dict["init_image_path"] = parameters[ + "init_img" + ] # TODO: Noncompliant + # if 'init_mask' in parameters: + # rfc_dict['mask_hash'] = calculate_init_img_hash( + # self.get_image_path_from_url(parameters['init_mask']) + # ) # TODO: Noncompliant + # rfc_dict['mask_image_path'] = parameters[ + # 'init_mask' + # ] # TODO: Noncompliant + else: + rfc_dict["type"] = "txt2img" + + metadata["image"] = rfc_dict + + return metadata + + except Exception as e: + self.socketio.emit("error", {"message": (str(e))}) + print("\n") + + traceback.print_exc() + print("\n") + + def parameters_to_post_processed_image_metadata( + self, parameters, original_image_path + ): + try: + current_metadata = retrieve_metadata(original_image_path)["sd-metadata"] + postprocessing_metadata = {} + + """ + if we don't have an original image metadata to reconstruct, + need to record the original image and its hash + """ + if "image" not in current_metadata: + current_metadata["image"] = {} + + orig_hash = calculate_init_img_hash( + self.get_image_path_from_url(original_image_path) + ) + + postprocessing_metadata["orig_path"] = (original_image_path,) + postprocessing_metadata["orig_hash"] = orig_hash + + if parameters["type"] == "esrgan": + postprocessing_metadata["type"] = "esrgan" + postprocessing_metadata["scale"] = parameters["upscale"][0] + postprocessing_metadata["strength"] = parameters["upscale"][1] + elif parameters["type"] == "gfpgan": + postprocessing_metadata["type"] = "gfpgan" + postprocessing_metadata["strength"] = parameters["facetool_strength"] + elif parameters["type"] == "codeformer": + postprocessing_metadata["type"] = "codeformer" + postprocessing_metadata["strength"] = parameters["facetool_strength"] + postprocessing_metadata["fidelity"] = parameters["codeformer_fidelity"] + + else: + raise TypeError(f"Invalid type: {parameters['type']}") + + if "postprocessing" in current_metadata["image"] and isinstance( + current_metadata["image"]["postprocessing"], list + ): + current_metadata["image"]["postprocessing"].append( + postprocessing_metadata + ) + else: + current_metadata["image"]["postprocessing"] = [postprocessing_metadata] + + return current_metadata + + except Exception as e: + self.socketio.emit("error", {"message": (str(e))}) + print("\n") + + traceback.print_exc() + print("\n") + + def save_result_image( + self, + image, + command, + metadata, + output_dir, + step_index=None, + postprocessing=False, + ): + try: + pngwriter = PngWriter(output_dir) + + number_prefix = pngwriter.unique_prefix() + + uuid = uuid4().hex + truncated_uuid = uuid[:8] + + seed = "unknown_seed" + + if "image" in metadata: + if "seed" in metadata["image"]: + seed = metadata["image"]["seed"] + + filename = f"{number_prefix}.{truncated_uuid}.{seed}" + + if step_index: + filename += f".{step_index}" + if postprocessing: + filename += f".postprocessed" + + filename += ".png" + + path = pngwriter.save_image_and_prompt_to_png( + image=image, + dream_prompt=command, + metadata=metadata, + name=filename, + ) + + return os.path.abspath(path) + + except Exception as e: + self.socketio.emit("error", {"message": (str(e))}) + print("\n") + + traceback.print_exc() + print("\n") + + def make_unique_init_image_filename(self, name): + try: + uuid = uuid4().hex + split = os.path.splitext(name) + name = f"{split[0]}.{uuid}{split[1]}" + return name + except Exception as e: + self.socketio.emit("error", {"message": (str(e))}) + print("\n") + + traceback.print_exc() + print("\n") + + def calculate_real_steps(self, steps, strength, has_init_image): + import math + + return math.floor(strength * steps) if has_init_image else steps + + def write_log_message(self, message): + """Logs the filename and parameters used to generate or process that image to log file""" + try: + message = f"{message}\n" + with open(self.log_path, "a", encoding="utf-8") as file: + file.writelines(message) + + except Exception as e: + self.socketio.emit("error", {"message": (str(e))}) + print("\n") + + traceback.print_exc() + print("\n") + + def get_image_path_from_url(self, url): + """Given a url to an image used by the client, returns the absolute file path to that image""" + try: + if "init-images" in url: + return os.path.abspath( + os.path.join(self.init_image_path, os.path.basename(url)) + ) + elif "mask-images" in url: + return os.path.abspath( + os.path.join(self.mask_image_path, os.path.basename(url)) + ) + elif "intermediates" in url: + return os.path.abspath( + os.path.join(self.intermediate_path, os.path.basename(url)) + ) + else: + return os.path.abspath( + os.path.join(self.result_path, os.path.basename(url)) + ) + except Exception as e: + self.socketio.emit("error", {"message": (str(e))}) + print("\n") + + traceback.print_exc() + print("\n") + + def get_url_from_image_path(self, path): + """Given an absolute file path to an image, returns the URL that the client can use to load the image""" + try: + if "init-images" in path: + return os.path.join(self.init_image_url, os.path.basename(path)) + elif "mask-images" in path: + return os.path.join(self.mask_image_url, os.path.basename(path)) + elif "intermediates" in path: + return os.path.join(self.intermediate_url, os.path.basename(path)) + else: + return os.path.join(self.result_url, os.path.basename(path)) + except Exception as e: + self.socketio.emit("error", {"message": (str(e))}) + print("\n") + + traceback.print_exc() + print("\n") + + def save_file_unique_uuid_name(self, bytes, name, path): + try: + uuid = uuid4().hex + truncated_uuid = uuid[:8] + + split = os.path.splitext(name) + name = f"{split[0]}.{truncated_uuid}{split[1]}" + + file_path = os.path.join(path, name) + + os.makedirs(os.path.dirname(file_path), exist_ok=True) + + newFile = open(file_path, "wb") + newFile.write(bytes) + + return file_path + except Exception as e: + self.socketio.emit("error", {"message": (str(e))}) + print("\n") + + traceback.print_exc() + print("\n") + + +class Progress: + def __init__(self, generation_parameters=None): + self.current_step = 1 + self.total_steps = ( + self._calculate_real_steps( + steps=generation_parameters["steps"], + strength=generation_parameters["strength"] + if "strength" in generation_parameters + else None, + has_init_image="init_img" in generation_parameters, + ) + if generation_parameters + else 1 + ) + self.current_iteration = 1 + self.total_iterations = ( + generation_parameters["iterations"] if generation_parameters else 1 + ) + self.current_status = "Preparing" + self.is_processing = True + self.current_status_has_steps = False + self.has_error = False + + def set_current_step(self, current_step): + self.current_step = current_step + + def set_total_steps(self, total_steps): + self.total_steps = total_steps + + def set_current_iteration(self, current_iteration): + self.current_iteration = current_iteration + + def set_total_iterations(self, total_iterations): + self.total_iterations = total_iterations + + def set_current_status(self, current_status): + self.current_status = current_status + + def set_is_processing(self, is_processing): + self.is_processing = is_processing + + def set_current_status_has_steps(self, current_status_has_steps): + self.current_status_has_steps = current_status_has_steps + + def set_has_error(self, has_error): + self.has_error = has_error + + def mark_complete(self): + self.current_status = "Processing Complete" + self.current_step = 0 + self.total_steps = 0 + self.current_iteration = 0 + self.total_iterations = 0 + self.is_processing = False + + def to_formatted_dict( + self, + ): + return { + "currentStep": self.current_step, + "totalSteps": self.total_steps, + "currentIteration": self.current_iteration, + "totalIterations": self.total_iterations, + "currentStatus": self.current_status, + "isProcessing": self.is_processing, + "currentStatusHasSteps": self.current_status_has_steps, + "hasError": self.has_error, + } + + def _calculate_real_steps(self, steps, strength, has_init_image): + return math.floor(strength * steps) if has_init_image else steps + + +class CanceledException(Exception): + pass + + +""" +Crops an image to a bounding box. +""" + + +def copy_image_from_bounding_box(image, x, y, width, height): + with image as im: + bounds = (x, y, x + width, y + height) + im_cropped = im.crop(bounds) + return im_cropped + + +""" +Pastes an image onto another with a bounding box. +""" + + +def paste_image_into_bounding_box(recipient_image, donor_image, x, y, width, height): + with recipient_image as im: + bounds = (x, y, x + width, y + height) + im.paste(donor_image, bounds) + return recipient_image diff --git a/backend/modules/create_cmd_parser.py b/backend/modules/create_cmd_parser.py new file mode 100644 index 0000000000..919caeda91 --- /dev/null +++ b/backend/modules/create_cmd_parser.py @@ -0,0 +1,55 @@ +import argparse +import os +from ldm.invoke.args import PRECISION_CHOICES + + +def create_cmd_parser(): + parser = argparse.ArgumentParser(description="InvokeAI web UI") + parser.add_argument( + "--host", + type=str, + help="The host to serve on", + default="localhost", + ) + parser.add_argument("--port", type=int, help="The port to serve on", default=9090) + parser.add_argument( + "--cors", + nargs="*", + type=str, + help="Additional allowed origins, comma-separated", + ) + parser.add_argument( + "--embedding_path", + type=str, + help="Path to a pre-trained embedding manager checkpoint - can only be set on command line", + ) + # TODO: Can't get flask to serve images from any dir (saving to the dir does work when specified) + # parser.add_argument( + # "--output_dir", + # default="outputs/", + # type=str, + # help="Directory for output images", + # ) + parser.add_argument( + "-v", + "--verbose", + action="store_true", + help="Enables verbose logging", + ) + parser.add_argument( + "--precision", + dest="precision", + type=str, + choices=PRECISION_CHOICES, + metavar="PRECISION", + help=f'Set model precision. Defaults to auto selected based on device. Options: {", ".join(PRECISION_CHOICES)}', + default="auto", + ) + parser.add_argument( + '--free_gpu_mem', + dest='free_gpu_mem', + action='store_true', + help='Force free gpu memory before final decoding', + ) + + return parser diff --git a/backend/modules/parameters.py b/backend/modules/parameters.py new file mode 100644 index 0000000000..f3079e0497 --- /dev/null +++ b/backend/modules/parameters.py @@ -0,0 +1,69 @@ +from backend.modules.parse_seed_weights import parse_seed_weights +import argparse + +SAMPLER_CHOICES = [ + "ddim", + "k_dpm_2_a", + "k_dpm_2", + "k_euler_a", + "k_euler", + "k_heun", + "k_lms", + "plms", +] + + +def parameters_to_command(params): + """ + Converts dict of parameters into a `invoke.py` REPL command. + """ + + switches = list() + + if "prompt" in params: + switches.append(f'"{params["prompt"]}"') + if "steps" in params: + switches.append(f'-s {params["steps"]}') + if "seed" in params: + switches.append(f'-S {params["seed"]}') + if "width" in params: + switches.append(f'-W {params["width"]}') + if "height" in params: + switches.append(f'-H {params["height"]}') + if "cfg_scale" in params: + switches.append(f'-C {params["cfg_scale"]}') + if "sampler_name" in params: + switches.append(f'-A {params["sampler_name"]}') + if "seamless" in params and params["seamless"] == True: + switches.append(f"--seamless") + if "hires_fix" in params and params["hires_fix"] == True: + switches.append(f"--hires") + if "init_img" in params and len(params["init_img"]) > 0: + switches.append(f'-I {params["init_img"]}') + if "init_mask" in params and len(params["init_mask"]) > 0: + switches.append(f'-M {params["init_mask"]}') + if "init_color" in params and len(params["init_color"]) > 0: + switches.append(f'--init_color {params["init_color"]}') + if "strength" in params and "init_img" in params: + switches.append(f'-f {params["strength"]}') + if "fit" in params and params["fit"] == True: + switches.append(f"--fit") + if "facetool" in params: + switches.append(f'-ft {params["facetool"]}') + if "facetool_strength" in params and params["facetool_strength"]: + switches.append(f'-G {params["facetool_strength"]}') + elif "gfpgan_strength" in params and params["gfpgan_strength"]: + switches.append(f'-G {params["gfpgan_strength"]}') + if "codeformer_fidelity" in params: + switches.append(f'-cf {params["codeformer_fidelity"]}') + if "upscale" in params and params["upscale"]: + switches.append(f'-U {params["upscale"][0]} {params["upscale"][1]}') + if "variation_amount" in params and params["variation_amount"] > 0: + switches.append(f'-v {params["variation_amount"]}') + if "with_variations" in params: + seed_weight_pairs = ",".join( + f"{seed}:{weight}" for seed, weight in params["with_variations"] + ) + switches.append(f"-V {seed_weight_pairs}") + + return " ".join(switches) diff --git a/backend/modules/parse_seed_weights.py b/backend/modules/parse_seed_weights.py new file mode 100644 index 0000000000..7e15d4e166 --- /dev/null +++ b/backend/modules/parse_seed_weights.py @@ -0,0 +1,47 @@ +def parse_seed_weights(seed_weights): + """ + Accepts seed weights as string in "12345:0.1,23456:0.2,3456:0.3" format + Validates them + If valid: returns as [[12345, 0.1], [23456, 0.2], [3456, 0.3]] + If invalid: returns False + """ + + # Must be a string + if not isinstance(seed_weights, str): + return False + # String must not be empty + if len(seed_weights) == 0: + return False + + pairs = [] + + for pair in seed_weights.split(","): + split_values = pair.split(":") + + # Seed and weight are required + if len(split_values) != 2: + return False + + if len(split_values[0]) == 0 or len(split_values[1]) == 1: + return False + + # Try casting the seed to int and weight to float + try: + seed = int(split_values[0]) + weight = float(split_values[1]) + except ValueError: + return False + + # Seed must be 0 or above + if not seed >= 0: + return False + + # Weight must be between 0 and 1 + if not (weight >= 0 and weight <= 1): + return False + + # This pair is valid + pairs.append([seed, weight]) + + # All pairs are valid + return pairs diff --git a/configs/autoencoder/autoencoder_kl_16x16x16.yaml b/configs/autoencoder/autoencoder_kl_16x16x16.yaml deleted file mode 100644 index 5f1d10ec75..0000000000 --- a/configs/autoencoder/autoencoder_kl_16x16x16.yaml +++ /dev/null @@ -1,54 +0,0 @@ -model: - base_learning_rate: 4.5e-6 - target: ldm.models.autoencoder.AutoencoderKL - params: - monitor: "val/rec_loss" - embed_dim: 16 - lossconfig: - target: ldm.modules.losses.LPIPSWithDiscriminator - params: - disc_start: 50001 - kl_weight: 0.000001 - disc_weight: 0.5 - - ddconfig: - double_z: True - z_channels: 16 - resolution: 256 - in_channels: 3 - out_ch: 3 - ch: 128 - ch_mult: [ 1,1,2,2,4] # num_down = len(ch_mult)-1 - num_res_blocks: 2 - attn_resolutions: [16] - dropout: 0.0 - - -data: - target: main.DataModuleFromConfig - params: - batch_size: 12 - wrap: True - train: - target: ldm.data.imagenet.ImageNetSRTrain - params: - size: 256 - degradation: pil_nearest - validation: - target: ldm.data.imagenet.ImageNetSRValidation - params: - size: 256 - degradation: pil_nearest - -lightning: - callbacks: - image_logger: - target: main.ImageLogger - params: - batch_frequency: 1000 - max_images: 8 - increase_log_steps: True - - trainer: - benchmark: True - accumulate_grad_batches: 2 diff --git a/configs/autoencoder/autoencoder_kl_32x32x4.yaml b/configs/autoencoder/autoencoder_kl_32x32x4.yaml deleted file mode 100644 index ab8b36fe6e..0000000000 --- a/configs/autoencoder/autoencoder_kl_32x32x4.yaml +++ /dev/null @@ -1,53 +0,0 @@ -model: - base_learning_rate: 4.5e-6 - target: ldm.models.autoencoder.AutoencoderKL - params: - monitor: "val/rec_loss" - embed_dim: 4 - lossconfig: - target: ldm.modules.losses.LPIPSWithDiscriminator - params: - disc_start: 50001 - kl_weight: 0.000001 - disc_weight: 0.5 - - ddconfig: - double_z: True - z_channels: 4 - resolution: 256 - in_channels: 3 - out_ch: 3 - ch: 128 - ch_mult: [ 1,2,4,4 ] # num_down = len(ch_mult)-1 - num_res_blocks: 2 - attn_resolutions: [ ] - dropout: 0.0 - -data: - target: main.DataModuleFromConfig - params: - batch_size: 12 - wrap: True - train: - target: ldm.data.imagenet.ImageNetSRTrain - params: - size: 256 - degradation: pil_nearest - validation: - target: ldm.data.imagenet.ImageNetSRValidation - params: - size: 256 - degradation: pil_nearest - -lightning: - callbacks: - image_logger: - target: main.ImageLogger - params: - batch_frequency: 1000 - max_images: 8 - increase_log_steps: True - - trainer: - benchmark: True - accumulate_grad_batches: 2 diff --git a/configs/autoencoder/autoencoder_kl_64x64x3.yaml b/configs/autoencoder/autoencoder_kl_64x64x3.yaml deleted file mode 100644 index 5e3db5c4e2..0000000000 --- a/configs/autoencoder/autoencoder_kl_64x64x3.yaml +++ /dev/null @@ -1,54 +0,0 @@ -model: - base_learning_rate: 4.5e-6 - target: ldm.models.autoencoder.AutoencoderKL - params: - monitor: "val/rec_loss" - embed_dim: 3 - lossconfig: - target: ldm.modules.losses.LPIPSWithDiscriminator - params: - disc_start: 50001 - kl_weight: 0.000001 - disc_weight: 0.5 - - ddconfig: - double_z: True - z_channels: 3 - resolution: 256 - in_channels: 3 - out_ch: 3 - ch: 128 - ch_mult: [ 1,2,4 ] # num_down = len(ch_mult)-1 - num_res_blocks: 2 - attn_resolutions: [ ] - dropout: 0.0 - - -data: - target: main.DataModuleFromConfig - params: - batch_size: 12 - wrap: True - train: - target: ldm.data.imagenet.ImageNetSRTrain - params: - size: 256 - degradation: pil_nearest - validation: - target: ldm.data.imagenet.ImageNetSRValidation - params: - size: 256 - degradation: pil_nearest - -lightning: - callbacks: - image_logger: - target: main.ImageLogger - params: - batch_frequency: 1000 - max_images: 8 - increase_log_steps: True - - trainer: - benchmark: True - accumulate_grad_batches: 2 diff --git a/configs/autoencoder/autoencoder_kl_8x8x64.yaml b/configs/autoencoder/autoencoder_kl_8x8x64.yaml deleted file mode 100644 index 5ccd09d38e..0000000000 --- a/configs/autoencoder/autoencoder_kl_8x8x64.yaml +++ /dev/null @@ -1,53 +0,0 @@ -model: - base_learning_rate: 4.5e-6 - target: ldm.models.autoencoder.AutoencoderKL - params: - monitor: "val/rec_loss" - embed_dim: 64 - lossconfig: - target: ldm.modules.losses.LPIPSWithDiscriminator - params: - disc_start: 50001 - kl_weight: 0.000001 - disc_weight: 0.5 - - ddconfig: - double_z: True - z_channels: 64 - resolution: 256 - in_channels: 3 - out_ch: 3 - ch: 128 - ch_mult: [ 1,1,2,2,4,4] # num_down = len(ch_mult)-1 - num_res_blocks: 2 - attn_resolutions: [16,8] - dropout: 0.0 - -data: - target: main.DataModuleFromConfig - params: - batch_size: 12 - wrap: True - train: - target: ldm.data.imagenet.ImageNetSRTrain - params: - size: 256 - degradation: pil_nearest - validation: - target: ldm.data.imagenet.ImageNetSRValidation - params: - size: 256 - degradation: pil_nearest - -lightning: - callbacks: - image_logger: - target: main.ImageLogger - params: - batch_frequency: 1000 - max_images: 8 - increase_log_steps: True - - trainer: - benchmark: True - accumulate_grad_batches: 2 diff --git a/configs/latent-diffusion/celebahq-ldm-vq-4.yaml b/configs/latent-diffusion/celebahq-ldm-vq-4.yaml deleted file mode 100644 index 89b3df4fe1..0000000000 --- a/configs/latent-diffusion/celebahq-ldm-vq-4.yaml +++ /dev/null @@ -1,86 +0,0 @@ -model: - base_learning_rate: 2.0e-06 - target: ldm.models.diffusion.ddpm.LatentDiffusion - params: - linear_start: 0.0015 - linear_end: 0.0195 - num_timesteps_cond: 1 - log_every_t: 200 - timesteps: 1000 - first_stage_key: image - image_size: 64 - channels: 3 - monitor: val/loss_simple_ema - - unet_config: - target: ldm.modules.diffusionmodules.openaimodel.UNetModel - params: - image_size: 64 - in_channels: 3 - out_channels: 3 - model_channels: 224 - attention_resolutions: - # note: this isn\t actually the resolution but - # the downsampling factor, i.e. this corresnponds to - # attention on spatial resolution 8,16,32, as the - # spatial reolution of the latents is 64 for f4 - - 8 - - 4 - - 2 - num_res_blocks: 2 - channel_mult: - - 1 - - 2 - - 3 - - 4 - num_head_channels: 32 - first_stage_config: - target: ldm.models.autoencoder.VQModelInterface - params: - embed_dim: 3 - n_embed: 8192 - ckpt_path: models/first_stage_models/vq-f4/model.ckpt - ddconfig: - double_z: false - z_channels: 3 - resolution: 256 - in_channels: 3 - out_ch: 3 - ch: 128 - ch_mult: - - 1 - - 2 - - 4 - num_res_blocks: 2 - attn_resolutions: [] - dropout: 0.0 - lossconfig: - target: torch.nn.Identity - cond_stage_config: __is_unconditional__ -data: - target: main.DataModuleFromConfig - params: - batch_size: 48 - num_workers: 5 - wrap: false - train: - target: taming.data.faceshq.CelebAHQTrain - params: - size: 256 - validation: - target: taming.data.faceshq.CelebAHQValidation - params: - size: 256 - - -lightning: - callbacks: - image_logger: - target: main.ImageLogger - params: - batch_frequency: 5000 - max_images: 8 - increase_log_steps: False - - trainer: - benchmark: True \ No newline at end of file diff --git a/configs/latent-diffusion/cin-ldm-vq-f8.yaml b/configs/latent-diffusion/cin-ldm-vq-f8.yaml deleted file mode 100644 index b8cd9e2ef5..0000000000 --- a/configs/latent-diffusion/cin-ldm-vq-f8.yaml +++ /dev/null @@ -1,98 +0,0 @@ -model: - base_learning_rate: 1.0e-06 - target: ldm.models.diffusion.ddpm.LatentDiffusion - params: - linear_start: 0.0015 - linear_end: 0.0195 - num_timesteps_cond: 1 - log_every_t: 200 - timesteps: 1000 - first_stage_key: image - cond_stage_key: class_label - image_size: 32 - channels: 4 - cond_stage_trainable: true - conditioning_key: crossattn - monitor: val/loss_simple_ema - unet_config: - target: ldm.modules.diffusionmodules.openaimodel.UNetModel - params: - image_size: 32 - in_channels: 4 - out_channels: 4 - model_channels: 256 - attention_resolutions: - #note: this isn\t actually the resolution but - # the downsampling factor, i.e. this corresnponds to - # attention on spatial resolution 8,16,32, as the - # spatial reolution of the latents is 32 for f8 - - 4 - - 2 - - 1 - num_res_blocks: 2 - channel_mult: - - 1 - - 2 - - 4 - num_head_channels: 32 - use_spatial_transformer: true - transformer_depth: 1 - context_dim: 512 - first_stage_config: - target: ldm.models.autoencoder.VQModelInterface - params: - embed_dim: 4 - n_embed: 16384 - ckpt_path: configs/first_stage_models/vq-f8/model.yaml - ddconfig: - double_z: false - z_channels: 4 - resolution: 256 - in_channels: 3 - out_ch: 3 - ch: 128 - ch_mult: - - 1 - - 2 - - 2 - - 4 - num_res_blocks: 2 - attn_resolutions: - - 32 - dropout: 0.0 - lossconfig: - target: torch.nn.Identity - cond_stage_config: - target: ldm.modules.encoders.modules.ClassEmbedder - params: - embed_dim: 512 - key: class_label -data: - target: main.DataModuleFromConfig - params: - batch_size: 64 - num_workers: 12 - wrap: false - train: - target: ldm.data.imagenet.ImageNetTrain - params: - config: - size: 256 - validation: - target: ldm.data.imagenet.ImageNetValidation - params: - config: - size: 256 - - -lightning: - callbacks: - image_logger: - target: main.ImageLogger - params: - batch_frequency: 5000 - max_images: 8 - increase_log_steps: False - - trainer: - benchmark: True \ No newline at end of file diff --git a/configs/latent-diffusion/cin256-v2.yaml b/configs/latent-diffusion/cin256-v2.yaml deleted file mode 100644 index b7c1aa240c..0000000000 --- a/configs/latent-diffusion/cin256-v2.yaml +++ /dev/null @@ -1,68 +0,0 @@ -model: - base_learning_rate: 0.0001 - target: ldm.models.diffusion.ddpm.LatentDiffusion - params: - linear_start: 0.0015 - linear_end: 0.0195 - num_timesteps_cond: 1 - log_every_t: 200 - timesteps: 1000 - first_stage_key: image - cond_stage_key: class_label - image_size: 64 - channels: 3 - cond_stage_trainable: true - conditioning_key: crossattn - monitor: val/loss - use_ema: False - - unet_config: - target: ldm.modules.diffusionmodules.openaimodel.UNetModel - params: - image_size: 64 - in_channels: 3 - out_channels: 3 - model_channels: 192 - attention_resolutions: - - 8 - - 4 - - 2 - num_res_blocks: 2 - channel_mult: - - 1 - - 2 - - 3 - - 5 - num_heads: 1 - use_spatial_transformer: true - transformer_depth: 1 - context_dim: 512 - - first_stage_config: - target: ldm.models.autoencoder.VQModelInterface - params: - embed_dim: 3 - n_embed: 8192 - ddconfig: - double_z: false - z_channels: 3 - resolution: 256 - in_channels: 3 - out_ch: 3 - ch: 128 - ch_mult: - - 1 - - 2 - - 4 - num_res_blocks: 2 - attn_resolutions: [] - dropout: 0.0 - lossconfig: - target: torch.nn.Identity - - cond_stage_config: - target: ldm.modules.encoders.modules.ClassEmbedder - params: - n_classes: 1001 - embed_dim: 512 - key: class_label diff --git a/configs/latent-diffusion/ffhq-ldm-vq-4.yaml b/configs/latent-diffusion/ffhq-ldm-vq-4.yaml deleted file mode 100644 index 1899e30f77..0000000000 --- a/configs/latent-diffusion/ffhq-ldm-vq-4.yaml +++ /dev/null @@ -1,85 +0,0 @@ -model: - base_learning_rate: 2.0e-06 - target: ldm.models.diffusion.ddpm.LatentDiffusion - params: - linear_start: 0.0015 - linear_end: 0.0195 - num_timesteps_cond: 1 - log_every_t: 200 - timesteps: 1000 - first_stage_key: image - image_size: 64 - channels: 3 - monitor: val/loss_simple_ema - unet_config: - target: ldm.modules.diffusionmodules.openaimodel.UNetModel - params: - image_size: 64 - in_channels: 3 - out_channels: 3 - model_channels: 224 - attention_resolutions: - # note: this isn\t actually the resolution but - # the downsampling factor, i.e. this corresnponds to - # attention on spatial resolution 8,16,32, as the - # spatial reolution of the latents is 64 for f4 - - 8 - - 4 - - 2 - num_res_blocks: 2 - channel_mult: - - 1 - - 2 - - 3 - - 4 - num_head_channels: 32 - first_stage_config: - target: ldm.models.autoencoder.VQModelInterface - params: - embed_dim: 3 - n_embed: 8192 - ckpt_path: configs/first_stage_models/vq-f4/model.yaml - ddconfig: - double_z: false - z_channels: 3 - resolution: 256 - in_channels: 3 - out_ch: 3 - ch: 128 - ch_mult: - - 1 - - 2 - - 4 - num_res_blocks: 2 - attn_resolutions: [] - dropout: 0.0 - lossconfig: - target: torch.nn.Identity - cond_stage_config: __is_unconditional__ -data: - target: main.DataModuleFromConfig - params: - batch_size: 42 - num_workers: 5 - wrap: false - train: - target: taming.data.faceshq.FFHQTrain - params: - size: 256 - validation: - target: taming.data.faceshq.FFHQValidation - params: - size: 256 - - -lightning: - callbacks: - image_logger: - target: main.ImageLogger - params: - batch_frequency: 5000 - max_images: 8 - increase_log_steps: False - - trainer: - benchmark: True \ No newline at end of file diff --git a/configs/latent-diffusion/lsun_bedrooms-ldm-vq-4.yaml b/configs/latent-diffusion/lsun_bedrooms-ldm-vq-4.yaml deleted file mode 100644 index c4ca66c16c..0000000000 --- a/configs/latent-diffusion/lsun_bedrooms-ldm-vq-4.yaml +++ /dev/null @@ -1,85 +0,0 @@ -model: - base_learning_rate: 2.0e-06 - target: ldm.models.diffusion.ddpm.LatentDiffusion - params: - linear_start: 0.0015 - linear_end: 0.0195 - num_timesteps_cond: 1 - log_every_t: 200 - timesteps: 1000 - first_stage_key: image - image_size: 64 - channels: 3 - monitor: val/loss_simple_ema - unet_config: - target: ldm.modules.diffusionmodules.openaimodel.UNetModel - params: - image_size: 64 - in_channels: 3 - out_channels: 3 - model_channels: 224 - attention_resolutions: - # note: this isn\t actually the resolution but - # the downsampling factor, i.e. this corresnponds to - # attention on spatial resolution 8,16,32, as the - # spatial reolution of the latents is 64 for f4 - - 8 - - 4 - - 2 - num_res_blocks: 2 - channel_mult: - - 1 - - 2 - - 3 - - 4 - num_head_channels: 32 - first_stage_config: - target: ldm.models.autoencoder.VQModelInterface - params: - ckpt_path: configs/first_stage_models/vq-f4/model.yaml - embed_dim: 3 - n_embed: 8192 - ddconfig: - double_z: false - z_channels: 3 - resolution: 256 - in_channels: 3 - out_ch: 3 - ch: 128 - ch_mult: - - 1 - - 2 - - 4 - num_res_blocks: 2 - attn_resolutions: [] - dropout: 0.0 - lossconfig: - target: torch.nn.Identity - cond_stage_config: __is_unconditional__ -data: - target: main.DataModuleFromConfig - params: - batch_size: 48 - num_workers: 5 - wrap: false - train: - target: ldm.data.lsun.LSUNBedroomsTrain - params: - size: 256 - validation: - target: ldm.data.lsun.LSUNBedroomsValidation - params: - size: 256 - - -lightning: - callbacks: - image_logger: - target: main.ImageLogger - params: - batch_frequency: 5000 - max_images: 8 - increase_log_steps: False - - trainer: - benchmark: True \ No newline at end of file diff --git a/configs/latent-diffusion/lsun_churches-ldm-kl-8.yaml b/configs/latent-diffusion/lsun_churches-ldm-kl-8.yaml deleted file mode 100644 index 18dc8c2d9c..0000000000 --- a/configs/latent-diffusion/lsun_churches-ldm-kl-8.yaml +++ /dev/null @@ -1,91 +0,0 @@ -model: - base_learning_rate: 5.0e-5 # set to target_lr by starting main.py with '--scale_lr False' - target: ldm.models.diffusion.ddpm.LatentDiffusion - params: - linear_start: 0.0015 - linear_end: 0.0155 - num_timesteps_cond: 1 - log_every_t: 200 - timesteps: 1000 - loss_type: l1 - first_stage_key: "image" - cond_stage_key: "image" - image_size: 32 - channels: 4 - cond_stage_trainable: False - concat_mode: False - scale_by_std: True - monitor: 'val/loss_simple_ema' - - scheduler_config: # 10000 warmup steps - target: ldm.lr_scheduler.LambdaLinearScheduler - params: - warm_up_steps: [10000] - cycle_lengths: [10000000000000] - f_start: [1.e-6] - f_max: [1.] - f_min: [ 1.] - - unet_config: - target: ldm.modules.diffusionmodules.openaimodel.UNetModel - params: - image_size: 32 - in_channels: 4 - out_channels: 4 - model_channels: 192 - attention_resolutions: [ 1, 2, 4, 8 ] # 32, 16, 8, 4 - num_res_blocks: 2 - channel_mult: [ 1,2,2,4,4 ] # 32, 16, 8, 4, 2 - num_heads: 8 - use_scale_shift_norm: True - resblock_updown: True - - first_stage_config: - target: ldm.models.autoencoder.AutoencoderKL - params: - embed_dim: 4 - monitor: "val/rec_loss" - ckpt_path: "models/first_stage_models/kl-f8/model.ckpt" - ddconfig: - double_z: True - z_channels: 4 - resolution: 256 - in_channels: 3 - out_ch: 3 - ch: 128 - ch_mult: [ 1,2,4,4 ] # num_down = len(ch_mult)-1 - num_res_blocks: 2 - attn_resolutions: [ ] - dropout: 0.0 - lossconfig: - target: torch.nn.Identity - - cond_stage_config: "__is_unconditional__" - -data: - target: main.DataModuleFromConfig - params: - batch_size: 96 - num_workers: 5 - wrap: False - train: - target: ldm.data.lsun.LSUNChurchesTrain - params: - size: 256 - validation: - target: ldm.data.lsun.LSUNChurchesValidation - params: - size: 256 - -lightning: - callbacks: - image_logger: - target: main.ImageLogger - params: - batch_frequency: 5000 - max_images: 8 - increase_log_steps: False - - - trainer: - benchmark: True \ No newline at end of file diff --git a/configs/latent-diffusion/txt2img-1p4B-eval.yaml b/configs/latent-diffusion/txt2img-1p4B-eval.yaml deleted file mode 100644 index 8e331cbfdf..0000000000 --- a/configs/latent-diffusion/txt2img-1p4B-eval.yaml +++ /dev/null @@ -1,71 +0,0 @@ -model: - base_learning_rate: 5.0e-05 - target: ldm.models.diffusion.ddpm.LatentDiffusion - params: - linear_start: 0.00085 - linear_end: 0.012 - num_timesteps_cond: 1 - log_every_t: 200 - timesteps: 1000 - first_stage_key: image - cond_stage_key: caption - image_size: 32 - channels: 4 - cond_stage_trainable: true - conditioning_key: crossattn - monitor: val/loss_simple_ema - scale_factor: 0.18215 - use_ema: False - - unet_config: - target: ldm.modules.diffusionmodules.openaimodel.UNetModel - params: - image_size: 32 - in_channels: 4 - out_channels: 4 - model_channels: 320 - attention_resolutions: - - 4 - - 2 - - 1 - num_res_blocks: 2 - channel_mult: - - 1 - - 2 - - 4 - - 4 - num_heads: 8 - use_spatial_transformer: true - transformer_depth: 1 - context_dim: 1280 - use_checkpoint: true - legacy: False - - first_stage_config: - target: ldm.models.autoencoder.AutoencoderKL - params: - embed_dim: 4 - monitor: val/rec_loss - ddconfig: - double_z: true - z_channels: 4 - resolution: 256 - in_channels: 3 - out_ch: 3 - ch: 128 - ch_mult: - - 1 - - 2 - - 4 - - 4 - num_res_blocks: 2 - attn_resolutions: [] - dropout: 0.0 - lossconfig: - target: torch.nn.Identity - - cond_stage_config: - target: ldm.modules.encoders.modules.BERTEmbedder - params: - n_embed: 1280 - n_layer: 32 diff --git a/configs/models.yaml b/configs/models.yaml deleted file mode 100644 index a3c929d29f..0000000000 --- a/configs/models.yaml +++ /dev/null @@ -1,18 +0,0 @@ -# This file describes the alternative machine learning models -# available to the dream script. -# -# To add a new model, follow the examples below. Each -# model requires a model config file, a weights file, -# and the width and height of the images it -# was trained on. - -laion400m: - config: configs/latent-diffusion/txt2img-1p4B-eval.yaml - weights: models/ldm/text2img-large/model.ckpt - width: 256 - height: 256 -stable-diffusion-1.4: - config: configs/stable-diffusion/v1-inference.yaml - weights: models/ldm/stable-diffusion-v1/model.ckpt - width: 512 - height: 512 diff --git a/configs/models.yaml.example b/configs/models.yaml.example new file mode 100644 index 0000000000..9c152c25c1 --- /dev/null +++ b/configs/models.yaml.example @@ -0,0 +1,27 @@ +# This file describes the alternative machine learning models +# available to InvokeAI script. +# +# To add a new model, follow the examples below. Each +# model requires a model config file, a weights file, +# and the width and height of the images it +# was trained on. +stable-diffusion-1.5: + description: The newest Stable Diffusion version 1.5 weight file (4.27 GB) + weights: ./models/ldm/stable-diffusion-v1/v1-5-pruned-emaonly.ckpt + config: ./configs/stable-diffusion/v1-inference.yaml + width: 512 + height: 512 + vae: ./models/ldm/stable-diffusion-v1/vae-ft-mse-840000-ema-pruned.ckpt + default: true +stable-diffusion-1.4: + description: Stable Diffusion inference model version 1.4 + config: configs/stable-diffusion/v1-inference.yaml + weights: models/ldm/stable-diffusion-v1/sd-v1-4.ckpt + vae: models/ldm/stable-diffusion-v1/vae-ft-mse-840000-ema-pruned.ckpt + width: 512 + height: 512 +inpainting-1.5: + weights: models/ldm/stable-diffusion-v1/sd-v1-5-inpainting.ckpt + config: configs/stable-diffusion/v1-inpainting-inference.yaml + vae: models/ldm/stable-diffusion-v1/vae-ft-mse-840000-ema-pruned.ckpt + description: RunwayML SD 1.5 model optimized for inpainting diff --git a/configs/retrieval-augmented-diffusion/768x768.yaml b/configs/retrieval-augmented-diffusion/768x768.yaml deleted file mode 100644 index b51b1d8373..0000000000 --- a/configs/retrieval-augmented-diffusion/768x768.yaml +++ /dev/null @@ -1,68 +0,0 @@ -model: - base_learning_rate: 0.0001 - target: ldm.models.diffusion.ddpm.LatentDiffusion - params: - linear_start: 0.0015 - linear_end: 0.015 - num_timesteps_cond: 1 - log_every_t: 200 - timesteps: 1000 - first_stage_key: jpg - cond_stage_key: nix - image_size: 48 - channels: 16 - cond_stage_trainable: false - conditioning_key: crossattn - monitor: val/loss_simple_ema - scale_by_std: false - scale_factor: 0.22765929 - unet_config: - target: ldm.modules.diffusionmodules.openaimodel.UNetModel - params: - image_size: 48 - in_channels: 16 - out_channels: 16 - model_channels: 448 - attention_resolutions: - - 4 - - 2 - - 1 - num_res_blocks: 2 - channel_mult: - - 1 - - 2 - - 3 - - 4 - use_scale_shift_norm: false - resblock_updown: false - num_head_channels: 32 - use_spatial_transformer: true - transformer_depth: 1 - context_dim: 768 - use_checkpoint: true - first_stage_config: - target: ldm.models.autoencoder.AutoencoderKL - params: - monitor: val/rec_loss - embed_dim: 16 - ddconfig: - double_z: true - z_channels: 16 - resolution: 256 - in_channels: 3 - out_ch: 3 - ch: 128 - ch_mult: - - 1 - - 1 - - 2 - - 2 - - 4 - num_res_blocks: 2 - attn_resolutions: - - 16 - dropout: 0.0 - lossconfig: - target: torch.nn.Identity - cond_stage_config: - target: torch.nn.Identity \ No newline at end of file diff --git a/configs/stable-diffusion/v1-finetune.yaml b/configs/stable-diffusion/v1-finetune.yaml index 7bc31168e7..df22987fa5 100644 --- a/configs/stable-diffusion/v1-finetune.yaml +++ b/configs/stable-diffusion/v1-finetune.yaml @@ -107,4 +107,4 @@ lightning: benchmark: True max_steps: 4000000 # max_steps: 4000 - \ No newline at end of file + diff --git a/configs/stable-diffusion/v1-inference.yaml b/configs/stable-diffusion/v1-inference.yaml index 59d8f33125..baf91f6e26 100644 --- a/configs/stable-diffusion/v1-inference.yaml +++ b/configs/stable-diffusion/v1-inference.yaml @@ -30,7 +30,7 @@ model: target: ldm.modules.embedding_manager.EmbeddingManager params: placeholder_strings: ["*"] - initializer_words: ["sculpture"] + initializer_words: ['face', 'man', 'photo', 'africanmale'] per_image_tokens: false num_vectors_per_token: 1 progressive_words: False @@ -76,4 +76,4 @@ model: target: torch.nn.Identity cond_stage_config: - target: ldm.modules.encoders.modules.FrozenCLIPEmbedder + target: ldm.modules.encoders.modules.WeightedFrozenCLIPEmbedder diff --git a/configs/stable-diffusion/v1-inpainting-inference.yaml b/configs/stable-diffusion/v1-inpainting-inference.yaml new file mode 100644 index 0000000000..3ea164a359 --- /dev/null +++ b/configs/stable-diffusion/v1-inpainting-inference.yaml @@ -0,0 +1,79 @@ +model: + base_learning_rate: 7.5e-05 + target: ldm.models.diffusion.ddpm.LatentInpaintDiffusion + params: + linear_start: 0.00085 + linear_end: 0.0120 + num_timesteps_cond: 1 + log_every_t: 200 + timesteps: 1000 + first_stage_key: "jpg" + cond_stage_key: "txt" + image_size: 64 + channels: 4 + cond_stage_trainable: false # Note: different from the one we trained before + conditioning_key: hybrid # important + monitor: val/loss_simple_ema + scale_factor: 0.18215 + finetune_keys: null + + scheduler_config: # 10000 warmup steps + target: ldm.lr_scheduler.LambdaLinearScheduler + params: + warm_up_steps: [ 2500 ] # NOTE for resuming. use 10000 if starting from scratch + cycle_lengths: [ 10000000000000 ] # incredibly large number to prevent corner cases + f_start: [ 1.e-6 ] + f_max: [ 1. ] + f_min: [ 1. ] + + personalization_config: + target: ldm.modules.embedding_manager.EmbeddingManager + params: + placeholder_strings: ["*"] + initializer_words: ['face', 'man', 'photo', 'africanmale'] + per_image_tokens: false + num_vectors_per_token: 1 + progressive_words: False + + unet_config: + target: ldm.modules.diffusionmodules.openaimodel.UNetModel + params: + image_size: 32 # unused + in_channels: 9 # 4 data + 4 downscaled image + 1 mask + out_channels: 4 + model_channels: 320 + attention_resolutions: [ 4, 2, 1 ] + num_res_blocks: 2 + channel_mult: [ 1, 2, 4, 4 ] + num_heads: 8 + use_spatial_transformer: True + transformer_depth: 1 + context_dim: 768 + use_checkpoint: True + legacy: False + + first_stage_config: + target: ldm.models.autoencoder.AutoencoderKL + params: + embed_dim: 4 + monitor: val/rec_loss + ddconfig: + double_z: true + z_channels: 4 + resolution: 256 + in_channels: 3 + out_ch: 3 + ch: 128 + ch_mult: + - 1 + - 2 + - 4 + - 4 + num_res_blocks: 2 + attn_resolutions: [] + dropout: 0.0 + lossconfig: + target: torch.nn.Identity + + cond_stage_config: + target: ldm.modules.encoders.modules.WeightedFrozenCLIPEmbedder diff --git a/configs/stable-diffusion/v1-m1-finetune.yaml b/configs/stable-diffusion/v1-m1-finetune.yaml new file mode 100644 index 0000000000..af37f1ec7e --- /dev/null +++ b/configs/stable-diffusion/v1-m1-finetune.yaml @@ -0,0 +1,110 @@ +model: + base_learning_rate: 5.0e-03 + target: ldm.models.diffusion.ddpm.LatentDiffusion + params: + linear_start: 0.00085 + linear_end: 0.0120 + num_timesteps_cond: 1 + log_every_t: 200 + timesteps: 1000 + first_stage_key: image + cond_stage_key: caption + image_size: 64 + channels: 4 + cond_stage_trainable: true # Note: different from the one we trained before + conditioning_key: crossattn + monitor: val/loss_simple_ema + scale_factor: 0.18215 + use_ema: False + embedding_reg_weight: 0.0 + + personalization_config: + target: ldm.modules.embedding_manager.EmbeddingManager + params: + placeholder_strings: ["*"] + initializer_words: ['face', 'man', 'photo', 'africanmale'] + per_image_tokens: false + num_vectors_per_token: 6 + progressive_words: False + + unet_config: + target: ldm.modules.diffusionmodules.openaimodel.UNetModel + params: + image_size: 32 # unused + in_channels: 4 + out_channels: 4 + model_channels: 320 + attention_resolutions: [ 4, 2, 1 ] + num_res_blocks: 2 + channel_mult: [ 1, 2, 4, 4 ] + num_heads: 8 + use_spatial_transformer: True + transformer_depth: 1 + context_dim: 768 + use_checkpoint: True + legacy: False + + first_stage_config: + target: ldm.models.autoencoder.AutoencoderKL + params: + embed_dim: 4 + monitor: val/rec_loss + ddconfig: + double_z: true + z_channels: 4 + resolution: 256 + in_channels: 3 + out_ch: 3 + ch: 128 + ch_mult: + - 1 + - 2 + - 4 + - 4 + num_res_blocks: 2 + attn_resolutions: [] + dropout: 0.0 + lossconfig: + target: torch.nn.Identity + + cond_stage_config: + target: ldm.modules.encoders.modules.FrozenCLIPEmbedder + +data: + target: main.DataModuleFromConfig + params: + batch_size: 1 + num_workers: 2 + wrap: false + train: + target: ldm.data.personalized.PersonalizedBase + params: + size: 512 + set: train + per_image_tokens: false + repeats: 100 + validation: + target: ldm.data.personalized.PersonalizedBase + params: + size: 512 + set: val + per_image_tokens: false + repeats: 10 + +lightning: + modelcheckpoint: + params: + every_n_train_steps: 500 + callbacks: + image_logger: + target: main.ImageLogger + params: + batch_frequency: 500 + max_images: 5 + increase_log_steps: False + + trainer: + benchmark: False + max_steps: 6200 +# max_steps: 4000 + diff --git a/docker-build/Dockerfile b/docker-build/Dockerfile new file mode 100644 index 0000000000..1de6f778bb --- /dev/null +++ b/docker-build/Dockerfile @@ -0,0 +1,75 @@ +FROM ubuntu AS get_miniconda + +SHELL ["/bin/bash", "-c"] + +# install wget +RUN apt-get update \ + && apt-get install -y \ + wget \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# download and install miniconda +ARG conda_version=py39_4.12.0-Linux-x86_64 +ARG conda_prefix=/opt/conda +RUN wget --progress=dot:giga -O /miniconda.sh \ + https://repo.anaconda.com/miniconda/Miniconda3-${conda_version}.sh \ + && bash /miniconda.sh -b -p ${conda_prefix} \ + && rm -f /miniconda.sh + +FROM ubuntu AS invokeai + +# use bash +SHELL [ "/bin/bash", "-c" ] + +# clean bashrc +RUN echo "" > ~/.bashrc + +# Install necesarry packages +RUN apt-get update \ + && apt-get install -y \ + --no-install-recommends \ + gcc \ + git \ + libgl1-mesa-glx \ + libglib2.0-0 \ + pip \ + python3 \ + python3-dev \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# clone repository, create models.yaml and create symlinks +ARG invokeai_git=invoke-ai/InvokeAI +ARG invokeai_branch=main +ARG project_name=invokeai +RUN git clone -b ${invokeai_branch} https://github.com/${invokeai_git}.git /${project_name} \ + && cp /${project_name}/configs/models.yaml.example /${project_name}/configs/models.yaml \ + && ln -s /data/models/v1-5-pruned-emaonly.ckpt /${project_name}/models/ldm/stable-diffusion-v1/v1-5-pruned-emaonly.ckpt \ + && ln -s /data/outputs/ /${project_name}/outputs + +# set workdir +WORKDIR /${project_name} + +# install conda env and preload models +ARG conda_prefix=/opt/conda +ARG conda_env_file=environment.yml +COPY --from=get_miniconda ${conda_prefix} ${conda_prefix} +RUN source ${conda_prefix}/etc/profile.d/conda.sh \ + && conda init bash \ + && source ~/.bashrc \ + && conda env create \ + --name ${project_name} \ + --file ${conda_env_file} \ + && rm -Rf ~/.cache \ + && conda clean -afy \ + && echo "conda activate ${project_name}" >> ~/.bashrc \ + && conda activate ${project_name} \ + && python scripts/preload_models.py \ + --no-interactive + +# Copy entrypoint and set env +ENV CONDA_PREFIX=${conda_prefix} +ENV PROJECT_NAME=${project_name} +COPY docker-build/entrypoint.sh / +ENTRYPOINT [ "/entrypoint.sh" ] diff --git a/docker-build/build.sh b/docker-build/build.sh new file mode 100755 index 0000000000..ebd1ca6a41 --- /dev/null +++ b/docker-build/build.sh @@ -0,0 +1,84 @@ +#!/usr/bin/env bash +set -e +# IMPORTANT: You need to have a token on huggingface.co to be able to download the checkpoint!!! +# configure values by using env when executing build.sh +# f.e. env ARCH=aarch64 GITHUB_INVOKE_AI=https://github.com/yourname/yourfork.git ./build.sh + +source ./docker-build/env.sh || echo "please run from repository root" || exit 1 + +invokeai_conda_version=${INVOKEAI_CONDA_VERSION:-py39_4.12.0-${platform/\//-}} +invokeai_conda_prefix=${INVOKEAI_CONDA_PREFIX:-\/opt\/conda} +invokeai_conda_env_file=${INVOKEAI_CONDA_ENV_FILE:-environment.yml} +invokeai_git=${INVOKEAI_GIT:-invoke-ai/InvokeAI} +invokeai_branch=${INVOKEAI_BRANCH:-main} +huggingface_token=${HUGGINGFACE_TOKEN?} + +# print the settings +echo "You are using these values:" +echo -e "project_name:\t\t ${project_name}" +echo -e "volumename:\t\t ${volumename}" +echo -e "arch:\t\t\t ${arch}" +echo -e "platform:\t\t ${platform}" +echo -e "invokeai_conda_version:\t ${invokeai_conda_version}" +echo -e "invokeai_conda_prefix:\t ${invokeai_conda_prefix}" +echo -e "invokeai_conda_env_file: ${invokeai_conda_env_file}" +echo -e "invokeai_git:\t\t ${invokeai_git}" +echo -e "invokeai_tag:\t\t ${invokeai_tag}\n" + +_runAlpine() { + docker run \ + --rm \ + --interactive \ + --tty \ + --mount source="$volumename",target=/data \ + --workdir /data \ + alpine "$@" +} + +_copyCheckpoints() { + echo "creating subfolders for models and outputs" + _runAlpine mkdir models + _runAlpine mkdir outputs + echo "downloading v1-5-pruned-emaonly.ckpt" + _runAlpine wget \ + --header="Authorization: Bearer ${huggingface_token}" \ + -O models/v1-5-pruned-emaonly.ckpt \ + https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.ckpt + echo "done" +} + +_checkVolumeContent() { + _runAlpine ls -lhA /data/models +} + +_getModelMd5s() { + _runAlpine \ + alpine sh -c "md5sum /data/models/*.ckpt" +} + +if [[ -n "$(docker volume ls -f name="${volumename}" -q)" ]]; then + echo "Volume already exists" + if [[ -z "$(_checkVolumeContent)" ]]; then + echo "looks empty, copying checkpoint" + _copyCheckpoints + fi + echo "Models in ${volumename}:" + _checkVolumeContent +else + echo -n "createing docker volume " + docker volume create "${volumename}" + _copyCheckpoints +fi + +# Build Container +docker build \ + --platform="${platform}" \ + --tag "${invokeai_tag}" \ + --build-arg project_name="${project_name}" \ + --build-arg conda_version="${invokeai_conda_version}" \ + --build-arg conda_prefix="${invokeai_conda_prefix}" \ + --build-arg conda_env_file="${invokeai_conda_env_file}" \ + --build-arg invokeai_git="${invokeai_git}" \ + --build-arg invokeai_branch="${invokeai_branch}" \ + --file ./docker-build/Dockerfile \ + . diff --git a/docker-build/entrypoint.sh b/docker-build/entrypoint.sh new file mode 100755 index 0000000000..7c0ca12f88 --- /dev/null +++ b/docker-build/entrypoint.sh @@ -0,0 +1,8 @@ +#!/bin/bash +set -e + +source "${CONDA_PREFIX}/etc/profile.d/conda.sh" +conda activate "${PROJECT_NAME}" + +python scripts/invoke.py \ + ${@:---web --host=0.0.0.0} diff --git a/docker-build/env.sh b/docker-build/env.sh new file mode 100644 index 0000000000..36b718d362 --- /dev/null +++ b/docker-build/env.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +project_name=${PROJECT_NAME:-invokeai} +volumename=${VOLUMENAME:-${project_name}_data} +arch=${ARCH:-x86_64} +platform=${PLATFORM:-Linux/${arch}} +invokeai_tag=${INVOKEAI_TAG:-${project_name}-${arch}} + +export project_name +export volumename +export arch +export platform +export invokeai_tag diff --git a/docker-build/run.sh b/docker-build/run.sh new file mode 100755 index 0000000000..3d1a564f4c --- /dev/null +++ b/docker-build/run.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +set -e + +source ./docker-build/env.sh || echo "please run from repository root" || exit 1 + +docker run \ + --interactive \ + --tty \ + --rm \ + --platform "$platform" \ + --name "$project_name" \ + --hostname "$project_name" \ + --mount source="$volumename",target=/data \ + --publish 9090:9090 \ + "$invokeai_tag" ${1:+$@} diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 31dc8e80db..9b4dfe1cfc 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,51 +1,106 @@ -# **Changelog** +--- +title: Changelog +--- -## v1.13 (in process) +# :octicons-log-16: **Changelog** -- Supports a Google Colab notebook for a standalone server running on Google hardware [Arturo Mendivil](https://github.com/artmen1516) -- WebUI supports GFPGAN/ESRGAN facial reconstruction and upscaling [Kevin Gibbons](https://github.com/bakkot) -- WebUI supports incremental display of in-progress images during generation [Kevin Gibbons](https://github.com/bakkot) -- Output directory can be specified on the dream> command line. -- The grid was displaying duplicated images when not enough images to fill the final row [Muhammad Usama](https://github.com/SMUsamaShah) -- Can specify --grid on dream.py command line as the default. +## v2.0.1 (13 October 2022) + +- fix noisy images at high step count when using k* samplers +- dream.py script now calls invoke.py module directly rather than + via a new python process (which could break the environment) + +## v2.0.0 (9 October 2022) + +- `dream.py` script renamed `invoke.py`. A `dream.py` script wrapper remains + for backward compatibility. +- Completely new WebGUI - launch with `python3 scripts/invoke.py --web` +- Support for [inpainting](features/INPAINTING.md) and [outpainting](features/OUTPAINTING.md) +- img2img runs on all k* samplers +- Support for [negative prompts](features/PROMPTS.md#negative-and-unconditioned-prompts) +- Support for CodeFormer face reconstruction +- Support for Textual Inversion on Macintoshes +- Support in both WebGUI and CLI for [post-processing of previously-generated images](features/POSTPROCESS.md) + using facial reconstruction, ESRGAN upscaling, outcropping (similar to DALL-E infinite canvas), + and "embiggen" upscaling. See the `!fix` command. +- New `--hires` option on `invoke>` line allows [larger images to be created without duplicating elements](features/CLI.md#this-is-an-example-of-txt2img), at the cost of some performance. +- New `--perlin` and `--threshold` options allow you to add and control variation + during image generation (see [Thresholding and Perlin Noise Initialization](features/OTHER.md#thresholding-and-perlin-noise-initialization-options)) +- Extensive metadata now written into PNG files, allowing reliable regeneration of images + and tweaking of previous settings. +- Command-line completion in `invoke.py` now works on Windows, Linux and Mac platforms. +- Improved [command-line completion behavior](features/CLI.md) + New commands added: + - List command-line history with `!history` + - Search command-line history with `!search` + - Clear history with `!clear` +- Deprecated `--full_precision` / `-F`. Simply omit it and `invoke.py` will auto + configure. To switch away from auto use the new flag like `--precision=float32`. + +## v1.14 (11 September 2022) + +- Memory optimizations for small-RAM cards. 512x512 now possible on 4 GB GPUs. +- Full support for Apple hardware with M1 or M2 chips. +- Add "seamless mode" for circular tiling of image. Generates beautiful effects. + ([prixt](https://github.com/prixt)). +- Inpainting support. +- Improved web server GUI. +- Lots of code and documentation cleanups. + +## v1.13 (3 September 2022) + +- Support image variations (see [VARIATIONS](features/VARIATIONS.md) + ([Kevin Gibbons](https://github.com/bakkot) and many contributors and reviewers) +- Supports a Google Colab notebook for a standalone server running on Google hardware + [Arturo Mendivil](https://github.com/artmen1516) +- WebUI supports GFPGAN/ESRGAN facial reconstruction and upscaling + [Kevin Gibbons](https://github.com/bakkot) +- WebUI supports incremental display of in-progress images during generation + [Kevin Gibbons](https://github.com/bakkot) +- A new configuration file scheme that allows new models (including upcoming + stable-diffusion-v1.5) to be added without altering the code. + ([David Wager](https://github.com/maddavid12)) +- Can specify --grid on invoke.py command line as the default. - Miscellaneous internal bug and stability fixes. +- Works on M1 Apple hardware. +- Multiple bug fixes. --- -## v1.12 (28 August 2022) +## v1.12 (28 August 2022) - Improved file handling, including ability to read prompts from standard input. (kudos to [Yunsaki](https://github.com/yunsaki) -- The web server is now integrated with the dream.py script. Invoke by adding --web to - the dream.py command arguments. +- The web server is now integrated with the invoke.py script. Invoke by adding --web to + the invoke.py command arguments. - Face restoration and upscaling via GFPGAN and Real-ESGAN are now automatically enabled if the GFPGAN directory is located as a sibling to Stable Diffusion. VRAM requirements are modestly reduced. Thanks to both [Blessedcoolant](https://github.com/blessedcoolant) and [Oceanswave](https://github.com/oceanswave) for their work on this. -- You can now swap samplers on the dream> command line. [Blessedcoolant](https://github.com/blessedcoolant) +- You can now swap samplers on the invoke> command line. [Blessedcoolant](https://github.com/blessedcoolant) --- -## v1.11 (26 August 2022) +## v1.11 (26 August 2022) - NEW FEATURE: Support upscaling and face enhancement using the GFPGAN module. (kudos to [Oceanswave](https://github.com/Oceanswave) - You now can specify a seed of -1 to use the previous image's seed, -2 to use the seed for the image generated before that, etc. Seed memory only extends back to the previous command, but will work on all images generated with the -n# switch. - Variant generation support temporarily disabled pending more general solution. -- Created a feature branch named **yunsaki-morphing-dream** which adds experimental support for - iteratively modifying the prompt and its parameters. Please see[ Pull Request #86](https://github.com/lstein/stable-diffusion/pull/86) +- Created a feature branch named **yunsaki-morphing-invoke** which adds experimental support for + iteratively modifying the prompt and its parameters. Please see[Pull Request #86](https://github.com/lstein/stable-diffusion/pull/86) for a synopsis of how this works. Note that when this feature is eventually added to the main branch, it will may be modified significantly. --- -## v1.10 (25 August 2022) +## v1.10 (25 August 2022) - A barebones but fully functional interactive web server for online generation of txt2img and img2img. --- -## v1.09 (24 August 2022) +## v1.09 (24 August 2022) - A new -v option allows you to generate multiple variants of an initial image in img2img mode. (kudos to [Oceanswave](https://github.com/Oceanswave). [ @@ -55,9 +110,9 @@ --- -## v1.08 (24 August 2022) +## v1.08 (24 August 2022) -- Escape single quotes on the dream> command before trying to parse. This avoids +- Escape single quotes on the invoke> command before trying to parse. This avoids parse errors. - Removed instruction to get Python3.8 as first step in Windows install. Anaconda3 does it for you. @@ -66,7 +121,7 @@ --- -## v1.07 (23 August 2022) +## v1.07 (23 August 2022) - Image filenames will now never fill gaps in the sequence, but will be assigned the next higher name in the chosen directory. This ensures that the alphabetic and chronological @@ -74,14 +129,14 @@ --- -## v1.06 (23 August 2022) +## v1.06 (23 August 2022) - Added weighted prompt support contributed by [xraxra](https://github.com/xraxra) - Example of using weighted prompts to tweak a demonic figure contributed by [bmaltais](https://github.com/bmaltais) --- -## v1.05 (22 August 2022 - after the drop) +## v1.05 (22 August 2022 - after the drop) - Filenames now use the following formats: 000010.95183149.png -- Two files produced by the same command (e.g. -n2), @@ -94,12 +149,12 @@ be regenerated with the indicated key - It should no longer be possible for one image to overwrite another -- You can use the "cd" and "pwd" commands at the dream> prompt to set and retrieve +- You can use the "cd" and "pwd" commands at the invoke> prompt to set and retrieve the path of the output directory. --- -## v1.04 (22 August 2022 - after the drop) +## v1.04 (22 August 2022 - after the drop) - Updated README to reflect installation of the released weights. - Suppressed very noisy and inconsequential warning when loading the frozen CLIP @@ -107,31 +162,31 @@ --- -## v1.03 (22 August 2022) +## v1.03 (22 August 2022) - The original txt2img and img2img scripts from the CompViz repository have been moved into a subfolder named "orig_scripts", to reduce confusion. --- -## v1.02 (21 August 2022) +## v1.02 (21 August 2022) - A copy of the prompt and all of its switches and options is now stored in the corresponding image in a tEXt metadata field named "Dream". You can read the prompt using scripts/images2prompt.py, or an image editor that allows you to explore the full metadata. - **Please run "conda env update -f environment.yaml" to load the k_lms dependencies!!** + **Please run "conda env update" to load the k_lms dependencies!!** --- -## v1.01 (21 August 2022) +## v1.01 (21 August 2022) - added k_lms sampling. - **Please run "conda env update -f environment.yaml" to load the k_lms dependencies!!** + **Please run "conda env update" to load the k_lms dependencies!!** - use half precision arithmetic by default, resulting in faster execution and lower memory requirements - Pass argument --full_precision to dream.py to get slower but more accurate image generation + Pass argument --full_precision to invoke.py to get slower but more accurate image generation --- ## Links -- **[Read Me](../readme.md)** +- **[Read Me](index.md)** diff --git a/docs/assets/Lincoln-and-Parrot-512-transparent.png b/docs/assets/Lincoln-and-Parrot-512-transparent.png new file mode 100755 index 0000000000..363f3cced3 Binary files /dev/null and b/docs/assets/Lincoln-and-Parrot-512-transparent.png differ diff --git a/docs/assets/Lincoln-and-Parrot-512.png b/docs/assets/Lincoln-and-Parrot-512.png new file mode 100644 index 0000000000..acabe0f27c Binary files /dev/null and b/docs/assets/Lincoln-and-Parrot-512.png differ diff --git a/docs/assets/img2img/000019.1592514025.png b/docs/assets/img2img/000019.1592514025.png new file mode 100644 index 0000000000..2bc2d63ffa Binary files /dev/null and b/docs/assets/img2img/000019.1592514025.png differ diff --git a/docs/assets/img2img/000019.steps.png b/docs/assets/img2img/000019.steps.png new file mode 100644 index 0000000000..28899e9111 Binary files /dev/null and b/docs/assets/img2img/000019.steps.png differ diff --git a/docs/assets/img2img/000030.1592514025.png b/docs/assets/img2img/000030.1592514025.png new file mode 100644 index 0000000000..0e1641f7eb Binary files /dev/null and b/docs/assets/img2img/000030.1592514025.png differ diff --git a/docs/assets/img2img/000030.step-0.png b/docs/assets/img2img/000030.step-0.png new file mode 100644 index 0000000000..81beb074ec Binary files /dev/null and b/docs/assets/img2img/000030.step-0.png differ diff --git a/docs/assets/img2img/000030.steps.gravity.png b/docs/assets/img2img/000030.steps.gravity.png new file mode 100644 index 0000000000..2bda935a5f Binary files /dev/null and b/docs/assets/img2img/000030.steps.gravity.png differ diff --git a/docs/assets/img2img/000032.1592514025.png b/docs/assets/img2img/000032.1592514025.png new file mode 100644 index 0000000000..0ed2106ec4 Binary files /dev/null and b/docs/assets/img2img/000032.1592514025.png differ diff --git a/docs/assets/img2img/000032.step-0.png b/docs/assets/img2img/000032.step-0.png new file mode 100644 index 0000000000..cc2da68ee4 Binary files /dev/null and b/docs/assets/img2img/000032.step-0.png differ diff --git a/docs/assets/img2img/000032.steps.gravity.png b/docs/assets/img2img/000032.steps.gravity.png new file mode 100644 index 0000000000..79058c1227 Binary files /dev/null and b/docs/assets/img2img/000032.steps.gravity.png differ diff --git a/docs/assets/img2img/000034.1592514025.png b/docs/assets/img2img/000034.1592514025.png new file mode 100644 index 0000000000..43751da572 Binary files /dev/null and b/docs/assets/img2img/000034.1592514025.png differ diff --git a/docs/assets/img2img/000034.steps.png b/docs/assets/img2img/000034.steps.png new file mode 100644 index 0000000000..216213162f Binary files /dev/null and b/docs/assets/img2img/000034.steps.png differ diff --git a/docs/assets/img2img/000035.1592514025.png b/docs/assets/img2img/000035.1592514025.png new file mode 100644 index 0000000000..d298895080 Binary files /dev/null and b/docs/assets/img2img/000035.1592514025.png differ diff --git a/docs/assets/img2img/000035.steps.gravity.png b/docs/assets/img2img/000035.steps.gravity.png new file mode 100644 index 0000000000..122c729e87 Binary files /dev/null and b/docs/assets/img2img/000035.steps.gravity.png differ diff --git a/docs/assets/img2img/000045.1592514025.png b/docs/assets/img2img/000045.1592514025.png new file mode 100644 index 0000000000..5e70f1a5bf Binary files /dev/null and b/docs/assets/img2img/000045.1592514025.png differ diff --git a/docs/assets/img2img/000045.steps.gravity.png b/docs/assets/img2img/000045.steps.gravity.png new file mode 100644 index 0000000000..39e2a9b711 Binary files /dev/null and b/docs/assets/img2img/000045.steps.gravity.png differ diff --git a/docs/assets/img2img/000046.1592514025.png b/docs/assets/img2img/000046.1592514025.png new file mode 100644 index 0000000000..70d248eb61 Binary files /dev/null and b/docs/assets/img2img/000046.1592514025.png differ diff --git a/docs/assets/img2img/000046.steps.gravity.png b/docs/assets/img2img/000046.steps.gravity.png new file mode 100644 index 0000000000..d801a48701 Binary files /dev/null and b/docs/assets/img2img/000046.steps.gravity.png differ diff --git a/docs/assets/img2img/fire-drawing.png b/docs/assets/img2img/fire-drawing.png new file mode 100644 index 0000000000..36e2f111fa Binary files /dev/null and b/docs/assets/img2img/fire-drawing.png differ diff --git a/docs/assets/inpainting/000019.curly.hair.deselected.png b/docs/assets/inpainting/000019.curly.hair.deselected.png new file mode 100644 index 0000000000..54f2285550 Binary files /dev/null and b/docs/assets/inpainting/000019.curly.hair.deselected.png differ diff --git a/docs/assets/inpainting/000019.curly.hair.masked.png b/docs/assets/inpainting/000019.curly.hair.masked.png new file mode 100644 index 0000000000..a221c522f3 Binary files /dev/null and b/docs/assets/inpainting/000019.curly.hair.masked.png differ diff --git a/docs/assets/inpainting/000019.curly.hair.selected.png b/docs/assets/inpainting/000019.curly.hair.selected.png new file mode 100644 index 0000000000..e25bb4340c Binary files /dev/null and b/docs/assets/inpainting/000019.curly.hair.selected.png differ diff --git a/docs/assets/inpainting/000024.801380492.png b/docs/assets/inpainting/000024.801380492.png new file mode 100644 index 0000000000..9c72eb06b8 Binary files /dev/null and b/docs/assets/inpainting/000024.801380492.png differ diff --git a/docs/assets/invoke-web-server-1.png b/docs/assets/invoke-web-server-1.png new file mode 100644 index 0000000000..e97697ba70 Binary files /dev/null and b/docs/assets/invoke-web-server-1.png differ diff --git a/docs/assets/invoke-web-server-2.png b/docs/assets/invoke-web-server-2.png new file mode 100644 index 0000000000..a3348d6853 Binary files /dev/null and b/docs/assets/invoke-web-server-2.png differ diff --git a/docs/assets/invoke-web-server-3.png b/docs/assets/invoke-web-server-3.png new file mode 100644 index 0000000000..7d392cfecc Binary files /dev/null and b/docs/assets/invoke-web-server-3.png differ diff --git a/docs/assets/invoke-web-server-4.png b/docs/assets/invoke-web-server-4.png new file mode 100644 index 0000000000..2690356b8a Binary files /dev/null and b/docs/assets/invoke-web-server-4.png differ diff --git a/docs/assets/invoke-web-server-5.png b/docs/assets/invoke-web-server-5.png new file mode 100644 index 0000000000..eb451c9b9c Binary files /dev/null and b/docs/assets/invoke-web-server-5.png differ diff --git a/docs/assets/invoke-web-server-6.png b/docs/assets/invoke-web-server-6.png new file mode 100644 index 0000000000..4daf4cfd78 Binary files /dev/null and b/docs/assets/invoke-web-server-6.png differ diff --git a/docs/assets/invoke-web-server-7.png b/docs/assets/invoke-web-server-7.png new file mode 100644 index 0000000000..154d45e987 Binary files /dev/null and b/docs/assets/invoke-web-server-7.png differ diff --git a/docs/assets/invoke-web-server-8.png b/docs/assets/invoke-web-server-8.png new file mode 100644 index 0000000000..dc708b1117 Binary files /dev/null and b/docs/assets/invoke-web-server-8.png differ diff --git a/docs/assets/invoke-web-server-9.png b/docs/assets/invoke-web-server-9.png new file mode 100644 index 0000000000..9d0d31bec0 Binary files /dev/null and b/docs/assets/invoke-web-server-9.png differ diff --git a/docs/assets/invoke_web_dark.png b/docs/assets/invoke_web_dark.png new file mode 100644 index 0000000000..9141ab40f3 Binary files /dev/null and b/docs/assets/invoke_web_dark.png differ diff --git a/docs/assets/invoke_web_light.png b/docs/assets/invoke_web_light.png new file mode 100644 index 0000000000..98311ccafd Binary files /dev/null and b/docs/assets/invoke_web_light.png differ diff --git a/docs/assets/invoke_web_server.png b/docs/assets/invoke_web_server.png new file mode 100644 index 0000000000..cdb34a0835 Binary files /dev/null and b/docs/assets/invoke_web_server.png differ diff --git a/docs/assets/join-us-on-discord-image.png b/docs/assets/join-us-on-discord-image.png new file mode 100644 index 0000000000..53e4ee0fe0 Binary files /dev/null and b/docs/assets/join-us-on-discord-image.png differ diff --git a/docs/assets/logo.png b/docs/assets/logo.png index fa0548ff78..b6eb33a6db 100644 Binary files a/docs/assets/logo.png and b/docs/assets/logo.png differ diff --git a/docs/assets/negative_prompt_walkthru/step1.png b/docs/assets/negative_prompt_walkthru/step1.png new file mode 100644 index 0000000000..6f94d7d035 Binary files /dev/null and b/docs/assets/negative_prompt_walkthru/step1.png differ diff --git a/docs/assets/negative_prompt_walkthru/step2.png b/docs/assets/negative_prompt_walkthru/step2.png new file mode 100644 index 0000000000..0ff90eca3c Binary files /dev/null and b/docs/assets/negative_prompt_walkthru/step2.png differ diff --git a/docs/assets/negative_prompt_walkthru/step3.png b/docs/assets/negative_prompt_walkthru/step3.png new file mode 100644 index 0000000000..f6676de386 Binary files /dev/null and b/docs/assets/negative_prompt_walkthru/step3.png differ diff --git a/docs/assets/negative_prompt_walkthru/step4.png b/docs/assets/negative_prompt_walkthru/step4.png new file mode 100644 index 0000000000..2e73532629 Binary files /dev/null and b/docs/assets/negative_prompt_walkthru/step4.png differ diff --git a/docs/assets/outpainting/curly-outcrop-2.png b/docs/assets/outpainting/curly-outcrop-2.png new file mode 100644 index 0000000000..595f011f27 Binary files /dev/null and b/docs/assets/outpainting/curly-outcrop-2.png differ diff --git a/docs/assets/outpainting/curly-outcrop.png b/docs/assets/outpainting/curly-outcrop.png new file mode 100644 index 0000000000..ae8d8dacd3 Binary files /dev/null and b/docs/assets/outpainting/curly-outcrop.png differ diff --git a/docs/assets/outpainting/curly-outpaint.png b/docs/assets/outpainting/curly-outpaint.png new file mode 100644 index 0000000000..9f4a2ee431 Binary files /dev/null and b/docs/assets/outpainting/curly-outpaint.png differ diff --git a/docs/assets/outpainting/curly.png b/docs/assets/outpainting/curly.png new file mode 100644 index 0000000000..d9a4cb257e Binary files /dev/null and b/docs/assets/outpainting/curly.png differ diff --git a/docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512-transparent.png b/docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512-transparent.png new file mode 100644 index 0000000000..363f3cced3 Binary files /dev/null and b/docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512-transparent.png differ diff --git a/docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512.png b/docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512.png new file mode 100644 index 0000000000..acabe0f27c Binary files /dev/null and b/docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512.png differ diff --git a/docs/assets/preflight-checks/inputs/curly.png b/docs/assets/preflight-checks/inputs/curly.png new file mode 100644 index 0000000000..d9a4cb257e Binary files /dev/null and b/docs/assets/preflight-checks/inputs/curly.png differ diff --git a/docs/assets/preflight-checks/outputs/000001.1863159593.png b/docs/assets/preflight-checks/outputs/000001.1863159593.png new file mode 100644 index 0000000000..510533ad37 Binary files /dev/null and b/docs/assets/preflight-checks/outputs/000001.1863159593.png differ diff --git a/docs/assets/preflight-checks/outputs/000002.1151955949.png b/docs/assets/preflight-checks/outputs/000002.1151955949.png new file mode 100644 index 0000000000..22bc883ba4 Binary files /dev/null and b/docs/assets/preflight-checks/outputs/000002.1151955949.png differ diff --git a/docs/assets/preflight-checks/outputs/000003.2736230502.png b/docs/assets/preflight-checks/outputs/000003.2736230502.png new file mode 100644 index 0000000000..43c734864d Binary files /dev/null and b/docs/assets/preflight-checks/outputs/000003.2736230502.png differ diff --git a/docs/assets/preflight-checks/outputs/000004.42.png b/docs/assets/preflight-checks/outputs/000004.42.png new file mode 100644 index 0000000000..a46b4306de Binary files /dev/null and b/docs/assets/preflight-checks/outputs/000004.42.png differ diff --git a/docs/assets/preflight-checks/outputs/000005.42.png b/docs/assets/preflight-checks/outputs/000005.42.png new file mode 100644 index 0000000000..a46b4306de Binary files /dev/null and b/docs/assets/preflight-checks/outputs/000005.42.png differ diff --git a/docs/assets/preflight-checks/outputs/000006.478163327.png b/docs/assets/preflight-checks/outputs/000006.478163327.png new file mode 100644 index 0000000000..c1852903c8 Binary files /dev/null and b/docs/assets/preflight-checks/outputs/000006.478163327.png differ diff --git a/docs/assets/preflight-checks/outputs/000007.2407640369.png b/docs/assets/preflight-checks/outputs/000007.2407640369.png new file mode 100644 index 0000000000..27f46bb79c Binary files /dev/null and b/docs/assets/preflight-checks/outputs/000007.2407640369.png differ diff --git a/docs/assets/preflight-checks/outputs/000008.2772421987.png b/docs/assets/preflight-checks/outputs/000008.2772421987.png new file mode 100644 index 0000000000..73122b6082 Binary files /dev/null and b/docs/assets/preflight-checks/outputs/000008.2772421987.png differ diff --git a/docs/assets/preflight-checks/outputs/000009.3532317557.png b/docs/assets/preflight-checks/outputs/000009.3532317557.png new file mode 100644 index 0000000000..29e47c1319 Binary files /dev/null and b/docs/assets/preflight-checks/outputs/000009.3532317557.png differ diff --git a/docs/assets/preflight-checks/outputs/000010.2028635318.png b/docs/assets/preflight-checks/outputs/000010.2028635318.png new file mode 100644 index 0000000000..82370d6f6d Binary files /dev/null and b/docs/assets/preflight-checks/outputs/000010.2028635318.png differ diff --git a/docs/assets/preflight-checks/outputs/000011.1111168647.png b/docs/assets/preflight-checks/outputs/000011.1111168647.png new file mode 100644 index 0000000000..3aaa9a7b5f Binary files /dev/null and b/docs/assets/preflight-checks/outputs/000011.1111168647.png differ diff --git a/docs/assets/preflight-checks/outputs/000012.1476370516.png b/docs/assets/preflight-checks/outputs/000012.1476370516.png new file mode 100644 index 0000000000..db12e814a5 Binary files /dev/null and b/docs/assets/preflight-checks/outputs/000012.1476370516.png differ diff --git a/docs/assets/preflight-checks/outputs/000013.4281108706.png b/docs/assets/preflight-checks/outputs/000013.4281108706.png new file mode 100644 index 0000000000..5d798249ed Binary files /dev/null and b/docs/assets/preflight-checks/outputs/000013.4281108706.png differ diff --git a/docs/assets/preflight-checks/outputs/000014.2396987386.png b/docs/assets/preflight-checks/outputs/000014.2396987386.png new file mode 100644 index 0000000000..031cecb9f3 Binary files /dev/null and b/docs/assets/preflight-checks/outputs/000014.2396987386.png differ diff --git a/docs/assets/preflight-checks/outputs/000015.1252923272.png b/docs/assets/preflight-checks/outputs/000015.1252923272.png new file mode 100644 index 0000000000..7d9bbd93a5 Binary files /dev/null and b/docs/assets/preflight-checks/outputs/000015.1252923272.png differ diff --git a/docs/assets/preflight-checks/outputs/000016.2633891320.png b/docs/assets/preflight-checks/outputs/000016.2633891320.png new file mode 100644 index 0000000000..46b60566d9 Binary files /dev/null and b/docs/assets/preflight-checks/outputs/000016.2633891320.png differ diff --git a/docs/assets/preflight-checks/outputs/000017.1134411920.png b/docs/assets/preflight-checks/outputs/000017.1134411920.png new file mode 100644 index 0000000000..7dbb581b29 Binary files /dev/null and b/docs/assets/preflight-checks/outputs/000017.1134411920.png differ diff --git a/docs/assets/preflight-checks/outputs/000018.47.png b/docs/assets/preflight-checks/outputs/000018.47.png new file mode 100644 index 0000000000..546c382fef Binary files /dev/null and b/docs/assets/preflight-checks/outputs/000018.47.png differ diff --git a/docs/assets/preflight-checks/outputs/000019.47.png b/docs/assets/preflight-checks/outputs/000019.47.png new file mode 100644 index 0000000000..58f3042add Binary files /dev/null and b/docs/assets/preflight-checks/outputs/000019.47.png differ diff --git a/docs/assets/preflight-checks/outputs/000020.47.png b/docs/assets/preflight-checks/outputs/000020.47.png new file mode 100644 index 0000000000..f9419e0a2e Binary files /dev/null and b/docs/assets/preflight-checks/outputs/000020.47.png differ diff --git a/docs/assets/preflight-checks/outputs/000021.47.png b/docs/assets/preflight-checks/outputs/000021.47.png new file mode 100644 index 0000000000..4f651424c6 Binary files /dev/null and b/docs/assets/preflight-checks/outputs/000021.47.png differ diff --git a/docs/assets/preflight-checks/outputs/000022.47.png b/docs/assets/preflight-checks/outputs/000022.47.png new file mode 100644 index 0000000000..94c2201a6d Binary files /dev/null and b/docs/assets/preflight-checks/outputs/000022.47.png differ diff --git a/docs/assets/preflight-checks/outputs/000023.47.png b/docs/assets/preflight-checks/outputs/000023.47.png new file mode 100644 index 0000000000..88fb064bef Binary files /dev/null and b/docs/assets/preflight-checks/outputs/000023.47.png differ diff --git a/docs/assets/preflight-checks/outputs/000024.1029061431.png b/docs/assets/preflight-checks/outputs/000024.1029061431.png new file mode 100644 index 0000000000..13afde0f13 Binary files /dev/null and b/docs/assets/preflight-checks/outputs/000024.1029061431.png differ diff --git a/docs/assets/preflight-checks/outputs/000025.1284519352.png b/docs/assets/preflight-checks/outputs/000025.1284519352.png new file mode 100644 index 0000000000..ed77106d4a Binary files /dev/null and b/docs/assets/preflight-checks/outputs/000025.1284519352.png differ diff --git a/docs/assets/preflight-checks/outputs/curly.942491079.gfpgan.png b/docs/assets/preflight-checks/outputs/curly.942491079.gfpgan.png new file mode 100644 index 0000000000..fa39975e74 Binary files /dev/null and b/docs/assets/preflight-checks/outputs/curly.942491079.gfpgan.png differ diff --git a/docs/assets/preflight-checks/outputs/curly.942491079.outcrop-01.png b/docs/assets/preflight-checks/outputs/curly.942491079.outcrop-01.png new file mode 100644 index 0000000000..42778777c0 Binary files /dev/null and b/docs/assets/preflight-checks/outputs/curly.942491079.outcrop-01.png differ diff --git a/docs/assets/preflight-checks/outputs/curly.942491079.outcrop.png b/docs/assets/preflight-checks/outputs/curly.942491079.outcrop.png new file mode 100644 index 0000000000..55a0d1f63b Binary files /dev/null and b/docs/assets/preflight-checks/outputs/curly.942491079.outcrop.png differ diff --git a/docs/assets/preflight-checks/outputs/curly.942491079.outpaint.png b/docs/assets/preflight-checks/outputs/curly.942491079.outpaint.png new file mode 100644 index 0000000000..c1db6c4bb9 Binary files /dev/null and b/docs/assets/preflight-checks/outputs/curly.942491079.outpaint.png differ diff --git a/docs/assets/preflight-checks/outputs/invoke_log.md b/docs/assets/preflight-checks/outputs/invoke_log.md new file mode 100644 index 0000000000..75ab95e49c --- /dev/null +++ b/docs/assets/preflight-checks/outputs/invoke_log.md @@ -0,0 +1,116 @@ +## 000001.1863159593.png +![](000001.1863159593.png) + +banana sushi -s 50 -S 1863159593 -W 512 -H 512 -C 7.5 -A k_lms +## 000002.1151955949.png +![](000002.1151955949.png) + +banana sushi -s 50 -S 1151955949 -W 512 -H 512 -C 7.5 -A plms +## 000003.2736230502.png +![](000003.2736230502.png) + +banana sushi -s 50 -S 2736230502 -W 512 -H 512 -C 7.5 -A ddim +## 000004.42.png +![](000004.42.png) + +banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms +## 000005.42.png +![](000005.42.png) + +banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms +## 000006.478163327.png +![](000006.478163327.png) + +banana sushi -s 50 -S 478163327 -W 640 -H 448 -C 7.5 -A k_lms +## 000007.2407640369.png +![](000007.2407640369.png) + +banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms -V 2407640369:0.1 +## 000008.2772421987.png +![](000008.2772421987.png) + +banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms -V 2772421987:0.1 +## 000009.3532317557.png +![](000009.3532317557.png) + +banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms -V 3532317557:0.1 +## 000010.2028635318.png +![](000010.2028635318.png) + +banana sushi -s 50 -S 2028635318 -W 512 -H 512 -C 7.5 -A k_lms +## 000011.1111168647.png +![](000011.1111168647.png) + +pond with waterlillies -s 50 -S 1111168647 -W 512 -H 512 -C 7.5 -A k_lms +## 000012.1476370516.png +![](000012.1476370516.png) + +pond with waterlillies -s 50 -S 1476370516 -W 512 -H 512 -C 7.5 -A k_lms +## 000013.4281108706.png +![](000013.4281108706.png) + +banana sushi -s 50 -S 4281108706 -W 960 -H 960 -C 7.5 -A k_lms +## 000014.2396987386.png +![](000014.2396987386.png) + +old sea captain with crow on shoulder -s 50 -S 2396987386 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512.png -A k_lms -f 0.75 +## 000015.1252923272.png +![](000015.1252923272.png) + +old sea captain with crow on shoulder -s 50 -S 1252923272 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512-transparent.png -A k_lms -f 0.75 +## 000016.2633891320.png +![](000016.2633891320.png) + +old sea captain with crow on shoulder -s 50 -S 2633891320 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512.png -A plms -f 0.75 +## 000017.1134411920.png +![](000017.1134411920.png) + +old sea captain with crow on shoulder -s 50 -S 1134411920 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512.png -A k_euler_a -f 0.75 +## 000018.47.png +![](000018.47.png) + +big red dog playing with cat -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms +## 000019.47.png +![](000019.47.png) + +big red++++ dog playing with cat -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms +## 000020.47.png +![](000020.47.png) + +big red dog playing with cat+++ -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms +## 000021.47.png +![](000021.47.png) + +big (red dog).swap(tiger) playing with cat -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms +## 000022.47.png +![](000022.47.png) + +dog:1,cat:2 -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms +## 000023.47.png +![](000023.47.png) + +dog:2,cat:1 -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms +## 000024.1029061431.png +![](000024.1029061431.png) + +medusa with cobras -s 50 -S 1029061431 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/curly.png -A k_lms -f 0.75 -tm hair +## 000025.1284519352.png +![](000025.1284519352.png) + +bearded man -s 50 -S 1284519352 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/curly.png -A k_lms -f 0.75 -tm face +## curly.942491079.gfpgan.png +![](curly.942491079.gfpgan.png) + +!fix ./docs/assets/preflight-checks/inputs/curly.png -s 50 -S 942491079 -W 512 -H 512 -C 7.5 -A k_lms -G 0.8 -ft gfpgan -U 2.0 0.75 +## curly.942491079.outcrop.png +![](curly.942491079.outcrop.png) + +!fix ./docs/assets/preflight-checks/inputs/curly.png -s 50 -S 942491079 -W 512 -H 512 -C 7.5 -A k_lms -c top 64 +## curly.942491079.outpaint.png +![](curly.942491079.outpaint.png) + +!fix ./docs/assets/preflight-checks/inputs/curly.png -s 50 -S 942491079 -W 512 -H 512 -C 7.5 -A k_lms -D top 64 +## curly.942491079.outcrop-01.png +![](curly.942491079.outcrop-01.png) + +!fix ./docs/assets/preflight-checks/inputs/curly.png -s 50 -S 942491079 -W 512 -H 512 -C 7.5 -A k_lms -c top 64 diff --git a/docs/assets/preflight-checks/outputs/invoke_log.txt b/docs/assets/preflight-checks/outputs/invoke_log.txt new file mode 100644 index 0000000000..081afe2822 --- /dev/null +++ b/docs/assets/preflight-checks/outputs/invoke_log.txt @@ -0,0 +1,29 @@ +outputs/preflight/000001.1863159593.png: banana sushi -s 50 -S 1863159593 -W 512 -H 512 -C 7.5 -A k_lms +outputs/preflight/000002.1151955949.png: banana sushi -s 50 -S 1151955949 -W 512 -H 512 -C 7.5 -A plms +outputs/preflight/000003.2736230502.png: banana sushi -s 50 -S 2736230502 -W 512 -H 512 -C 7.5 -A ddim +outputs/preflight/000004.42.png: banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms +outputs/preflight/000005.42.png: banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms +outputs/preflight/000006.478163327.png: banana sushi -s 50 -S 478163327 -W 640 -H 448 -C 7.5 -A k_lms +outputs/preflight/000007.2407640369.png: banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms -V 2407640369:0.1 +outputs/preflight/000008.2772421987.png: banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms -V 2772421987:0.1 +outputs/preflight/000009.3532317557.png: banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms -V 3532317557:0.1 +outputs/preflight/000010.2028635318.png: banana sushi -s 50 -S 2028635318 -W 512 -H 512 -C 7.5 -A k_lms +outputs/preflight/000011.1111168647.png: pond with waterlillies -s 50 -S 1111168647 -W 512 -H 512 -C 7.5 -A k_lms +outputs/preflight/000012.1476370516.png: pond with waterlillies -s 50 -S 1476370516 -W 512 -H 512 -C 7.5 -A k_lms +outputs/preflight/000013.4281108706.png: banana sushi -s 50 -S 4281108706 -W 960 -H 960 -C 7.5 -A k_lms +outputs/preflight/000014.2396987386.png: old sea captain with crow on shoulder -s 50 -S 2396987386 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512.png -A k_lms -f 0.75 +outputs/preflight/000015.1252923272.png: old sea captain with crow on shoulder -s 50 -S 1252923272 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512-transparent.png -A k_lms -f 0.75 +outputs/preflight/000016.2633891320.png: old sea captain with crow on shoulder -s 50 -S 2633891320 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512.png -A plms -f 0.75 +outputs/preflight/000017.1134411920.png: old sea captain with crow on shoulder -s 50 -S 1134411920 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512.png -A k_euler_a -f 0.75 +outputs/preflight/000018.47.png: big red dog playing with cat -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms +outputs/preflight/000019.47.png: big red++++ dog playing with cat -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms +outputs/preflight/000020.47.png: big red dog playing with cat+++ -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms +outputs/preflight/000021.47.png: big (red dog).swap(tiger) playing with cat -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms +outputs/preflight/000022.47.png: dog:1,cat:2 -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms +outputs/preflight/000023.47.png: dog:2,cat:1 -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms +outputs/preflight/000024.1029061431.png: medusa with cobras -s 50 -S 1029061431 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/curly.png -A k_lms -f 0.75 -tm hair +outputs/preflight/000025.1284519352.png: bearded man -s 50 -S 1284519352 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/curly.png -A k_lms -f 0.75 -tm face +outputs/preflight/curly.942491079.gfpgan.png: !fix ./docs/assets/preflight-checks/inputs/curly.png -s 50 -S 942491079 -W 512 -H 512 -C 7.5 -A k_lms -G 0.8 -ft gfpgan -U 2.0 0.75 +outputs/preflight/curly.942491079.outcrop.png: !fix ./docs/assets/preflight-checks/inputs/curly.png -s 50 -S 942491079 -W 512 -H 512 -C 7.5 -A k_lms -c top 64 +outputs/preflight/curly.942491079.outpaint.png: !fix ./docs/assets/preflight-checks/inputs/curly.png -s 50 -S 942491079 -W 512 -H 512 -C 7.5 -A k_lms -D top 64 +outputs/preflight/curly.942491079.outcrop-01.png: !fix ./docs/assets/preflight-checks/inputs/curly.png -s 50 -S 942491079 -W 512 -H 512 -C 7.5 -A k_lms -c top 64 diff --git a/docs/assets/preflight-checks/preflight_prompts.txt b/docs/assets/preflight-checks/preflight_prompts.txt new file mode 100644 index 0000000000..3ec421e9e9 --- /dev/null +++ b/docs/assets/preflight-checks/preflight_prompts.txt @@ -0,0 +1,61 @@ +# outputs/preflight/000001.1863159593.png +banana sushi -s 50 -S 1863159593 -W 512 -H 512 -C 7.5 -A k_lms +# outputs/preflight/000002.1151955949.png +banana sushi -s 50 -S 1151955949 -W 512 -H 512 -C 7.5 -A plms +# outputs/preflight/000003.2736230502.png +banana sushi -s 50 -S 2736230502 -W 512 -H 512 -C 7.5 -A ddim +# outputs/preflight/000004.42.png +banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms +# outputs/preflight/000005.42.png +banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms +# outputs/preflight/000006.478163327.png +banana sushi -s 50 -S 478163327 -W 640 -H 448 -C 7.5 -A k_lms +# outputs/preflight/000007.2407640369.png +banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms -V 2407640369:0.1 +# outputs/preflight/000007.2772421987.png +banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms -V 2772421987:0.1 +# outputs/preflight/000007.3532317557.png +banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms -V 3532317557:0.1 +# outputs/preflight/000008.2028635318.png +banana sushi -s 50 -S 2028635318 -W 512 -H 512 -C 7.5 -A k_lms +# outputs/preflight/000009.1111168647.png +pond with waterlillies -s 50 -S 1111168647 -W 512 -H 512 -C 7.5 -A k_lms +# outputs/preflight/000010.1476370516.png +pond with waterlillies -s 50 -S 1476370516 -W 512 -H 512 -C 7.5 -A k_lms --seamless +# outputs/preflight/000011.4281108706.png +banana sushi -s 50 -S 4281108706 -W 960 -H 960 -C 7.5 -A k_lms +# outputs/preflight/000012.2396987386.png +old sea captain with crow on shoulder -s 50 -S 2396987386 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512.png -A k_lms -f 0.75 +# outputs/preflight/000013.1252923272.png +old sea captain with crow on shoulder -s 50 -S 1252923272 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512-transparent.png -A k_lms -f 0.75 +# outputs/preflight/000014.2633891320.png +old sea captain with crow on shoulder -s 50 -S 2633891320 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512.png -A plms -f 0.75 +# outputs/preflight/000015.1134411920.png +old sea captain with crow on shoulder -s 50 -S 1134411920 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512.png -A k_euler_a -f 0.75 +# outputs/preflight/000016.42.png +big red dog playing with cat -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms +# outputs/preflight/000017.42.png +big red++++ dog playing with cat -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms +# outputs/preflight/000018.42.png +big red dog playing with cat+++ -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms +# outputs/preflight/000019.42.png +big (red dog).swap(tiger) playing with cat -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms +# outputs/preflight/000020.42.png +dog:1,cat:2 -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms +# outputs/preflight/000021.42.png +dog:2,cat:1 -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms +# outputs/preflight/000022.1029061431.png +medusa with cobras -s 50 -S 1029061431 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/curly.png -A k_lms -f 0.75 -tm hair +# outputs/preflight/000023.1284519352.png +bearded man -s 50 -S 1284519352 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/curly.png -A k_lms -f 0.75 -tm face +# outputs/preflight/000024.curly.hair.deselected.png +!mask -I docs/assets/preflight-checks/inputs/curly.png -tm hair +# outputs/preflight/curly.942491079.gfpgan.png +!fix ./docs/assets/preflight-checks/inputs/curly.png -U2 -G0.8 +# outputs/preflight/curly.942491079.outcrop.png +!fix ./docs/assets/preflight-checks/inputs/curly.png -c top 64 +# outputs/preflight/curly.942491079.outpaint.png +!fix ./docs/assets/preflight-checks/inputs/curly.png -D top 64 +# outputs/preflight/curly.942491079.outcrop-01.png +!switch inpainting-1.5 +!fix ./docs/assets/preflight-checks/inputs/curly.png -c top 64 diff --git a/docs/assets/prompt-blending/blue-sphere-0.25-red-cube-0.75-hybrid.png b/docs/assets/prompt-blending/blue-sphere-0.25-red-cube-0.75-hybrid.png new file mode 100644 index 0000000000..854c804639 Binary files /dev/null and b/docs/assets/prompt-blending/blue-sphere-0.25-red-cube-0.75-hybrid.png differ diff --git a/docs/assets/prompt-blending/blue-sphere-0.5-red-cube-0.5-hybrid.png b/docs/assets/prompt-blending/blue-sphere-0.5-red-cube-0.5-hybrid.png new file mode 100644 index 0000000000..80d75aa84d Binary files /dev/null and b/docs/assets/prompt-blending/blue-sphere-0.5-red-cube-0.5-hybrid.png differ diff --git a/docs/assets/prompt-blending/blue-sphere-0.5-red-cube-0.5.png b/docs/assets/prompt-blending/blue-sphere-0.5-red-cube-0.5.png new file mode 100644 index 0000000000..d0cb8e389e Binary files /dev/null and b/docs/assets/prompt-blending/blue-sphere-0.5-red-cube-0.5.png differ diff --git a/docs/assets/prompt-blending/blue-sphere-0.75-red-cube-0.25-hybrid.png b/docs/assets/prompt-blending/blue-sphere-0.75-red-cube-0.25-hybrid.png new file mode 100644 index 0000000000..29b5a7fdcf Binary files /dev/null and b/docs/assets/prompt-blending/blue-sphere-0.75-red-cube-0.25-hybrid.png differ diff --git a/docs/assets/prompt-blending/blue-sphere-red-cube-hybrid.png b/docs/assets/prompt-blending/blue-sphere-red-cube-hybrid.png new file mode 100644 index 0000000000..f844e5937a Binary files /dev/null and b/docs/assets/prompt-blending/blue-sphere-red-cube-hybrid.png differ diff --git a/docs/assets/prompt_syntax/apricots--1.png b/docs/assets/prompt_syntax/apricots--1.png new file mode 100644 index 0000000000..0f0c17f08b Binary files /dev/null and b/docs/assets/prompt_syntax/apricots--1.png differ diff --git a/docs/assets/prompt_syntax/apricots--2.png b/docs/assets/prompt_syntax/apricots--2.png new file mode 100644 index 0000000000..5c519b09ae Binary files /dev/null and b/docs/assets/prompt_syntax/apricots--2.png differ diff --git a/docs/assets/prompt_syntax/apricots--3.png b/docs/assets/prompt_syntax/apricots--3.png new file mode 100644 index 0000000000..c98ffd8b07 Binary files /dev/null and b/docs/assets/prompt_syntax/apricots--3.png differ diff --git a/docs/assets/prompt_syntax/apricots-0.png b/docs/assets/prompt_syntax/apricots-0.png new file mode 100644 index 0000000000..f8ead74db2 Binary files /dev/null and b/docs/assets/prompt_syntax/apricots-0.png differ diff --git a/docs/assets/prompt_syntax/apricots-1.png b/docs/assets/prompt_syntax/apricots-1.png new file mode 100644 index 0000000000..75ff7a24a3 Binary files /dev/null and b/docs/assets/prompt_syntax/apricots-1.png differ diff --git a/docs/assets/prompt_syntax/apricots-2.png b/docs/assets/prompt_syntax/apricots-2.png new file mode 100644 index 0000000000..e24ced7637 Binary files /dev/null and b/docs/assets/prompt_syntax/apricots-2.png differ diff --git a/docs/assets/prompt_syntax/apricots-3.png b/docs/assets/prompt_syntax/apricots-3.png new file mode 100644 index 0000000000..d6edf5073c Binary files /dev/null and b/docs/assets/prompt_syntax/apricots-3.png differ diff --git a/docs/assets/prompt_syntax/apricots-4.png b/docs/assets/prompt_syntax/apricots-4.png new file mode 100644 index 0000000000..291c5a1b03 Binary files /dev/null and b/docs/assets/prompt_syntax/apricots-4.png differ diff --git a/docs/assets/prompt_syntax/apricots-5.png b/docs/assets/prompt_syntax/apricots-5.png new file mode 100644 index 0000000000..c71b857837 Binary files /dev/null and b/docs/assets/prompt_syntax/apricots-5.png differ diff --git a/docs/assets/prompt_syntax/mountain-man.png b/docs/assets/prompt_syntax/mountain-man.png new file mode 100644 index 0000000000..4bfa5817b8 Binary files /dev/null and b/docs/assets/prompt_syntax/mountain-man.png differ diff --git a/docs/assets/prompt_syntax/mountain-man1.png b/docs/assets/prompt_syntax/mountain-man1.png new file mode 100644 index 0000000000..5ed98162d3 Binary files /dev/null and b/docs/assets/prompt_syntax/mountain-man1.png differ diff --git a/docs/assets/prompt_syntax/mountain-man2.png b/docs/assets/prompt_syntax/mountain-man2.png new file mode 100644 index 0000000000..d4466514de Binary files /dev/null and b/docs/assets/prompt_syntax/mountain-man2.png differ diff --git a/docs/assets/prompt_syntax/mountain-man3.png b/docs/assets/prompt_syntax/mountain-man3.png new file mode 100644 index 0000000000..3196c5ca96 Binary files /dev/null and b/docs/assets/prompt_syntax/mountain-man3.png differ diff --git a/docs/assets/prompt_syntax/mountain-man4.png b/docs/assets/prompt_syntax/mountain-man4.png new file mode 100644 index 0000000000..69522dba23 Binary files /dev/null and b/docs/assets/prompt_syntax/mountain-man4.png differ diff --git a/docs/assets/prompt_syntax/mountain1-man.png b/docs/assets/prompt_syntax/mountain1-man.png new file mode 100644 index 0000000000..b5952d02f9 Binary files /dev/null and b/docs/assets/prompt_syntax/mountain1-man.png differ diff --git a/docs/assets/prompt_syntax/mountain2-man.png b/docs/assets/prompt_syntax/mountain2-man.png new file mode 100644 index 0000000000..8ab55ff2a7 Binary files /dev/null and b/docs/assets/prompt_syntax/mountain2-man.png differ diff --git a/docs/assets/prompt_syntax/mountain3-man.png b/docs/assets/prompt_syntax/mountain3-man.png new file mode 100644 index 0000000000..c1024b0a63 Binary files /dev/null and b/docs/assets/prompt_syntax/mountain3-man.png differ diff --git a/assets/stable-samples/img2img/mountains-2.png b/docs/assets/stable-samples/img2img/mountains-2.png similarity index 100% rename from assets/stable-samples/img2img/mountains-2.png rename to docs/assets/stable-samples/img2img/mountains-2.png diff --git a/assets/stable-samples/img2img/mountains-3.png b/docs/assets/stable-samples/img2img/mountains-3.png similarity index 100% rename from assets/stable-samples/img2img/mountains-3.png rename to docs/assets/stable-samples/img2img/mountains-3.png diff --git a/assets/stable-samples/img2img/sketch-mountains-input.jpg b/docs/assets/stable-samples/img2img/sketch-mountains-input.jpg similarity index 100% rename from assets/stable-samples/img2img/sketch-mountains-input.jpg rename to docs/assets/stable-samples/img2img/sketch-mountains-input.jpg diff --git a/assets/stable-samples/txt2img/merged-0005.png b/docs/assets/stable-samples/txt2img/merged-0005.png similarity index 100% rename from assets/stable-samples/txt2img/merged-0005.png rename to docs/assets/stable-samples/txt2img/merged-0005.png diff --git a/assets/stable-samples/txt2img/merged-0006.png b/docs/assets/stable-samples/txt2img/merged-0006.png similarity index 100% rename from assets/stable-samples/txt2img/merged-0006.png rename to docs/assets/stable-samples/txt2img/merged-0006.png diff --git a/assets/stable-samples/txt2img/merged-0007.png b/docs/assets/stable-samples/txt2img/merged-0007.png similarity index 100% rename from assets/stable-samples/txt2img/merged-0007.png rename to docs/assets/stable-samples/txt2img/merged-0007.png diff --git a/docs/assets/still-life-inpainted.png b/docs/assets/still-life-inpainted.png new file mode 100644 index 0000000000..ab8c7bd69a Binary files /dev/null and b/docs/assets/still-life-inpainted.png differ diff --git a/docs/assets/still-life-scaled.jpg b/docs/assets/still-life-scaled.jpg new file mode 100644 index 0000000000..ba9c86be00 Binary files /dev/null and b/docs/assets/still-life-scaled.jpg differ diff --git a/docs/assets/truncation_comparison.jpg b/docs/assets/truncation_comparison.jpg new file mode 100644 index 0000000000..a39a804beb Binary files /dev/null and b/docs/assets/truncation_comparison.jpg differ diff --git a/assets/v1-variants-scores.jpg b/docs/assets/v1-variants-scores.jpg similarity index 100% rename from assets/v1-variants-scores.jpg rename to docs/assets/v1-variants-scores.jpg diff --git a/docs/features/CLI.md b/docs/features/CLI.md index d809d48841..26d0ecc8d5 100644 --- a/docs/features/CLI.md +++ b/docs/features/CLI.md @@ -1,228 +1,569 @@ -# **Interactive Command-Line Interface** +--- +title: CLI +hide: + - toc +--- -The `dream.py` script, located in `scripts/dream.py`, provides an interactive interface to image generation similar to the "dream mothership" bot that Stable AI provided on its Discord server. +# :material-bash: CLI -Unlike the txt2img.py and img2img.py scripts provided in the original CompViz/stable-diffusion source code repository, the time-consuming initialization of the AI model initialization only happens once. After that image generation -from the command-line interface is very fast. +## **Interactive Command Line Interface** -The script uses the readline library to allow for in-line editing, command history (up and down arrows), autocompletion, and more. To help keep track of which prompts generated which images, the script writes a log file of image names and prompts to the selected output directory. +The `invoke.py` script, located in `scripts/`, provides an interactive interface +to image generation similar to the "invoke mothership" bot that Stable AI +provided on its Discord server. -In addition, as of version 1.02, it also writes the prompt into the PNG file's metadata where it can be retrieved using scripts/images2prompt.py +Unlike the `txt2img.py` and `img2img.py` scripts provided in the original +[CompVis/stable-diffusion](https://github.com/CompVis/stable-diffusion) source +code repository, the time-consuming initialization of the AI model +initialization only happens once. After that image generation from the +command-line interface is very fast. + +The script uses the readline library to allow for in-line editing, command +history (++up++ and ++down++), autocompletion, and more. To help keep track of +which prompts generated which images, the script writes a log file of image +names and prompts to the selected output directory. + +In addition, as of version 1.02, it also writes the prompt into the PNG file's +metadata where it can be retrieved using `scripts/images2prompt.py` The script is confirmed to work on Linux, Windows and Mac systems. -_Note:_ This script runs from the command-line or can be used as a Web application. The Web GUI is currently rudimentary, but a much better replacement is on its way. +!!! note -``` -(ldm) ~/stable-diffusion$ python3 ./scripts/dream.py + This script runs from the command-line or can be used as a Web application. The Web GUI is + currently rudimentary, but a much better replacement is on its way. + +```bash +(invokeai) ~/stable-diffusion$ python3 ./scripts/invoke.py * Initializing, be patient... Loading model from models/ldm/text2img-large/model.ckpt (...more initialization messages...) * Initialization done! Awaiting your command... -dream> ashley judd riding a camel -n2 -s150 +invoke> ashley judd riding a camel -n2 -s150 Outputs: outputs/img-samples/00009.png: "ashley judd riding a camel" -n2 -s150 -S 416354203 outputs/img-samples/00010.png: "ashley judd riding a camel" -n2 -s150 -S 1362479620 -dream> "there's a fly in my soup" -n6 -g +invoke> "there's a fly in my soup" -n6 -g outputs/img-samples/00011.png: "there's a fly in my soup" -n6 -g -S 2685670268 seeds for individual rows: [2685670268, 1216708065, 2335773498, 822223658, 714542046, 3395302430] -dream> q +invoke> q # this shows how to retrieve the prompt stored in the saved image's metadata -(ldm) ~/stable-diffusion$ python ./scripts/images2prompt.py outputs/img_samples/*.png +(invokeai) ~/stable-diffusion$ python ./scripts/images2prompt.py outputs/img_samples/*.png 00009.png: "ashley judd riding a camel" -s150 -S 416354203 00010.png: "ashley judd riding a camel" -s150 -S 1362479620 00011.png: "there's a fly in my soup" -n6 -g -S 2685670268 ``` -

- -

+![invoke-py-demo](../assets/dream-py-demo.png) -The `dream>` prompt's arguments are pretty much identical to those -used in the Discord bot, except you don't need to type "!dream" (it -doesn't hurt if you do). A significant change is that creation of -individual images is now the default unless --grid (-g) is given. A -full list is given in [List of prompt arguments] -(#list-of-prompt-arguments). +The `invoke>` prompt's arguments are pretty much identical to those used in the +Discord bot, except you don't need to type `!invoke` (it doesn't hurt if you +do). A significant change is that creation of individual images is now the +default unless `--grid` (`-g`) is given. A full list is given in +[List of prompt arguments](#list-of-prompt-arguments). -# Arguments +## Arguments -The script itself also recognizes a series of command-line switches -that will change important global defaults, such as the directory for -image outputs and the location of the model weight files. +The script itself also recognizes a series of command-line switches that will +change important global defaults, such as the directory for image outputs and +the location of the model weight files. -## List of arguments recognized at the command line: +### List of arguments recognized at the command line -These command-line arguments can be passed to dream.py when you first -run it from the Windows, Mac or Linux command line. Some set defaults -that can be overridden on a per-prompt basis (see [List of prompt -arguments] (#list-of-prompt-arguments). Others +These command-line arguments can be passed to `invoke.py` when you first run it +from the Windows, Mac or Linux command line. Some set defaults that can be +overridden on a per-prompt basis (see +[List of prompt arguments](#list-of-prompt-arguments). Others -| Argument | Shortcut | Default | Description | -|--------------------|------------|---------------------|--------------| -| --help | -h | | Print a concise help message. | -| --outdir | -o | outputs/img_samples | Location for generated images. | -| --prompt_as_dir | -p | False | Name output directories using the prompt text. | -| --from_file | | None | Read list of prompts from a file. Use "-" to read from standard input | -| --model | | stable-diffusion-1.4| Loads model specified in configs/models.yaml. Currently one of "stable-diffusion-1.4" or "laion400m"| -| --full_precision | -F | False | Run in slower full-precision mode. Needed for Macintosh M1/M2 hardware and some older video cards. | -| --web | | False | Start in web server mode | -| --host | | localhost | Which network interface web server should listen on. Set to 0.0.0.0 to listen on any. | -| --port | | 9090 | Which port web server should listen for requests on. | -| --config | | configs/models.yaml | Configuration file for models and their weights. | -| --iterations | -n | 1 | How many images to generate per prompt. | -| --grid | -g | False | Save all image series as a grid rather than individually. | -| --sampler | -A| k_lms | Sampler to use. Use -h to get list of available samplers. | -| --seamless | | False | Create interesting effects by tiling elements of the image. | -| --embedding_path | | None | Path to pre-trained embedding manager checkpoints, for custom models | -| --gfpgan_dir | | src/gfpgan | Path to where GFPGAN is installed. | -| --gfpgan_model_path| | experiments/pretrained_models/GFPGANv1.3.pth| Path to GFPGAN model file, relative to --gfpgan_dir. | -| --device | -d| torch.cuda.current_device() | Device to run SD on, e.g. "cuda:0" | +| Argument | Shortcut | Default | Description | +| ----------------------------------------- | ----------------------------------------- | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------- | +| `--help` | `-h` | | Print a concise help message. | +| `--outdir ` | `-o` | `outputs/img_samples` | Location for generated images. | +| `--prompt_as_dir` | `-p` | `False` | Name output directories using the prompt text. | +| `--from_file ` | | `None` | Read list of prompts from a file. Use `-` to read from standard input | +| `--model ` | | `stable-diffusion-1.4` | Loads model specified in configs/models.yaml. Currently one of "stable-diffusion-1.4" or "laion400m" | +| `--full_precision` | `-F` | `False` | Run in slower full-precision mode. Needed for Macintosh M1/M2 hardware and some older video cards. | +| `--png_compression <0-9>` | `-z<0-9>` | `6` | Select level of compression for output files, from 0 (no compression) to 9 (max compression) | +| `--safety-checker` | | `False` | Activate safety checker for NSFW and other potentially disturbing imagery | +| `--web` | | `False` | Start in web server mode | +| `--host ` | | `localhost` | Which network interface web server should listen on. Set to 0.0.0.0 to listen on any. | +| `--port ` | | `9090` | Which port web server should listen for requests on. | +| `--config ` | | `configs/models.yaml` | Configuration file for models and their weights. | +| `--iterations ` | `-n` | `1` | How many images to generate per prompt. | +| `--grid` | `-g` | `False` | Save all image series as a grid rather than individually. | +| `--sampler ` | `-A` | `k_lms` | Sampler to use. Use `-h` to get list of available samplers. | +| `--seamless` | | `False` | Create interesting effects by tiling elements of the image. | +| `--embedding_path ` | | `None` | Path to pre-trained embedding manager checkpoints, for custom models | +| `--gfpgan_dir` | | `src/gfpgan` | Path to where GFPGAN is installed. | +| `--gfpgan_model_path` | | `experiments/pretrained_models/GFPGANv1.4.pth` | Path to GFPGAN model file, relative to `--gfpgan_dir`. | +| `--free_gpu_mem` | | `False` | Free GPU memory after sampling, to allow image decoding and saving in low VRAM conditions | +| `--precision` | | `auto` | Set model precision, default is selected by device. Options: auto, float32, float16, autocast | -These arguments are deprecated but still work: +!!! warning "These arguments are deprecated but still work" -| Argument | Shortcut | Default | Description | -|--------------------|------------|---------------------|--------------| -| --weights | | None | Pth to weights file; use `--model stable-diffusion-1.4` instead | -| --laion400m | -l | False | Use older LAION400m weights; use `--model=laion400m` instead | +
-**A note on path names:** On Windows systems, you may run into - problems when passing the dream script standard backslashed path - names because the Python interpreter treats "\" as an escape. - You can either double your slashes (ick): C:\\\\path\\\\to\\\\my\\\\file, or - use Linux/Mac style forward slashes (better): C:/path/to/my/file. + | Argument | Shortcut | Default | Description | + |--------------------|------------|---------------------|--------------| + | `--weights ` | | `None` | Pth to weights file; use `--model stable-diffusion-1.4` instead | + | `--laion400m` | `-l` | `False` | Use older LAION400m weights; use `--model=laion400m` instead | + +
+ +!!! tip + + On Windows systems, you may run into + problems when passing the invoke script standard backslashed path + names because the Python interpreter treats "\" as an escape. + You can either double your slashes (ick): `C:\\path\\to\\my\\file`, or + use Linux/Mac style forward slashes (better): `C:/path/to/my/file`. ## List of prompt arguments -After the dream.py script initializes, it will present you with a -**dream>** prompt. Here you can enter information to generate images -from text (txt2img), to embellish an existing image or sketch -(img2img), or to selectively alter chosen regions of the image -(inpainting). +After the invoke.py script initializes, it will present you with a `invoke>` +prompt. Here you can enter information to generate images from text +([txt2img](#txt2img)), to embellish an existing image or sketch +([img2img](#img2img)), or to selectively alter chosen regions of the image +([inpainting](#inpainting)). -### This is an example of txt2img: +### txt2img -~~~~ -dream> waterfall and rainbow -W640 -H480 -~~~~ +!!! example "" -This will create the requested image with the dimensions 640 (width) -and 480 (height). + ```bash + invoke> waterfall and rainbow -W640 -H480 + ``` -Here are the dream> command that apply to txt2img: + This will create the requested image with the dimensions 640 (width) + and 480 (height). -| Argument | Shortcut | Default | Description | -|--------------------|------------|---------------------|--------------| -| "my prompt" | | | Text prompt to use. The quotation marks are optional. | -| --width | -W | 512 | Width of generated image | -| --height | -H | 512 | Height of generated image | -| --iterations | -n | 1 | How many images to generate from this prompt | -| --steps | -s | 50 | How many steps of refinement to apply | -| --cfg_scale | -C | 7.5 | How hard to try to match the prompt to the generated image; any number greater than 0.0 works, but the useful range is roughly 5.0 to 20.0 | -| --seed | -S | None | Set the random seed for the next series of images. This can be used to recreate an image generated previously.| -| --sampler | -A| k_lms | Sampler to use. Use -h to get list of available samplers. | -| --grid | -g | False | Turn on grid mode to return a single image combining all the images generated by this prompt | -| --individual | -i | True | Turn off grid mode (deprecated; leave off --grid instead) | -| --outdir | -o | outputs/img_samples | Temporarily change the location of these images | -| --seamless | | False | Activate seamless tiling for interesting effects | -| --log_tokenization | -t | False | Display a color-coded list of the parsed tokens derived from the prompt | -| --skip_normalization| -x | False | Weighted subprompts will not be normalized. See [Weighted Prompts](./OTHER.md#weighted-prompts) | -| --upscale | -U | -U 1 0.75| Upscale image by magnification factor (2, 4), and set strength of upscaling (0.0-1.0). If strength not set, will default to 0.75. | -| --gfpgan_strength | -G | -G0 | Fix faces using the GFPGAN algorithm; argument indicates how hard the algorithm should try (0.0-1.0) | -| --save_original | -save_orig| False | When upscaling or fixing faces, this will cause the original image to be saved rather than replaced. | -| --variation |-v| 0.0 | Add a bit of noise (0.0=none, 1.0=high) to the image in order to generate a series of variations. Usually used in combination with -S and -n to generate a series a riffs on a starting image. See [Variations](./VARIATIONS.md). | -| --with_variations | -V| None | Combine two or more variations. See [Variations](./VARIATIONS.md) for now to use this. | +Here are the invoke> command that apply to txt2img: -Note that the width and height of the image must be multiples of -64. You can provide different values, but they will be rounded down to -the nearest multiple of 64. +| Argument | Shortcut | Default | Description | +| ----------------------------------------- | ----------------------------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| "my prompt" | | | Text prompt to use. The quotation marks are optional. | +| `--width ` | `-W` | `512` | Width of generated image | +| `--height ` | `-H` | `512` | Height of generated image | +| `--iterations ` | `-n` | `1` | How many images to generate from this prompt | +| `--steps ` | `-s` | `50` | How many steps of refinement to apply | +| `--cfg_scale ` | `-C` | `7.5` | How hard to try to match the prompt to the generated image; any number greater than 1.0 works, but the useful range is roughly 5.0 to 20.0 | +| `--seed ` | `-S` | `None` | Set the random seed for the next series of images. This can be used to recreate an image generated previously. | +| `--sampler ` | `-A` | `k_lms` | Sampler to use. Use -h to get list of available samplers. | +| `--karras_max ` | | `29` | When using k\_\* samplers, set the maximum number of steps before shifting from using the Karras noise schedule (good for low step counts) to the LatentDiffusion noise schedule (good for high step counts) This value is sticky. [29] | +| `--hires_fix` | | | Larger images often have duplication artefacts. This option suppresses duplicates by generating the image at low res, and then using img2img to increase the resolution | +| `--png_compression <0-9>` | `-z<0-9>` | `6` | Select level of compression for output files, from 0 (no compression) to 9 (max compression) | +| `--grid` | `-g` | `False` | Turn on grid mode to return a single image combining all the images generated by this prompt | +| `--individual` | `-i` | `True` | Turn off grid mode (deprecated; leave off --grid instead) | +| `--outdir ` | `-o` | `outputs/img_samples` | Temporarily change the location of these images | +| `--seamless` | | `False` | Activate seamless tiling for interesting effects | +| `--seamless_axes` | | `x,y` | Specify which axes to use circular convolution on. | +| `--log_tokenization` | `-t` | `False` | Display a color-coded list of the parsed tokens derived from the prompt | +| `--skip_normalization` | `-x` | `False` | Weighted subprompts will not be normalized. See [Weighted Prompts](./OTHER.md#weighted-prompts) | +| `--upscale ` | `-U ` | `-U 1 0.75` | Upscale image by magnification factor (2, 4), and set strength of upscaling (0.0-1.0). If strength not set, will default to 0.75. | +| `--facetool_strength ` | `-G ` | `-G0` | Fix faces (defaults to using the GFPGAN algorithm); argument indicates how hard the algorithm should try (0.0-1.0) | +| `--facetool ` | `-ft ` | `-ft gfpgan` | Select face restoration algorithm to use: gfpgan, codeformer | +| `--codeformer_fidelity` | `-cf ` | `0.75` | Used along with CodeFormer. Takes values between 0 and 1. 0 produces high quality but low accuracy. 1 produces high accuracy but low quality | +| `--save_original` | `-save_orig` | `False` | When upscaling or fixing faces, this will cause the original image to be saved rather than replaced. | +| `--variation ` | `-v` | `0.0` | Add a bit of noise (0.0=none, 1.0=high) to the image in order to generate a series of variations. Usually used in combination with `-S` and `-n` to generate a series a riffs on a starting image. See [Variations](./VARIATIONS.md). | +| `--with_variations ` | | `None` | Combine two or more variations. See [Variations](./VARIATIONS.md) for now to use this. | +| `--save_intermediates ` | | `None` | Save the image from every nth step into an "intermediates" folder inside the output directory | +Note that the width and height of the image must be multiples of 64. You can +provide different values, but they will be rounded down to the nearest multiple +of 64. -### This is an example of img2img: +### This is an example of img2img: -~~~~ -dream> waterfall and rainbow -I./vacation-photo.png -W640 -H480 --fit -~~~~ +``` +invoke> waterfall and rainbow -I./vacation-photo.png -W640 -H480 --fit +``` -This will modify the indicated vacation photograph by making it more -like the prompt. Results will vary greatly depending on what is in the -image. We also ask to --fit the image into a box no bigger than -640x480. Otherwise the image size will be identical to the provided -photo and you may run out of memory if it is large. +This will modify the indicated vacation photograph by making it more like the +prompt. Results will vary greatly depending on what is in the image. We also ask +to --fit the image into a box no bigger than 640x480. Otherwise the image size +will be identical to the provided photo and you may run out of memory if it is +large. -In addition to the command-line options recognized by txt2img, img2img -accepts additional options: +In addition to the command-line options recognized by txt2img, img2img accepts +additional options: -| Argument | Shortcut | Default | Description | -|--------------------|------------|---------------------|--------------| -| --init_img | -I | None | Path to the initialization image | -| --fit | -F | False | Scale the image to fit into the specified -H and -W dimensions | -| --strength | -s | 0.75 | How hard to try to match the prompt to the initial image. Ranges from 0.0-0.99, with higher values replacing the initial image completely.| +| Argument | Shortcut | Default | Description | +| ----------------------------------------- | ----------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------ | +| `--init_img ` | `-I` | `None` | Path to the initialization image | +| `--fit` | `-F` | `False` | Scale the image to fit into the specified -H and -W dimensions | +| `--strength ` | `-s` | `0.75` | How hard to try to match the prompt to the initial image. Ranges from 0.0-0.99, with higher values replacing the initial image completely. | -### This is an example of inpainting: +### inpainting -~~~~ -dream> waterfall and rainbow -I./vacation-photo.png -M./vacation-mask.png -W640 -H480 --fit -~~~~ +!!! example "" -This will do the same thing as img2img, but image alterations will -only occur within transparent areas defined by the mask file specified -by -M. You may also supply just a single initial image with the areas -to overpaint made transparent, but you must be careful not to destroy -the pixels underneath when you create the transparent areas. See -[Inpainting](./INPAINTING.md) for details. + ```bash + invoke> waterfall and rainbow -I./vacation-photo.png -M./vacation-mask.png -W640 -H480 --fit + ``` -inpainting accepts all the arguments used for txt2img and img2img, as -well as the --mask (-M) argument: + This will do the same thing as img2img, but image alterations will + only occur within transparent areas defined by the mask file specified + by `-M`. You may also supply just a single initial image with the areas + to overpaint made transparent, but you must be careful not to destroy + the pixels underneath when you create the transparent areas. See + [Inpainting](./INPAINTING.md) for details. -| Argument | Shortcut | Default | Description | -|--------------------|------------|---------------------|--------------| -| --init_mask | -M | None |Path to an image the same size as the initial_image, with areas for inpainting made transparent.| +inpainting accepts all the arguments used for txt2img and img2img, as well as +the --mask (-M) and --text_mask (-tm) arguments: +| Argument | Shortcut | Default | Description | +| ----------------------------------------- | ------------------------ | ------- | ------------------------------------------------------------------------------------------------ | +| `--init_mask ` | `-M` | `None` | Path to an image the same size as the initial_image, with areas for inpainting made transparent. | +| `--invert_mask ` | | False | If true, invert the mask so that transparent areas are opaque and vice versa. | +| `--text_mask []` | `-tm []` | | Create a mask from a text prompt describing part of the image | -# Command-line editing and completion +The mask may either be an image with transparent areas, in which case the +inpainting will occur in the transparent areas only, or a black and white image, +in which case all black areas will be painted into. -If you are on a Macintosh or Linux machine, the command-line offers -convenient history tracking, editing, and command completion. +`--text_mask` (short form `-tm`) is a way to generate a mask using a text +description of the part of the image to replace. For example, if you have an +image of a breakfast plate with a bagel, toast and scrambled eggs, you can +selectively mask the bagel and replace it with a piece of cake this way: -- To scroll through previous commands and potentially edit/reuse them, use the up and down cursor keys. -- To edit the current command, use the left and right cursor keys to position the cursor, and then backspace, delete or insert characters. -- To move to the very beginning of the command, type CTRL-A (or command-A on the Mac) -- To move to the end of the command, type CTRL-E. -- To cut a section of the command, position the cursor where you want to start cutting and type CTRL-K. -- To paste a cut section back in, position the cursor where you want to paste, and type CTRL-Y +``` +invoke> a piece of cake -I /path/to/breakfast.png -tm bagel +``` -Windows users can get similar, but more limited, functionality if they -launch dream.py with the "winpty" program: +The algorithm uses clipseg to classify different +regions of the image. The classifier puts out a confidence score for each region +it identifies. Generally regions that score above 0.5 are reliable, but if you +are getting too much or too little masking you can adjust the threshold down (to +get more mask), or up (to get less). In this example, by passing `-tm` a higher +value, we are insisting on a more stringent classification. -~~~ -> winpty python scripts\dream.py -~~~ +``` +invoke> a piece of cake -I /path/to/breakfast.png -tm bagel 0.6 +``` -On the Mac and Linux platforms, when you exit dream.py, the last 1000 -lines of your command-line history will be saved. When you restart -dream.py, you can access the saved history using the up-arrow key. +# Other Commands -In addition, limited command-line completion is installed. In various -contexts, you can start typing your command and press tab. A list of -potential completions will be presented to you. You can then type a -little more, hit tab again, and eventually autocomplete what you want. +The CLI offers a number of commands that begin with "!". -When specifying file paths using the one-letter shortcuts, the CLI -will attempt to complete pathnames for you. This is most handy for the --I (init image) and -M (init mask) paths. To initiate completion, start -the path with a slash ("/") or "./". For example: +## Postprocessing images -~~~ -dream> zebra with a mustache -I./test-pictures +To postprocess a file using face restoration or upscaling, use the `!fix` +command. + +### `!fix` + +This command runs a post-processor on a previously-generated image. It takes a +PNG filename or path and applies your choice of the `-U`, `-G`, or `--embiggen` +switches in order to fix faces or upscale. If you provide a filename, the script +will look for it in the current output directory. Otherwise you can provide a +full or partial path to the desired file. + +Some examples: + +!!! example "Upscale to 4X its original size and fix faces using codeformer" + + ```bash + invoke> !fix 0000045.4829112.png -G1 -U4 -ft codeformer + ``` + +!!! example "Use the GFPGAN algorithm to fix faces, then upscale to 3X using --embiggen" + + ```bash + invoke> !fix 0000045.4829112.png -G0.8 -ft gfpgan + >> fixing outputs/img-samples/0000045.4829112.png + >> retrieved seed 4829112 and prompt "boy enjoying a banana split" + >> GFPGAN - Restoring Faces for image seed:4829112 + Outputs: + [1] outputs/img-samples/000017.4829112.gfpgan-00.png: !fix "outputs/img-samples/0000045.4829112.png" -s 50 -S -W 512 -H 512 -C 7.5 -A k_lms -G 0.8 + ``` + +### !mask + +This command takes an image, a text prompt, and uses the `clipseg` algorithm to +automatically generate a mask of the area that matches the text prompt. It is +useful for debugging the text masking process prior to inpainting with the +`--text_mask` argument. See [INPAINTING.md] for details. + +## Model selection and importation + +The CLI allows you to add new models on the fly, as well as to switch among them +rapidly without leaving the script. + +### !models + +This prints out a list of the models defined in `config/models.yaml'. The active +model is bold-faced + +Example: + +
+laion400m                 not loaded  
+stable-diffusion-1.4          active  Stable Diffusion v1.4
+waifu-diffusion           not loaded  Waifu Diffusion v1.3
+
+ +### !switch + +This quickly switches from one model to another without leaving the CLI script. +`invoke.py` uses a memory caching system; once a model has been loaded, +switching back and forth is quick. The following example shows this in action. +Note how the second column of the `!models` table changes to `cached` after a +model is first loaded, and that the long initialization step is not needed when +loading a cached model. + +
+invoke> !models
+laion400m                 not loaded  
+stable-diffusion-1.4          cached  Stable Diffusion v1.4
+waifu-diffusion               active  Waifu Diffusion v1.3
+
+invoke> !switch waifu-diffusion
+>> Caching model stable-diffusion-1.4 in system RAM
+>> Loading waifu-diffusion from models/ldm/stable-diffusion-v1/model-epoch08-float16.ckpt
+   | LatentDiffusion: Running in eps-prediction mode
+   | DiffusionWrapper has 859.52 M params.
+   | Making attention of type 'vanilla' with 512 in_channels
+   | Working with z of shape (1, 4, 32, 32) = 4096 dimensions.
+   | Making attention of type 'vanilla' with 512 in_channels
+   | Using faster float16 precision
+>> Model loaded in 18.24s
+>> Max VRAM used to load the model: 2.17G 
+>> Current VRAM usage:2.17G
+>> Setting Sampler to k_lms
+
+invoke> !models
+laion400m                 not loaded  
+stable-diffusion-1.4          cached  Stable Diffusion v1.4
+waifu-diffusion               active  Waifu Diffusion v1.3
+
+invoke> !switch stable-diffusion-1.4
+>> Caching model waifu-diffusion in system RAM
+>> Retrieving model stable-diffusion-1.4 from system RAM cache
+>> Setting Sampler to k_lms
+
+invoke> !models
+laion400m                 not loaded  
+stable-diffusion-1.4          active  Stable Diffusion v1.4
+waifu-diffusion               cached  Waifu Diffusion v1.3
+
+ +### !import_model + +This command imports a new model weights file into InvokeAI, makes it available +for image generation within the script, and writes out the configuration for the +model into `config/models.yaml` for use in subsequent sessions. + +Provide `!import_model` with the path to a weights file ending in `.ckpt`. If +you type a partial path and press tab, the CLI will autocomplete. Although it +will also autocomplete to `.vae` files, these are not currenty supported (but +will be soon). + +When you hit return, the CLI will prompt you to fill in additional information +about the model, including the short name you wish to use for it with the +`!switch` command, a brief description of the model, the default image width and +height to use with this model, and the model's configuration file. The latter +three fields are automatically filled with reasonable defaults. In the example +below, the bold-faced text shows what the user typed in with the exception of +the width, height and configuration file paths, which were filled in +automatically. + +Example: + +
+invoke> !import_model models/ldm/stable-diffusion-v1/model-epoch08-float16.ckpt
+>> Model import in process. Please enter the values needed to configure this model:
+
+Name for this model: waifu-diffusion
+Description of this model: Waifu Diffusion v1.3
+Configuration file for this model: configs/stable-diffusion/v1-inference.yaml
+Default image width: 512
+Default image height: 512
+>> New configuration:
+waifu-diffusion:
+  config: configs/stable-diffusion/v1-inference.yaml
+  description: Waifu Diffusion v1.3
+  height: 512
+  weights: models/ldm/stable-diffusion-v1/model-epoch08-float16.ckpt
+  width: 512
+OK to import [n]? y
+>> Caching model stable-diffusion-1.4 in system RAM
+>> Loading waifu-diffusion from models/ldm/stable-diffusion-v1/model-epoch08-float16.ckpt
+   | LatentDiffusion: Running in eps-prediction mode
+   | DiffusionWrapper has 859.52 M params.
+   | Making attention of type 'vanilla' with 512 in_channels
+   | Working with z of shape (1, 4, 32, 32) = 4096 dimensions.
+   | Making attention of type 'vanilla' with 512 in_channels
+   | Using faster float16 precision
+invoke> 
+
+ +###!edit_model + +The `!edit_model` command can be used to modify a model that is already defined +in `config/models.yaml`. Call it with the short name of the model you wish to +modify, and it will allow you to modify the model's `description`, `weights` and +other fields. + +Example: + +
+invoke> !edit_model waifu-diffusion
+>> Editing model waifu-diffusion from configuration file ./configs/models.yaml
+description: Waifu diffusion v1.4beta
+weights: models/ldm/stable-diffusion-v1/model-epoch10-float16.ckpt
+config: configs/stable-diffusion/v1-inference.yaml
+width: 512
+height: 512
+
+>> New configuration:
+waifu-diffusion:
+  config: configs/stable-diffusion/v1-inference.yaml
+  description: Waifu diffusion v1.4beta
+  weights: models/ldm/stable-diffusion-v1/model-epoch10-float16.ckpt
+  height: 512
+  width: 512
+
+OK to import [n]? y
+>> Caching model stable-diffusion-1.4 in system RAM
+>> Loading waifu-diffusion from models/ldm/stable-diffusion-v1/model-epoch10-float16.ckpt
+...
+
+ +======= invoke> !fix 000017.4829112.gfpgan-00.png --embiggen 3 ...lots of +text... Outputs: [2] outputs/img-samples/000018.2273800735.embiggen-00.png: !fix +"outputs/img-samples/000017.243781548.gfpgan-00.png" -s 50 -S 2273800735 -W 512 +-H 512 -C 7.5 -A k_lms --embiggen 3.0 0.75 0.25 ``` + +## History processing + +The CLI provides a series of convenient commands for reviewing previous actions, +retrieving them, modifying them, and re-running them. + +### !history + +The invoke script keeps track of all the commands you issue during a session, +allowing you to re-run them. On Mac and Linux systems, it also writes the +command-line history out to disk, giving you access to the most recent 1000 +commands issued. + +The `!history` command will return a numbered list of all the commands issued +during the session (Windows), or the most recent 1000 commands (Mac|Linux). You +can then repeat a command by using the command `!NNN`, where "NNN" is the +history line number. For example: + +```bash +invoke> !history +... +[14] happy woman sitting under tree wearing broad hat and flowing garment +[15] beautiful woman sitting under tree wearing broad hat and flowing garment +[18] beautiful woman sitting under tree wearing broad hat and flowing garment -v0.2 -n6 +[20] watercolor of beautiful woman sitting under tree wearing broad hat and flowing garment -v0.2 -n6 -S2878767194 +[21] surrealist painting of beautiful woman sitting under tree wearing broad hat and flowing garment -v0.2 -n6 -S2878767194 +... +invoke> !20 +invoke> watercolor of beautiful woman sitting under tree wearing broad hat and flowing garment -v0.2 -n6 -S2878767194 +``` + +### !fetch + +This command retrieves the generation parameters from a previously generated +image and either loads them into the command line (Linux|Mac), or prints them +out in a comment for copy-and-paste (Windows). You may provide either the name +of a file in the current output directory, or a full file path. Specify path to +a folder with image png files, and wildcard \*.png to retrieve the dream command +used to generate the images, and save them to a file commands.txt for further +processing. + +This example loads the generation command for a single png file: + +```bash +invoke> !fetch 0000015.8929913.png +# the script returns the next line, ready for editing and running: +invoke> a fantastic alien landscape -W 576 -H 512 -s 60 -A plms -C 7.5 +``` + +This one fetches the generation commands from a batch of files and stores them +into `selected.txt`: + +```bash +invoke> !fetch outputs\selected-imgs\*.png selected.txt +``` + +### !replay + +This command replays a text file generated by !fetch or created manually + +``` +invoke> !replay outputs\selected-imgs\selected.txt +``` + +Note that these commands may behave unexpectedly if given a PNG file that was +not generated by InvokeAI. + +### !search + +This is similar to !history but it only returns lines that contain +`search string`. For example: + +```bash +invoke> !search surreal +[21] surrealist painting of beautiful woman sitting under tree wearing broad hat and flowing garment -v0.2 -n6 -S2878767194 +``` + +### `!clear` + +This clears the search history from memory and disk. Be advised that this +operation is irreversible and does not issue any warnings! + +## Command-line editing and completion + +The command-line offers convenient history tracking, editing, and command +completion. + +- To scroll through previous commands and potentially edit/reuse them, use the + ++up++ and ++down++ keys. +- To edit the current command, use the ++left++ and ++right++ keys to position + the cursor, and then ++backspace++, ++delete++ or insert characters. +- To move to the very beginning of the command, type ++ctrl+a++ (or + ++command+a++ on the Mac) +- To move to the end of the command, type ++ctrl+e++. +- To cut a section of the command, position the cursor where you want to start + cutting and type ++ctrl+k++ +- To paste a cut section back in, position the cursor where you want to paste, + and type ++ctrl+y++ + +Windows users can get similar, but more limited, functionality if they launch +`invoke.py` with the `winpty` program and have the `pyreadline3` library +installed: + +```batch +> winpty python scripts\invoke.py +``` + +On the Mac and Linux platforms, when you exit invoke.py, the last 1000 lines of +your command-line history will be saved. When you restart `invoke.py`, you can +access the saved history using the ++up++ key. + +In addition, limited command-line completion is installed. In various contexts, +you can start typing your command and press ++tab++. A list of potential +completions will be presented to you. You can then type a little more, hit +++tab++ again, and eventually autocomplete what you want. + +When specifying file paths using the one-letter shortcuts, the CLI will attempt +to complete pathnames for you. This is most handy for the `-I` (init image) and +`-M` (init mask) paths. To initiate completion, start the path with a slash +(`/`) or `./`. For example: + +```bash +invoke> zebra with a mustache -I./test-pictures -I./test-pictures/Lincoln-and-Parrot.png -I./test-pictures/zebra.jpg -I./test-pictures/madonna.png -I./test-pictures/bad-sketch.png -I./test-pictures/man_with_eagle/ -~~~ +``` -You can then type "z", hit tab again, and it will autofill to "zebra.jpg". +You can then type ++z++, hit ++tab++ again, and it will autofill to `zebra.jpg`. More text completion features (such as autocompleting seeds) are on their way. - diff --git a/docs/features/EMBIGGEN.md b/docs/features/EMBIGGEN.md new file mode 100644 index 0000000000..03b0b9a8a4 --- /dev/null +++ b/docs/features/EMBIGGEN.md @@ -0,0 +1,158 @@ +--- +title: Embiggen +--- + +# :material-loupe: Embiggen + +**upscale your images on limited memory machines** + +GFPGAN and Real-ESRGAN are both memory intensive. In order to avoid +crashes and memory overloads during the Stable Diffusion process, +these effects are applied after Stable Diffusion has completed its +work. + +In single image generations, you will see the output right away but +when you are using multiple iterations, the images will first be +generated and then upscaled and face restored after that process is +complete. While the image generation is taking place, you will still +be able to preview the base images. + +If you wish to stop during the image generation but want to upscale or +face restore a particular generated image, pass it again with the same +prompt and generated seed along with the `-U` and `-G` prompt +arguments to perform those actions. + +## Embiggen + +If you wanted to be able to do more (pixels) without running out of VRAM, +or you want to upscale with details that couldn't possibly appear +without the context of a prompt, this is the feature to try out. + +Embiggen automates the process of taking an init image, upscaling it, +cutting it into smaller tiles that slightly overlap, running all the +tiles through img2img to refine details with respect to the prompt, +and "stitching" the tiles back together into a cohesive image. + +It automatically computes how many tiles are needed, and so it can be fed +*ANY* size init image and perform Img2Img on it (though it will be run only +one tile at a time, which can cause problems, see the Note at the end). + +If you're familiar with "GoBig" (ala [progrock-stable](https://github.com/lowfuel/progrock-stable)) +it's similar to that, except it can work up to an arbitrarily large size +(instead of just 2x), with tile overlaps configurable as a ratio, and +has extra logic to re-run any number of the tile sub-sections of the image +if for example a small part of a huge run got messed up. + +### Usage + +`-embiggen ` + +Takes a scaling factor relative to the size of the `--init_img` (`-I`), followed by +ESRGAN upscaling strength (0 - 1.0), followed by minimum amount of overlap +between tiles as a decimal ratio (0 - 1.0) *OR* a number of pixels. + +The scaling factor is how much larger than the `--init_img` the output +should be, and will multiply both x and y axis, so an image that is a +scaling factor of 3.0 has 3*3= 9 times as many pixels, and will take +(at least) 9 times as long (see overlap for why it might be +longer). If the `--init_img` is already the right size `-embiggen 1`, +and it can also be less than one if the init_img is too big. + +Esrgan_strength defaults to 0.75, and the overlap_ratio defaults to +0.25, both are optional. + +Unlike Img2Img, the `--width` (`-W`) and `--height` (`-H`) arguments +do not control the size of the image as a whole, but the size of the +tiles used to Embiggen the image. + +ESRGAN is used to upscale the `--init_img` prior to cutting it into +tiles/pieces to run through img2img and then stitch back +together. Embiggen can be run without ESRGAN; just set the strength to +zero (e.g. `-embiggen 1.75 0`). The output of Embiggen can also be +upscaled after it's finished (`-U`). + +The overlap is the minimum that tiles will overlap with adjacent +tiles, specified as either a ratio or a number of pixels. How much the +tiles overlap determines the likelihood the tiling will be noticable, +really small overlaps (e.g. a couple of pixels) may produce noticeable +grid-like fuzzy distortions in the final stitched image. Though, as +the overlapping space doesn't contribute to making the image bigger, +and the larger the overlap the more tiles (and the more time) it will +take to finish. + +Because the overlapping parts of tiles don't "contribute" to +increasing size, every tile after the first in a row or column +effectively only covers an extra `1 - overlap_ratio` on each axis. If +the input/`--init_img` is same size as a tile, the ideal (for time) +scaling factors with the default overlap (0.25) are 1.75, 2.5, 3.25, +4.0 etc.. + +`-embiggen_tiles ` + +An advanced usage useful if you only want to alter parts of the image +while running Embiggen. It takes a list of tiles by number to run and +replace onto the initial image e.g. `1 3 5`. It's useful for either +fixing problem spots from a previous Embiggen run, or selectively +altering the prompt for sections of an image - for creative or +coherency reasons. + +Tiles are numbered starting with one, and left-to-right, +top-to-bottom. So, if you are generating a 3x3 tiled image, the +middle row would be `4 5 6`. + +### Examples + +!!! example "" + + Running Embiggen with 512x512 tiles on an existing image, scaling up by a factor of 2.5x; + and doing the same again (default ESRGAN strength is 0.75, default overlap between tiles is 0.25): + + ```bash + invoke > a photo of a forest at sunset -s 100 -W 512 -H 512 -I outputs/forest.png -f 0.4 -embiggen 2.5 + invoke > a photo of a forest at sunset -s 100 -W 512 -H 512 -I outputs/forest.png -f 0.4 -embiggen 2.5 0.75 0.25 + ``` + + If your starting image was also 512x512 this should have taken 9 tiles. + +!!! example "" + + If there weren't enough clouds in the sky of that forest you just made + (and that image is about 1280 pixels (512*2.5) wide A.K.A. three + 512x512 tiles with 0.25 overlaps wide) we can replace that top row of + tiles: + + ```bash + invoke> a photo of puffy clouds over a forest at sunset -s 100 -W 512 -H 512 -I outputs/000002.seed.png -f 0.5 -embiggen_tiles 1 2 3 + ``` + +## Fixing Previously-Generated Images + +It is easy to apply embiggen to any previously-generated file without having to +look up the original prompt and provide an initial image. Just use the +syntax `!fix path/to/file.png `. For example, you can rewrite the +previous command to look like this: + +```bash +invoke> !fix ./outputs/000002.seed.png -embiggen_tiles 1 2 3 +``` + +A new file named `000002.seed.fixed.png` will be created in the output directory. Note that +the `!fix` command does not replace the original file, unlike the behavior at generate time. +You do not need to provide the prompt, and `!fix` automatically selects a good strength for +embiggen-ing. + +!!! note + + Because the same prompt is used on all the tiled images, and the model + doesn't have the context of anything outside the tile being run - it + can end up creating repeated pattern (also called 'motifs') across all + the tiles based on that prompt. The best way to combat this is + lowering the `--strength` (`-f`) to stay more true to the init image, + and increasing the number of steps so there is more compute-time to + create the detail. Anecdotally `--strength` 0.35-0.45 works pretty + well on most things. It may also work great in some examples even with + the `--strength` set high for patterns, landscapes, or subjects that + are more abstract. Because this is (relatively) fast, you can also + preserve the best parts from each. + +Author: [Travco](https://github.com/travco) diff --git a/docs/features/IMG2IMG.md b/docs/features/IMG2IMG.md index ac560f6984..8729ec9410 100644 --- a/docs/features/IMG2IMG.md +++ b/docs/features/IMG2IMG.md @@ -1,30 +1,235 @@ -# **Image-to-Image** +--- +title: Image-to-Image +--- -This script also provides an img2img feature that lets you seed your -creations with an initial drawing or photo. This is a really cool -feature that tells stable diffusion to build the prompt on top of the -image you provide, preserving the original's basic shape and -layout. To use it, provide the `--init_img` option as shown here: +# :material-image-multiple: Image-to-Image -``` -dream> "waterfall and rainbow" --init_img=./init-images/crude_drawing.png --strength=0.5 -s100 -n4 +## `img2img` + +This script also provides an `img2img` feature that lets you seed your creations +with an initial drawing or photo. This is a really cool feature that tells +stable diffusion to build the prompt on top of the image you provide, preserving +the original's basic shape and layout. To use it, provide the `--init_img` +option as shown here: + +```commandline +tree on a hill with a river, nature photograph, national geographic -I./test-pictures/tree-and-river-sketch.png -f 0.85 ``` -The `--init_img (-I)` option gives the path to the seed -picture. `--strength (-f)` controls how much the original will be -modified, ranging from `0.0` (keep the original intact), to `1.0` -(ignore the original completely). The default is `0.75`, and ranges -from `0.25-0.75` give interesting results. +This will take the original image shown here: -You may also pass a `-v` option to generate count variants on -the original image. This is done by passing the first generated image -back into img2img the requested number of times. It generates +
+![](https://user-images.githubusercontent.com/50542132/193946000-c42a96d8-5a74-4f8a-b4c3-5213e6cadcce.png) +
+ +and generate a new image based on it as shown here: + +
+![](https://user-images.githubusercontent.com/111189/194135515-53d4c060-e994-4016-8121-7c685e281ac9.png) +
+ +The `--init_img` (`-I`) option gives the path to the seed picture. `--strength` +(`-f`) controls how much the original will be modified, ranging from `0.0` (keep +the original intact), to `1.0` (ignore the original completely). The default is +`0.75`, and ranges from `0.25-0.90` give interesting results. Other relevant +options include `-C` (classification free guidance scale), and `-s` (steps). +Unlike `txt2img`, adding steps will continuously change the resulting image and +it will not converge. + +You may also pass a `-v` option to generate `-n` +count variants on the original image. This is done by passing the first +generated image back into img2img the requested number of times. It generates interesting variants. -If the initial image contains transparent regions, then Stable -Diffusion will only draw within the transparent regions, a process -called "inpainting". However, for this to work correctly, the color -information underneath the transparent needs to be preserved, not -erased. See [Creating Transparent Images For -Inpainting](./INPAINTING.md#creating-transparent-regions-for-inpainting) -for details. +Note that the prompt makes a big difference. For example, this slight variation +on the prompt produces a very different image: + +
+![](https://user-images.githubusercontent.com/111189/194135220-16b62181-b60c-4248-8989-4834a8fd7fbd.png) +photograph of a tree on a hill with a river +
+ +!!! tip + + When designing prompts, think about how the images scraped from the internet were captioned. Very few photographs will + be labeled "photograph" or "photorealistic." They will, however, be captioned with the publication, photographer, camera + model, or film settings. + +If the initial image contains transparent regions, then Stable Diffusion will +only draw within the transparent regions, a process called +[`inpainting`](./INPAINTING.md#creating-transparent-regions-for-inpainting). +However, for this to work correctly, the color information underneath the +transparent needs to be preserved, not erased. + +!!! warning + +**IMPORTANT ISSUE** `img2img` does not work properly on initial images smaller +than 512x512. Please scale your image to at least 512x512 before using it. +Larger images are not a problem, but may run out of VRAM on your GPU card. To +fix this, use the --fit option, which downscales the initial image to fit within +the box specified by width x height: + +``` +tree on a hill with a river, national geographic -I./test-pictures/big-sketch.png -H512 -W512 --fit +``` + +## How does it actually work, though? + +The main difference between `img2img` and `prompt2img` is the starting point. +While `prompt2img` always starts with pure gaussian noise and progressively +refines it over the requested number of steps, `img2img` skips some of these +earlier steps (how many it skips is indirectly controlled by the `--strength` +parameter), and uses instead your initial image mixed with gaussian noise as the +starting image. + +**Let's start** by thinking about vanilla `prompt2img`, just generating an image +from a prompt. If the step count is 10, then the "latent space" (Stable +Diffusion's internal representation of the image) for the prompt "fire" with +seed `1592514025` develops something like this: + +```commandline +invoke> "fire" -s10 -W384 -H384 -S1592514025 +``` + +
+![latent steps](../assets/img2img/000019.steps.png) +
+ +Put simply: starting from a frame of fuzz/static, SD finds details in each frame +that it thinks look like "fire" and brings them a little bit more into focus, +gradually scrubbing out the fuzz until a clear image remains. + +**When you use `img2img`** some of the earlier steps are cut, and instead an +initial image of your choice is used. But because of how the maths behind Stable +Diffusion works, this image needs to be mixed with just the right amount of +noise (fuzz/static) for where it is being inserted. This is where the strength +parameter comes in. Depending on the set strength, your image will be inserted +into the sequence at the appropriate point, with just the right amount of noise. + +### A concrete example + +I want SD to draw a fire based on this hand-drawn image: + +
+![drawing of a fireplace](../assets/img2img/fire-drawing.png) +
+ +Let's only do 10 steps, to make it easier to see what's happening. If strength +is `0.7`, this is what the internal steps the algorithm has to take will look +like: + +
+![gravity32](../assets/img2img/000032.steps.gravity.png) +
+ +With strength `0.4`, the steps look more like this: + +
+![gravity30](../assets/img2img/000030.steps.gravity.png) +
+ +Notice how much more fuzzy the starting image is for strength `0.7` compared to +`0.4`, and notice also how much longer the sequence is with `0.7`: + +| | strength = 0.7 | strength = 0.4 | +| --------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------- | +| initial image that SD sees | ![](../assets/img2img/000032.step-0.png) | ![](../assets/img2img/000030.step-0.png) | +| steps argument to `invoke>` | `-S10` | `-S10` | +| steps actually taken | 7 | 4 | +| latent space at each step | ![gravity32](../assets/img2img/000032.steps.gravity.png) | ![gravity30](../assets/img2img/000030.steps.gravity.png) | +| output | ![000032.1592514025](../assets/img2img/000032.1592514025.png) | ![000030.1592514025](../assets/img2img/000030.1592514025.png) | + +Both of the outputs look kind of like what I was thinking of. With the strength +higher, my input becomes more vague, _and_ Stable Diffusion has more steps to +refine its output. But it's not really making what I want, which is a picture of +cheery open fire. With the strength lower, my input is more clear, _but_ Stable +Diffusion has less chance to refine itself, so the result ends up inheriting all +the problems of my bad drawing. + +If you want to try this out yourself, all of these are using a seed of +`1592514025` with a width/height of `384`, step count `10`, the default sampler +(`k_lms`), and the single-word prompt `"fire"`: + +```commandline +invoke> "fire" -s10 -W384 -H384 -S1592514025 -I /tmp/fire-drawing.png --strength 0.7 +``` + +The code for rendering intermediates is on my (damian0815's) branch +[document-img2img](https://github.com/damian0815/InvokeAI/tree/document-img2img) - +run `invoke.py` and check your `outputs/img-samples/intermediates` folder while +generating an image. + +### Compensating for the reduced step count + +After putting this guide together I was curious to see how the difference would +be if I increased the step count to compensate, so that SD could have the same +amount of steps to develop the image regardless of the strength. So I ran the +generation again using the same seed, but this time adapting the step count to +give each generation 20 steps. + +Here's strength `0.4` (note step count `50`, which is `20 ÷ 0.4` to make sure SD +does `20` steps from my image): + +```commandline +invoke> "fire" -s50 -W384 -H384 -S1592514025 -I /tmp/fire-drawing.png -f 0.4 +``` + +
+![000035.1592514025](../assets/img2img/000035.1592514025.png) +
+ +and here is strength `0.7` (note step count `30`, which is roughly `20 ÷ 0.7` to +make sure SD does `20` steps from my image): + +```commandline +invoke> "fire" -s30 -W384 -H384 -S1592514025 -I /tmp/fire-drawing.png -f 0.7 +``` + +
+![000046.1592514025](../assets/img2img/000046.1592514025.png) +
+ +In both cases the image is nice and clean and "finished", but because at +strength `0.7` Stable Diffusion has been give so much more freedom to improve on +my badly-drawn flames, they've come out looking much better. You can really see +the difference when looking at the latent steps. There's more noise on the first +image with strength `0.7`: + +
+![gravity46](../assets/img2img/000046.steps.gravity.png) +
+ +than there is for strength `0.4`: + +
+![gravity35](../assets/img2img/000035.steps.gravity.png) +
+ +and that extra noise gives the algorithm more choices when it is evaluating how +to denoise any particular pixel in the image. + +Unfortunately, it seems that `img2img` is very sensitive to the step count. +Here's strength `0.7` with a step count of `29` (SD did 19 steps from my image): + +
+![gravity45](../assets/img2img/000045.1592514025.png) +
+ +By comparing the latents we can sort of see that something got interpreted +differently enough on the third or fourth step to lead to a rather different +interpretation of the flames. + +
+![gravity46](../assets/img2img/000046.steps.gravity.png) +
+ +
+![gravity45](../assets/img2img/000045.steps.gravity.png) +
+ +This is the result of a difference in the de-noising "schedule" - basically the +noise has to be cleaned by a certain degree each step or the model won't +"converge" on the image properly (see +[stable diffusion blog](https://huggingface.co/blog/stable_diffusion) for more +about that). A different step count means a different schedule, which means +things get interpreted slightly differently at every step. diff --git a/docs/features/INPAINTING.md b/docs/features/INPAINTING.md index 0db67c6af6..e22fbd08e7 100644 --- a/docs/features/INPAINTING.md +++ b/docs/features/INPAINTING.md @@ -1,30 +1,240 @@ -# **Creating Transparent Regions for Inpainting** +--- +title: Inpainting +--- -Inpainting is really cool. To do it, you start with an initial image -and use a photoeditor to make one or more regions transparent -(i.e. they have a "hole" in them). You then provide the path to this -image at the dream> command line using the `-I` switch. Stable -Diffusion will only paint within the transparent region. +# :octicons-paintbrush-16: Inpainting -There's a catch. In the current implementation, you have to prepare -the initial image correctly so that the underlying colors are -preserved under the transparent area. Many imaging editing -applications will by default erase the color information under the -transparent pixels and replace them with white or black, which will -lead to suboptimal inpainting. You also must take care to export the -PNG file in such a way that the color information is preserved. +## **Creating Transparent Regions for Inpainting** -If your photoeditor is erasing the underlying color information, -`dream.py` will give you a big fat warning. If you can't find a way to -coax your photoeditor to retain color values under transparent areas, -then you can combine the `-I` and `-M` switches to provide both the -original unedited image and the masked (partially transparent) image: +Inpainting is really cool. To do it, you start with an initial image and use a +photoeditor to make one or more regions transparent (i.e. they have a "hole" in +them). You then provide the path to this image at the dream> command line using +the `-I` switch. Stable Diffusion will only paint within the transparent region. -``` -dream> man with cat on shoulder -I./images/man.png -M./images/man-transparent.png +There's a catch. In the current implementation, you have to prepare the initial +image correctly so that the underlying colors are preserved under the +transparent area. Many imaging editing applications will by default erase the +color information under the transparent pixels and replace them with white or +black, which will lead to suboptimal inpainting. It often helps to apply +incomplete transparency, such as any value between 1 and 99% + +You also must take care to export the PNG file in such a way that the color +information is preserved. There is often an option in the export dialog that +lets you specify this. + +If your photoeditor is erasing the underlying color information, `dream.py` will +give you a big fat warning. If you can't find a way to coax your photoeditor to +retain color values under transparent areas, then you can combine the `-I` and +`-M` switches to provide both the original unedited image and the masked +(partially transparent) image: + +```bash +invoke> "man with cat on shoulder" -I./images/man.png -M./images/man-transparent.png ``` -We are hoping to get rid of the need for this workaround in an upcoming release. +## **Masking using Text** + +You can also create a mask using a text prompt to select the part of the image +you want to alter, using the [clipseg](https://github.com/timojl/clipseg) +algorithm. This works on any image, not just ones generated by InvokeAI. + +The `--text_mask` (short form `-tm`) option takes two arguments. The first +argument is a text description of the part of the image you wish to mask (paint +over). If the text description contains a space, you must surround it with +quotation marks. The optional second argument is the minimum threshold for the +mask classifier's confidence score, described in more detail below. + +To see how this works in practice, here's an image of a still life painting that +I got off the web. + +
+![still life scaled](../assets/still-life-scaled.jpg) +
+ +You can selectively mask out the orange and replace it with a baseball in this +way: + +```bash +invoke> a baseball -I /path/to/still_life.png -tm orange +``` + +
+![](../assets/still-life-inpainted.png) +
+ +The clipseg classifier produces a confidence score for each region it +identifies. Generally regions that score above 0.5 are reliable, but if you are +getting too much or too little masking you can adjust the threshold down (to get +more mask), or up (to get less). In this example, by passing `-tm` a higher +value, we are insisting on a tigher mask. However, if you make it too high, the +orange may not be picked up at all! + +```bash +invoke> a baseball -I /path/to/breakfast.png -tm orange 0.6 +``` + +The `!mask` command may be useful for debugging problems with the text2mask +feature. The syntax is `!mask /path/to/image.png -tm ` + +It will generate three files: + +- The image with the selected area highlighted. + - it will be named XXXXX...selected.png +- The image with the un-selected area highlighted. + - it will be named XXXXX...deselected.png +- The image with the selected area converted into a black and white image + according to the threshold level + - it will be named XXXXX...masked.png + +The `.masked.png` file can then be directly passed to the `invoke>` prompt in +the CLI via the `-M` argument. Do not attempt this with the `selected.png` or +`deselected.png` files, as they contain some transparency throughout the image +and will not produce the desired results. + +Here is an example of how `!mask` works: + +```bash +invoke> !mask ./test-pictures/curly.png -tm hair 0.5 +>> generating masks from ./test-pictures/curly.png +>> Initializing clipseg model for text to mask inference +Outputs: +[941.1] outputs/img-samples/000019.curly.hair.deselected.png: !mask ./test-pictures/curly.png -tm hair 0.5 +[941.2] outputs/img-samples/000019.curly.hair.selected.png: !mask ./test-pictures/curly.png -tm hair 0.5 +[941.3] outputs/img-samples/000019.curly.hair.masked.png: !mask ./test-pictures/curly.png -tm hair 0.5 +``` + +
+![curly](../assets/outpainting/curly.png) +
Original image "curly.png"
+
+ +
+![curly hair selected](../assets/inpainting/000019.curly.hair.selected.png) +
000019.curly.hair.selected.png
+
+ +
+![curly hair deselected](../assets/inpainting/000019.curly.hair.deselected.png) +
000019.curly.hair.deselected.png
+
+ +
+![curly hair masked](../assets/inpainting/000019.curly.hair.masked.png) +
000019.curly.hair.masked.png
+
+ +It looks like we selected the hair pretty well at the 0.5 threshold (which is +the default, so we didn't actually have to specify it), so let's have some fun: + +```bash +invoke> medusa with cobras -I ./test-pictures/curly.png -M 000019.curly.hair.masked.png -C20 +>> loaded input image of size 512x512 from ./test-pictures/curly.png +... +Outputs: +[946] outputs/img-samples/000024.801380492.png: "medusa with cobras" -s 50 -S 801380492 -W 512 -H 512 -C 20.0 -I ./test-pictures/curly.png -A k_lms -f 0.75 +``` + +
+![](../assets/inpainting/000024.801380492.png) +
+ +You can also skip the `!mask` creation step and just select the masked + +region directly: + +```bash +invoke> medusa with cobras -I ./test-pictures/curly.png -tm hair -C20 +``` + +## Using the RunwayML inpainting model + +The +[RunwayML Inpainting Model v1.5](https://huggingface.co/runwayml/stable-diffusion-inpainting) +is a specialized version of +[Stable Diffusion v1.5](https://huggingface.co/spaces/runwayml/stable-diffusion-v1-5) +that contains extra channels specifically designed to enhance inpainting and +outpainting. While it can do regular `txt2img` and `img2img`, it really shines +when filling in missing regions. It has an almost uncanny ability to blend the +new regions with existing ones in a semantically coherent way. + +To install the inpainting model, follow the +[instructions](../installation/INSTALLING_MODELS.md) for installing a new model. +You may use either the CLI (`invoke.py` script) or directly edit the +`configs/models.yaml` configuration file to do this. The main thing to watch out +for is that the the model `config` option must be set up to use +`v1-inpainting-inference.yaml` rather than the `v1-inference.yaml` file that is +used by Stable Diffusion 1.4 and 1.5. + +After installation, your `models.yaml` should contain an entry that looks like +this one: + +inpainting-1.5: weights: models/ldm/stable-diffusion-v1/sd-v1-5-inpainting.ckpt +description: SD inpainting v1.5 config: +configs/stable-diffusion/v1-inpainting-inference.yaml vae: +models/ldm/stable-diffusion-v1/vae-ft-mse-840000-ema-pruned.ckpt width: 512 +height: 512 + +As shown in the example, you may include a VAE fine-tuning weights file as well. +This is strongly recommended. + +To use the custom inpainting model, launch `invoke.py` with the argument +`--model inpainting-1.5` or alternatively from within the script use the +`!switch inpainting-1.5` command to load and switch to the inpainting model. + +You can now do inpainting and outpainting exactly as described above, but there +will (likely) be a noticeable improvement in coherence. Txt2img and Img2img will +work as well. + +There are a few caveats to be aware of: + +1. The inpainting model is larger than the standard model, and will use nearly 4 + GB of GPU VRAM. This makes it unlikely to run on a 4 GB graphics card. + +2. When operating in Img2img mode, the inpainting model is much less steerable + than the standard model. It is great for making small changes, such as + changing the pattern of a fabric, or slightly changing a subject's expression + or hair, but the model will resist making the dramatic alterations that the + standard model lets you do. + +3. While the `--hires` option works fine with the inpainting model, some special + features, such as `--embiggen` are disabled. + +4. Prompt weighting (`banana++ sushi`) and merging work well with the inpainting + model, but prompt swapping + (`a ("fluffy cat").swap("smiling dog") eating a hotdog`) will not have any + effect due to the way the model is set up. You may use text masking (with + `-tm thing-to-mask`) as an effective replacement. + +5. The model tends to oversharpen image if you use high step or CFG values. If + you need to do large steps, use the standard model. + +6. The `--strength` (`-f`) option has no effect on the inpainting model due to + its fundamental differences with the standard model. It will always take the + full number of steps you specify. + +## Troubleshooting + +Here are some troubleshooting tips for inpainting and outpainting. + +## Inpainting is not changing the masked region enough! + +One of the things to understand about how inpainting works is that it is +equivalent to running img2img on just the masked (transparent) area. img2img +builds on top of the existing image data, and therefore will attempt to preserve +colors, shapes and textures to the best of its ability. Unfortunately this means +that if you want to make a dramatic change in the inpainted region, for example +replacing a red wall with a blue one, the algorithm will fight you. + +You have a couple of options. The first is to increase the values of the +requested steps (`-sXXX`), strength (`-f0.XX`), and/or condition-free guidance +(`-CXX.X`). If this is not working for you, a more extreme step is to provide +the `--inpaint_replace 0.X` (`-r0.X`) option. This value ranges from 0.0 to 1.0. +The higher it is the less attention the algorithm will pay to the data +underneath the masked region. At high values this will enable you to replace +colored regions entirely, but beware that the masked region mayl not blend in +with the surrounding unmasked regions as well. + +--- ## Recipe for GIMP @@ -32,47 +242,65 @@ We are hoping to get rid of the need for this workaround in an upcoming release. 1. Open image in GIMP. 2. Layer->Transparency->Add Alpha Channel -3. Use lasoo tool to select region to mask +3. Use lasso tool to select region to mask 4. Choose Select -> Float to create a floating selection 5. Open the Layers toolbar (^L) and select "Floating Selection" -6. Set opacity to a value less than 100% +6. Set opacity to a value between 0% and 99% 7. Export as PNG -8. In the export dialogue, Make sure the "Save colour values from - transparent pixels" checkbox is selected. +8. In the export dialogue, Make sure the "Save colour values from transparent + pixels" checkbox is selected. +--- ## Recipe for Adobe Photoshop 1. Open image in Photoshop -

- -

-2. Use any of the selection tools (Marquee, Lasso, or Wand) to select the area you desire to inpaint. -

- -

+
+ ![step1](../assets/step1.png) +
-3. Because we'll be applying a mask over the area we want to preserve, you should now select the inverse by using the Shift + Ctrl + I shortcut, or right clicking and using the "Select Inverse" option. +2. Use any of the selection tools (Marquee, Lasso, or Wand) to select the area + you desire to inpaint. -4. You'll now create a mask by selecting the image layer, and Masking the selection. Make sure that you don't delete any of the underlying image, or your inpainting results will be dramatically impacted. -

- -

+
+ ![step2](../assets/step2.png) +
-5. Make sure to hide any background layers that are present. You should see the mask applied to your image layer, and the image on your canvas should display the checkered background. -

- -

+3. Because we'll be applying a mask over the area we want to preserve, you + should now select the inverse by using the ++shift+ctrl+i++ shortcut, or + right clicking and using the "Select Inverse" option. -

- -

+4. You'll now create a mask by selecting the image layer, and Masking the + selection. Make sure that you don't delete any of the underlying image, or + your inpainting results will be dramatically impacted. -6. Save the image as a transparent PNG by using the "Save a Copy" option in the File menu, or using the Alt + Ctrl + S keyboard shortcut. +
+ ![step4](../assets/step4.png) +
-7. After following the inpainting instructions above (either through the CLI or the Web UI), marvel at your newfound ability to selectively dream. Lookin' good! -

- -

+5. Make sure to hide any background layers that are present. You should see the + mask applied to your image layer, and the image on your canvas should display + the checkered background. +
+ ![step5](../assets/step5.png) +
+ +6. Save the image as a transparent PNG by using `File`-->`Save a Copy` from the + menu bar, or by using the keyboard shortcut ++alt+ctrl+s++ + +
+ ![step6](../assets/step6.png) +
+ +7. After following the inpainting instructions above (either through the CLI or + the Web UI), marvel at your newfound ability to selectively invoke. Lookin' + good! + +
+ ![step7](../assets/step7.png) +
+ +8. In the export dialogue, Make sure the "Save colour values from transparent + pixels" checkbox is selected. diff --git a/docs/features/OTHER.md b/docs/features/OTHER.md index 3853b185ed..e2e1c746fb 100644 --- a/docs/features/OTHER.md +++ b/docs/features/OTHER.md @@ -1,71 +1,57 @@ +--- +title: Others +--- + +# :fontawesome-regular-share-from-square: Others + ## **Google Colab** -Stable Diffusion AI Notebook:
Open and follow instructions to use an -isolated environment running Dream.
+[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg){ align="right" }](https://colab.research.google.com/github/lstein/stable-diffusion/blob/main/notebooks/Stable_Diffusion_AI_Notebook.ipynb) + +Open and follow instructions to use an isolated environment running Dream. Output Example: + ![Colab Notebook](../assets/colab_notebook.png) --- ## **Seamless Tiling** -The seamless tiling mode causes generated images to seamlessly tile -with itself. To use it, add the `--seamless` option when starting the -script which will result in all generated images to tile, or for each -`dream>` prompt as shown here: +The seamless tiling mode causes generated images to seamlessly tile with itself. To use it, add the +`--seamless` option when starting the script which will result in all generated images to tile, or +for each `invoke>` prompt as shown here: -``` -dream> "pond garden with lotus by claude monet" --seamless -s100 -n4 +```python +invoke> "pond garden with lotus by claude monet" --seamless -s100 -n4 ``` ---- - -## **Reading Prompts from a File** - -You can automate `dream.py` by providing a text file with the prompts -you want to run, one line per prompt. The text file must be composed -with a text editor (e.g. Notepad) and not a word processor. Each line -should look like what you would type at the dream> prompt: - -``` -a beautiful sunny day in the park, children playing -n4 -C10 -stormy weather on a mountain top, goats grazing -s100 -innovative packaging for a squid's dinner -S137038382 -``` - -Then pass this file's name to `dream.py` when you invoke it: - -``` -(ldm) ~/stable-diffusion$ python3 scripts/dream.py --from_file "path/to/prompts.txt" -``` - -You may read a series of prompts from standard input by providing a filename of `-`: - -``` -(ldm) ~/stable-diffusion$ echo "a beautiful day" | python3 scripts/dream.py --from_file - +By default this will tile on both the X and Y axes. However, you can also specify specific axes to tile on with `--seamless_axes`. +Possible values are `x`, `y`, and `x,y`: +```python +invoke> "pond garden with lotus by claude monet" --seamless --seamless_axes=x -s100 -n4 ``` --- ## **Shortcuts: Reusing Seeds** -Since it is so common to reuse seeds while refining a prompt, there is now a shortcut as of version 1.11. Provide a `**-S**` (or `**--seed**`) -switch of `-1` to use the seed of the most recent image generated. If you produced multiple images with the `**-n**` switch, then you can go back further using -2, -3, etc. up to the first image generated by the previous command. Sorry, but you can't go back further than one command. +Since it is so common to reuse seeds while refining a prompt, there is now a shortcut as of version +1.11. Provide a `-S` (or `--seed`) switch of `-1` to use the seed of the most recent image +generated. If you produced multiple images with the `-n` switch, then you can go back further +using `-2`, `-3`, etc. up to the first image generated by the previous command. Sorry, but you can't go +back further than one command. -Here's an example of using this to do a quick refinement. It also illustrates using the new `**-G**` switch to turn on upscaling and face enhancement (see previous section): +Here's an example of using this to do a quick refinement. It also illustrates using the new `-G` +switch to turn on upscaling and face enhancement (see previous section): -``` -dream> a cute child playing hopscotch -G0.5 +```bash +invoke> a cute child playing hopscotch -G0.5 [...] outputs/img-samples/000039.3498014304.png: "a cute child playing hopscotch" -s50 -W512 -H512 -C7.5 -mk_lms -S3498014304 # I wonder what it will look like if I bump up the steps and set facial enhancement to full strength? -dream> a cute child playing hopscotch -G1.0 -s100 -S -1 +invoke> a cute child playing hopscotch -G1.0 -s100 -S -1 reusing previous seed 3498014304 [...] outputs/img-samples/000040.3498014304.png: "a cute child playing hopscotch" -G1.0 -s100 -W512 -H512 -C7.5 -mk_lms -S3498014304 @@ -76,26 +62,70 @@ outputs/img-samples/000040.3498014304.png: "a cute child playing hopscotch" -G1. ## **Weighted Prompts** You may weight different sections of the prompt to tell the sampler to attach different levels of -priority to them, by adding `:(number)` to the end of the section you wish to up- or downweight. -For example consider this prompt: +priority to them, by adding `:` to the end of the section you wish to up- or downweight. For +example consider this prompt: -``` - tabby cat:0.25 white duck:0.75 hybrid +```bash +tabby cat:0.25 white duck:0.75 hybrid ``` -This will tell the sampler to invest 25% of its effort on the tabby -cat aspect of the image and 75% on the white duck aspect -(surprisingly, this example actually works). The prompt weights can -use any combination of integers and floating point numbers, and they -do not need to add up to 1. +This will tell the sampler to invest 25% of its effort on the tabby cat aspect of the image and 75% +on the white duck aspect (surprisingly, this example actually works). The prompt weights can use any +combination of integers and floating point numbers, and they do not need to add up to 1. + +--- + +## **Filename Format** + +The argument `--fnformat` allows to specify the filename of the + image. Supported wildcards are all arguments what can be set such as + `perlin`, `seed`, `threshold`, `height`, `width`, `gfpgan_strength`, + `sampler_name`, `steps`, `model`, `upscale`, `prompt`, `cfg_scale`, + `prefix`. + +The following prompt +```bash +dream> a red car --steps 25 -C 9.8 --perlin 0.1 --fnformat {prompt}_steps.{steps}_cfg.{cfg_scale}_perlin.{perlin}.png +``` + +generates a file with the name: `outputs/img-samples/a red car_steps.25_cfg.9.8_perlin.0.1.png` + +--- + +## **Thresholding and Perlin Noise Initialization Options** + +Two new options are the thresholding (`--threshold`) and the perlin noise initialization (`--perlin`) options. Thresholding limits the range of the latent values during optimization, which helps combat oversaturation with higher CFG scale values. Perlin noise initialization starts with a percentage (a value ranging from 0 to 1) of perlin noise mixed into the initial noise. Both features allow for more variations and options in the course of generating images. + +For better intuition into what these options do in practice: + +![here is a graphic demonstrating them both](../assets/truncation_comparison.jpg) + +In generating this graphic, perlin noise at initialization was programmatically varied going across on the diagram by values 0.0, 0.1, 0.2, 0.4, 0.5, 0.6, 0.8, 0.9, 1.0; and the threshold was varied going down from +0, 1, 2, 3, 4, 5, 10, 20, 100. The other options are fixed, so the initial prompt is as follows (no thresholding or perlin noise): + +```bash +invoke> "a portrait of a beautiful young lady" -S 1950357039 -s 100 -C 20 -A k_euler_a --threshold 0 --perlin 0 +``` + +Here's an example of another prompt used when setting the threshold to 5 and perlin noise to 0.2: + +```bash +invoke> "a portrait of a beautiful young lady" -S 1950357039 -s 100 -C 20 -A k_euler_a --threshold 5 --perlin 0.2 +``` + +!!! note + + currently the thresholding feature is only implemented for the k-diffusion style samplers, and empirically appears to work best with `k_euler_a` and `k_dpm_2_a`. Using 0 disables thresholding. Using 0 for perlin noise disables using perlin noise for initialization. Finally, using 1 for perlin noise uses only perlin noise for initialization. --- ## **Simplified API** -For programmers who wish to incorporate stable-diffusion into other products, this repository includes a simplified API for text to image generation, which lets you create images from a prompt in just three lines of code: +For programmers who wish to incorporate stable-diffusion into other products, this repository +includes a simplified API for text to image generation, which lets you create images from a prompt +in just three lines of code: -``` +```bash from ldm.generate import Generate g = Generate() outputs = g.txt2img("a unicorn in manhattan") @@ -109,17 +139,15 @@ Please see ldm/generate.py for more information. A set of example scripts is com ## **Preload Models** -In situations where you have limited internet connectivity or are -blocked behind a firewall, you can use the preload script to preload -the required files for Stable Diffusion to run. +In situations where you have limited internet connectivity or are blocked behind a firewall, you can +use the preload script to preload the required files for Stable Diffusion to run. -The preload script `scripts/preload_models.py` needs to be run once at -least while connected to the internet. In the following runs, it will -load up the cached versions of the required files from the `.cache` -directory of the system. +The preload script `scripts/preload_models.py` needs to be run once at least while connected to the +internet. In the following runs, it will load up the cached versions of the required files from the +`.cache` directory of the system. -``` -(ldm) ~/stable-diffusion$ python3 ./scripts/preload_models.py +```bash +(invokeai) ~/stable-diffusion$ python3 ./scripts/preload_models.py preloading bert tokenizer... Downloading: 100%|██████████████████████████████████| 28.0/28.0 [00:00<00:00, 49.3kB/s] Downloading: 100%|██████████████████████████████████| 226k/226k [00:00<00:00, 2.79MB/s] diff --git a/docs/features/OUTPAINTING.md b/docs/features/OUTPAINTING.md new file mode 100644 index 0000000000..122c732605 --- /dev/null +++ b/docs/features/OUTPAINTING.md @@ -0,0 +1,156 @@ +--- +title: Outpainting +--- + +# :octicons-paintbrush-16: Outpainting + +## Outpainting and outcropping + +Outpainting is a process by which the AI generates parts of the image that are +outside its original frame. It can be used to fix up images in which the subject +is off center, or when some detail (often the top of someone's head!) is cut +off. + +InvokeAI supports two versions of outpainting, one called "outpaint" and the +other "outcrop." They work slightly differently and each has its advantages and +drawbacks. + +### Outpainting + +Outpainting is the same as inpainting, except that the painting occurs in the +regions outside of the original image. To outpaint using the `invoke.py` command +line script, prepare an image in which the borders to be extended are pure +black. Add an alpha channel (if there isn't one already), and make the borders +completely transparent and the interior completely opaque. If you wish to modify +the interior as well, you may create transparent holes in the transparency +layer, which `img2img` will paint into as usual. + +Pass the image as the argument to the `-I` switch as you would for regular +inpainting: + +```bash +invoke> a stream by a river -I /path/to/transparent_img.png +``` + +You'll likely be delighted by the results. + +### Tips + +1. Do not try to expand the image too much at once. Generally it is best to + expand the margins in 64-pixel increments. 128 pixels often works, but your + mileage may vary depending on the nature of the image you are trying to + outpaint into. + +2. There are a series of switches that can be used to adjust how the inpainting + algorithm operates. In particular, you can use these to minimize the seam + that sometimes appears between the original image and the extended part. + These switches are: + +| switch | default | description | +| -------------------------- | ------- | ---------------------------------------------------------------------- | +| `--seam_size SEAM_SIZE ` | `0` | Size of the mask around the seam between original and outpainted image | +| `--seam_blur SEAM_BLUR` | `0` | The amount to blur the seam inwards | +| `--seam_strength STRENGTH` | `0.7` | The img2img strength to use when filling the seam | +| `--seam_steps SEAM_STEPS` | `10` | The number of steps to use to fill the seam. | +| `--tile_size TILE_SIZE` | `32` | The tile size to use for filling outpaint areas | + +### Outcrop + +The `outcrop` extension gives you a convenient `!fix` postprocessing command +that allows you to extend a previously-generated image in 64 pixel increments in +any direction. You can apply the module to any image previously-generated by +InvokeAI. Note that it works with arbitrary PNG photographs, but not currently +with JPG or other formats. Outcropping is particularly effective when combined +with the +[runwayML custom inpainting model](INPAINTING.md#using-the-runwayml-inpainting-model). + +Consider this image: + +
+![curly_woman](../assets/outpainting/curly.png) +
+ +Pretty nice, but it's annoying that the top of her head is cut off. She's also a +bit off center. Let's fix that! + +```bash +invoke> !fix images/curly.png --outcrop top 128 right 64 bottom 64 +``` + +This is saying to apply the `outcrop` extension by extending the top of the +image by 128 pixels, and the right and bottom of the image by 64 pixels. You can +use any combination of top|left|right|bottom, and specify any number of pixels +to extend. You can also abbreviate `--outcrop` to `-c`. + +The result looks like this: + +
+![curly_woman_outcrop](../assets/outpainting/curly-outcrop-2.png) +
+ +The new image is larger than the original (576x704) because 64 pixels were added +to the top and right sides. You will need enough VRAM to process an image of +this size. + +A number of caveats: + +1. Although you can specify any pixel values, they will be rounded up to the + nearest multiple of 64. Smaller values are better. Larger extensions are more + likely to generate artefacts. However, if you wish you can run the !fix + command repeatedly to cautiously expand the image. + +2. The extension is stochastic, meaning that each time you run it you'll get a + slightly different result. You can run it repeatedly until you get an image + you like. Unfortunately `!fix` does not currently respect the `-n` + (`--iterations`) argument. + +3. Your results will be _much_ better if you use the `inpaint-1.5` model + released by runwayML and installed by default by `scripts/preload_models.py`. + This model was trained specifically to harmoniously fill in image gaps. The + standard model will work as well, but you may notice color discontinuities at + the border. + +4. When using the `inpaint-1.5` model, you may notice subtle changes to the area + within the original image. This is because the model performs an + encoding/decoding on the image as a whole. This does not occur with the + standard model. + +## Outpaint + +The `outpaint` extension does the same thing, but with subtle differences. +Starting with the same image, here is how we would add an additional 64 pixels +to the top of the image: + +```bash +invoke> !fix images/curly.png --out_direction top 64 +``` + +(you can abbreviate `--out_direction` as `-D`. + +The result is shown here: + +
+![curly_woman_outpaint](../assets/outpainting/curly-outpaint.png) +
+ +Although the effect is similar, there are significant differences from +outcropping: + +- You can only specify one direction to extend at a time. +- The image is **not** resized. Instead, the image is shifted by the specified + number of pixels. If you look carefully, you'll see that less of the lady's + torso is visible in the image. +- Because the image dimensions remain the same, there's no rounding to multiples + of 64. +- Attempting to outpaint larger areas will frequently give rise to ugly ghosting + effects. +- For best results, try increasing the step number. +- If you don't specify a pixel value in `-D`, it will default to half of the + whole image, which is likely not what you want. + +!!! tip + + Neither `outpaint` nor `outcrop` are perfect, but we continue to tune + and improve them. If one doesn't work, try the other. You may also + wish to experiment with other `img2img` arguments, such as `-C`, `-f` + and `-s`. diff --git a/docs/features/POSTPROCESS.md b/docs/features/POSTPROCESS.md new file mode 100644 index 0000000000..74a48c4d8f --- /dev/null +++ b/docs/features/POSTPROCESS.md @@ -0,0 +1,177 @@ +--- +title: Postprocessing +--- + +# :material-image-edit: Postprocessing + +## Intro + +This extension provides the ability to restore faces and upscale +images. + +Face restoration and upscaling can be applied at the time you generate +the images, or at any later time against a previously-generated PNG +file, using the [!fix](#fixing-previously-generated-images) +command. [Outpainting and outcropping](OUTPAINTING.md) can only be +applied after the fact. + +## Face Fixing + +The default face restoration module is GFPGAN. The default upscale is +Real-ESRGAN. For an alternative face restoration module, see [CodeFormer +Support](#codeformer-support) below. + +As of version 1.14, environment.yaml will install the Real-ESRGAN +package into the standard install location for python packages, and +will put GFPGAN into a subdirectory of "src" in the InvokeAI +directory. Upscaling with Real-ESRGAN should "just work" without +further intervention. Simply pass the `--upscale` (`-U`) option on the +`invoke>` command line, or indicate the desired scale on the popup in +the Web GUI. + +**GFPGAN** requires a series of downloadable model files to +work. These are loaded when you run `scripts/preload_models.py`. If +GFPAN is failing with an error, please run the following from the +InvokeAI directory: + +```bash +python scripts/preload_models.py +``` + +If you do not run this script in advance, the GFPGAN module will attempt +to download the models files the first time you try to perform facial +reconstruction. + +Alternatively, if you have GFPGAN installed elsewhere, or if you are +using an earlier version of this package which asked you to install +GFPGAN in a sibling directory, you may use the `--gfpgan_dir` argument +with `invoke.py` to set a custom path to your GFPGAN directory. _There +are other GFPGAN related boot arguments if you wish to customize +further._ + +## Usage + +You will now have access to two new prompt arguments. + +### Upscaling + +`-U : ` + +The upscaling prompt argument takes two values. The first value is a scaling +factor and should be set to either `2` or `4` only. This will either scale the +image 2x or 4x respectively using different models. + +You can set the scaling stength between `0` and `1.0` to control intensity of +the of the scaling. This is handy because AI upscalers generally tend to smooth +out texture details. If you wish to retain some of those for natural looking +results, we recommend using values between `0.5 to 0.8`. + +If you do not explicitly specify an upscaling_strength, it will default to 0.75. + +### Face Restoration + +`-G : ` + +This prompt argument controls the strength of the face restoration that is being +applied. Similar to upscaling, values between `0.5 to 0.8` are recommended. + +You can use either one or both without any conflicts. In cases where you use +both, the image will be first upscaled and then the face restoration process +will be executed to ensure you get the highest quality facial features. + +`--save_orig` + +When you use either `-U` or `-G`, the final result you get is upscaled or face +modified. If you want to save the original Stable Diffusion generation, you can +use the `-save_orig` prompt argument to save the original unaffected version +too. + +### Example Usage + +```bash +invoke> "superman dancing with a panda bear" -U 2 0.6 -G 0.4 +``` + +This also works with img2img: + +```bash +invoke> "a man wearing a pineapple hat" -I path/to/your/file.png -U 2 0.5 -G 0.6 +``` + +!!! note + + GFPGAN and Real-ESRGAN are both memory intensive. In order to avoid crashes and memory overloads + during the Stable Diffusion process, these effects are applied after Stable Diffusion has completed + its work. + + In single image generations, you will see the output right away but when you are using multiple + iterations, the images will first be generated and then upscaled and face restored after that + process is complete. While the image generation is taking place, you will still be able to preview + the base images. + +If you wish to stop during the image generation but want to upscale or face +restore a particular generated image, pass it again with the same prompt and +generated seed along with the `-U` and `-G` prompt arguments to perform those +actions. + +## CodeFormer Support + +This repo also allows you to perform face restoration using +[CodeFormer](https://github.com/sczhou/CodeFormer). + +In order to setup CodeFormer to work, you need to download the models +like with GFPGAN. You can do this either by running +`preload_models.py` or by manually downloading the [model +file](https://github.com/sczhou/CodeFormer/releases/download/v0.1.0/codeformer.pth) +and saving it to `ldm/invoke/restoration/codeformer/weights` folder. + +You can use `-ft` prompt argument to swap between CodeFormer and the +default GFPGAN. The above mentioned `-G` prompt argument will allow +you to control the strength of the restoration effect. + +### Usage + +The following command will perform face restoration with CodeFormer instead of +the default gfpgan. + +` -G 0.8 -ft codeformer` + +### Other Options + +- `-cf` - cf or CodeFormer Fidelity takes values between `0` and `1`. 0 produces + high quality results but low accuracy and 1 produces lower quality results but + higher accuacy to your original face. + +The following command will perform face restoration with CodeFormer. CodeFormer +will output a result that is closely matching to the input face. + +` -G 1.0 -ft codeformer -cf 0.9` + +The following command will perform face restoration with CodeFormer. CodeFormer +will output a result that is the best restoration possible. This may deviate +slightly from the original face. This is an excellent option to use in +situations when there is very little facial data to work with. + +` -G 1.0 -ft codeformer -cf 0.1` + +## Fixing Previously-Generated Images + +It is easy to apply face restoration and/or upscaling to any +previously-generated file. Just use the syntax `!fix path/to/file.png +`. For example, to apply GFPGAN at strength 0.8 and upscale +2X for a file named `./outputs/img-samples/000044.2945021133.png`, +just run: + +```bash +invoke> !fix ./outputs/img-samples/000044.2945021133.png -G 0.8 -U 2 +``` + +A new file named `000044.2945021133.fixed.png` will be created in the output +directory. Note that the `!fix` command does not replace the original file, +unlike the behavior at generate time. + +### Disabling + +If, for some reason, you do not wish to load the GFPGAN and/or ESRGAN libraries, +you can disable them on the invoke.py command line with the `--no_restore` and +`--no_upscale` options, respectively. diff --git a/docs/features/PROMPTS.md b/docs/features/PROMPTS.md new file mode 100644 index 0000000000..d18a5c8b75 --- /dev/null +++ b/docs/features/PROMPTS.md @@ -0,0 +1,320 @@ +--- +title: Prompting-Features +--- + +# :octicons-command-palette-24: Prompting-Features + +## **Reading Prompts from a File** + +You can automate `invoke.py` by providing a text file with the prompts you want +to run, one line per prompt. The text file must be composed with a text editor +(e.g. Notepad) and not a word processor. Each line should look like what you +would type at the invoke> prompt: + +```bash +"a beautiful sunny day in the park, children playing" -n4 -C10 +"stormy weather on a mountain top, goats grazing" -s100 +"innovative packaging for a squid's dinner" -S137038382 +``` + +Then pass this file's name to `invoke.py` when you invoke it: + +```bash +(invokeai) ~/stable-diffusion$ python3 scripts/invoke.py --from_file "path/to/prompts.txt" +``` + +You may read a series of prompts from standard input by providing a filename of +`-`: + +```bash +(invokeai) ~/stable-diffusion$ echo "a beautiful day" | python3 scripts/invoke.py --from_file - +``` + +--- + +## **Negative and Unconditioned Prompts** + +Any words between a pair of square brackets will instruct Stable Diffusion to +attempt to ban the concept from the generated image. + +```text +this is a test prompt [not really] to make you understand [cool] how this works. +``` + +In the above statement, the words 'not really cool` will be ignored by Stable +Diffusion. + +Here's a prompt that depicts what it does. + +original prompt: + +`#!bash "A fantastical translucent pony made of water and foam, ethereal, radiant, hyperalism, scottish folklore, digital painting, artstation, concept art, smooth, 8 k frostbite 3 engine, ultra detailed, art by artgerm and greg rutkowski and magali villeneuve" -s 20 -W 512 -H 768 -C 7.5 -A k_euler_a -S 1654590180` + +
+![step1](../assets/negative_prompt_walkthru/step1.png) +
+ +That image has a woman, so if we want the horse without a rider, we can +influence the image not to have a woman by putting [woman] in the prompt, like +this: + +`#!bash "A fantastical translucent poney made of water and foam, ethereal, radiant, hyperalism, scottish folklore, digital painting, artstation, concept art, smooth, 8 k frostbite 3 engine, ultra detailed, art by artgerm and greg rutkowski and magali villeneuve [woman]" -s 20 -W 512 -H 768 -C 7.5 -A k_euler_a -S 1654590180` + +
+![step2](../assets/negative_prompt_walkthru/step2.png) +
+ +That's nice - but say we also don't want the image to be quite so blue. We can +add "blue" to the list of negative prompts, so it's now [woman blue]: + +`#!bash "A fantastical translucent poney made of water and foam, ethereal, radiant, hyperalism, scottish folklore, digital painting, artstation, concept art, smooth, 8 k frostbite 3 engine, ultra detailed, art by artgerm and greg rutkowski and magali villeneuve [woman blue]" -s 20 -W 512 -H 768 -C 7.5 -A k_euler_a -S 1654590180` + +
+![step3](../assets/negative_prompt_walkthru/step3.png) +
+ +Getting close - but there's no sense in having a saddle when our horse doesn't +have a rider, so we'll add one more negative prompt: [woman blue saddle]. + +`#!bash "A fantastical translucent poney made of water and foam, ethereal, radiant, hyperalism, scottish folklore, digital painting, artstation, concept art, smooth, 8 k frostbite 3 engine, ultra detailed, art by artgerm and greg rutkowski and magali villeneuve [woman blue saddle]" -s 20 -W 512 -H 768 -C 7.5 -A k_euler_a -S 1654590180` + +
+![step4](../assets/negative_prompt_walkthru/step4.png) +
+ +!!! notes "Notes about this feature:" + + * The only requirement for words to be ignored is that they are in between a pair of square brackets. + * You can provide multiple words within the same bracket. + * You can provide multiple brackets with multiple words in different places of your prompt. That works just fine. + * To improve typical anatomy problems, you can add negative prompts like `[bad anatomy, extra legs, extra arms, extra fingers, poorly drawn hands, poorly drawn feet, disfigured, out of frame, tiling, bad art, deformed, mutated]`. + +--- + +## **Prompt Syntax Features** + +The InvokeAI prompting language has the following features: + +### Attention weighting + +Append a word or phrase with `-` or `+`, or a weight between `0` and `2` +(`1`=default), to decrease or increase "attention" (= a mix of per-token CFG +weighting multiplier and, for `-`, a weighted blend with the prompt without the +term). + +The following syntax is recognised: + +- single words without parentheses: `a tall thin man picking apricots+` +- single or multiple words with parentheses: + `a tall thin man picking (apricots)+` `a tall thin man picking (apricots)-` + `a tall thin man (picking apricots)+` `a tall thin man (picking apricots)-` +- more effect with more symbols `a tall thin man (picking apricots)++` +- nesting `a tall thin man (picking apricots+)++` (`apricots` effectively gets + `+++`) +- all of the above with explicit numbers `a tall thin man picking (apricots)1.1` + `a tall thin man (picking (apricots)1.3)1.1`. (`+` is equivalent to 1.1, `++` + is pow(1.1,2), `+++` is pow(1.1,3), etc; `-` means 0.9, `--` means pow(0.9,2), + etc.) +- attention also applies to `[unconditioning]` so + `a tall thin man picking apricots [(ladder)0.01]` will _very gently_ nudge SD + away from trying to draw the man on a ladder + +You can use this to increase or decrease the amount of something. Starting from +this prompt of `a man picking apricots from a tree`, let's see what happens if +we increase and decrease how much attention we want Stable Diffusion to pay to +the word `apricots`: + +![an AI generated image of a man picking apricots from a tree](../assets/prompt_syntax/apricots-0.png) + +Using `-` to reduce apricot-ness: + +| `a man picking apricots- from a tree` | `a man picking apricots-- from a tree` | `a man picking apricots--- from a tree` | +| ------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | +| ![an AI generated image of a man picking apricots from a tree, with smaller apricots](../assets/prompt_syntax/apricots--1.png) | ![an AI generated image of a man picking apricots from a tree, with even smaller and fewer apricots](../assets/prompt_syntax/apricots--2.png) | ![an AI generated image of a man picking apricots from a tree, with very few very small apricots](../assets/prompt_syntax/apricots--3.png) | + +Using `+` to increase apricot-ness: + +| `a man picking apricots+ from a tree` | `a man picking apricots++ from a tree` | `a man picking apricots+++ from a tree` | `a man picking apricots++++ from a tree` | `a man picking apricots+++++ from a tree` | +| ------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ![an AI generated image of a man picking apricots from a tree, with larger, more vibrant apricots](../assets/prompt_syntax/apricots-1.png) | ![an AI generated image of a man picking apricots from a tree with even larger, even more vibrant apricots](../assets/prompt_syntax/apricots-2.png) | ![an AI generated image of a man picking apricots from a tree, but the man has been replaced by a pile of apricots](../assets/prompt_syntax/apricots-3.png) | ![an AI generated image of a man picking apricots from a tree, but the man has been replaced by a mound of giant melting-looking apricots](../assets/prompt_syntax/apricots-4.png) | ![an AI generated image of a man picking apricots from a tree, but the man and the leaves and parts of the ground have all been replaced by giant melting-looking apricots](../assets/prompt_syntax/apricots-5.png) | + +You can also change the balance between different parts of a prompt. For +example, below is a `mountain man`: + +![an AI generated image of a mountain man](../assets/prompt_syntax/mountain-man.png) + +And here he is with more mountain: + +| `mountain+ man` | `mountain++ man` | `mountain+++ man` | +| ---------------------------------------------- | ---------------------------------------------- | ---------------------------------------------- | +| ![](../assets/prompt_syntax/mountain1-man.png) | ![](../assets/prompt_syntax/mountain2-man.png) | ![](../assets/prompt_syntax/mountain3-man.png) | + +Or, alternatively, with more man: + +| `mountain man+` | `mountain man++` | `mountain man+++` | `mountain man++++` | +| ---------------------------------------------- | ---------------------------------------------- | ---------------------------------------------- | ---------------------------------------------- | +| ![](../assets/prompt_syntax/mountain-man1.png) | ![](../assets/prompt_syntax/mountain-man2.png) | ![](../assets/prompt_syntax/mountain-man3.png) | ![](../assets/prompt_syntax/mountain-man4.png) | + +### Blending between prompts + +- `("a tall thin man picking apricots", "a tall thin man picking pears").blend(1,1)` +- The existing prompt blending using `:` will continue to be supported - + `("a tall thin man picking apricots", "a tall thin man picking pears").blend(1,1)` + is equivalent to + `a tall thin man picking apricots:1 a tall thin man picking pears:1` in the + old syntax. +- Attention weights can be nested inside blends. +- Non-normalized blends are supported by passing `no_normalize` as an additional + argument to the blend weights, eg + `("a tall thin man picking apricots", "a tall thin man picking pears").blend(1,-1,no_normalize)`. + very fun to explore local maxima in the feature space, but also easy to + produce garbage output. + +See the section below on "Prompt Blending" for more information about how this +works. + +### Cross-Attention Control ('prompt2prompt') + +Sometimes an image you generate is almost right, and you just want to change one +detail without affecting the rest. You could use a photo editor and inpainting +to overpaint the area, but that's a pain. Here's where `prompt2prompt` comes in +handy. + +Generate an image with a given prompt, record the seed of the image, and then +use the `prompt2prompt` syntax to substitute words in the original prompt for +words in a new prompt. This works for `img2img` as well. + +- `a ("fluffy cat").swap("smiling dog") eating a hotdog`. + - quotes optional: `a (fluffy cat).swap(smiling dog) eating a hotdog`. + - for single word substitutions parentheses are also optional: + `a cat.swap(dog) eating a hotdog`. +- Supports options `s_start`, `s_end`, `t_start`, `t_end` (each 0-1) loosely + corresponding to bloc97's `prompt_edit_spatial_start/_end` and + `prompt_edit_tokens_start/_end` but with the math swapped to make it easier to + intuitively understand. + - Example usage:`a (cat).swap(dog, s_end=0.3) eating a hotdog` - the `s_end` + argument means that the "spatial" (self-attention) edit will stop having any + effect after 30% (=0.3) of the steps have been done, leaving Stable + Diffusion with 70% of the steps where it is free to decide for itself how to + reshape the cat-form into a dog form. + - The numbers represent a percentage through the step sequence where the edits + should happen. 0 means the start (noisy starting image), 1 is the end (final + image). + - For img2img, the step sequence does not start at 0 but instead at + (1-strength) - so if strength is 0.7, s_start and s_end must both be + greater than 0.3 (1-0.7) to have any effect. +- Convenience option `shape_freedom` (0-1) to specify how much "freedom" Stable + Diffusion should have to change the shape of the subject being swapped. + - `a (cat).swap(dog, shape_freedom=0.5) eating a hotdog`. + +The `prompt2prompt` code is based off +[bloc97's colab](https://github.com/bloc97/CrossAttentionControl). + +Note that `prompt2prompt` is not currently working with the runwayML inpainting +model, and may never work due to the way this model is set up. If you attempt to +use `prompt2prompt` you will get the original image back. However, since this +model is so good at inpainting, a good substitute is to use the `clipseg` text +masking option: + +```bash +invoke> a fluffy cat eating a hotdot +Outputs: +[1010] outputs/000025.2182095108.png: a fluffy cat eating a hotdog +invoke> a smiling dog eating a hotdog -I 000025.2182095108.png -tm cat +``` + +### Escaping parantheses () and speech marks "" + +If the model you are using has parentheses () or speech marks "" as part of its +syntax, you will need to "escape" these using a backslash, so that`(my_keyword)` +becomes `\(my_keyword\)`. Otherwise, the prompt parser will attempt to interpret +the parentheses as part of the prompt syntax and it will get confused. + +--- + +## **Prompt Blending** + +You may blend together different sections of the prompt to explore the AI's +latent semantic space and generate interesting (and often surprising!) +variations. The syntax is: + +```bash +blue sphere:0.25 red cube:0.75 hybrid +``` + +This will tell the sampler to blend 25% of the concept of a blue sphere with 75% +of the concept of a red cube. The blend weights can use any combination of +integers and floating point numbers, and they do not need to add up to 1. +Everything to the left of the `:XX` up to the previous `:XX` is used for +merging, so the overall effect is: + +```bash +0.25 * "blue sphere" + 0.75 * "white duck" + hybrid +``` + +Because you are exploring the "mind" of the AI, the AI's way of mixing two +concepts may not match yours, leading to surprising effects. To illustrate, here +are three images generated using various combinations of blend weights. As +usual, unless you fix the seed, the prompts will give you different results each +time you run them. + +
+### "blue sphere, red cube, hybrid" +
+ +This example doesn't use melding at all and represents the default way of mixing +concepts. + +
+![blue-sphere-red-cube-hyprid](../assets/prompt-blending/blue-sphere-red-cube-hybrid.png) +
+ +It's interesting to see how the AI expressed the concept of "cube" as the four +quadrants of the enclosing frame. If you look closely, there is depth there, so +the enclosing frame is actually a cube. + +
+### "blue sphere:0.25 red cube:0.75 hybrid" + +![blue-sphere-25-red-cube-75](../assets/prompt-blending/blue-sphere-0.25-red-cube-0.75-hybrid.png) + +
+ +Now that's interesting. We get neither a blue sphere nor a red cube, but a red +sphere embedded in a brick wall, which represents a melding of concepts within +the AI's "latent space" of semantic representations. Where is Ludwig +Wittgenstein when you need him? + +
+### "blue sphere:0.75 red cube:0.25 hybrid" + +![blue-sphere-75-red-cube-25](../assets/prompt-blending/blue-sphere-0.75-red-cube-0.25-hybrid.png) + +
+ +Definitely more blue-spherey. The cube is gone entirely, but it's really cool +abstract art. + +
+### "blue sphere:0.5 red cube:0.5 hybrid" + +![blue-sphere-5-red-cube-5-hybrid](../assets/prompt-blending/blue-sphere-0.5-red-cube-0.5-hybrid.png) + +
+ +Whoa...! I see blue and red, but no spheres or cubes. Is the word "hybrid" +summoning up the concept of some sort of scifi creature? Let's find out. + +
+### "blue sphere:0.5 red cube:0.5" + +![blue-sphere-5-red-cube-5](../assets/prompt-blending/blue-sphere-0.5-red-cube-0.5.png) + +
+ +Indeed, removing the word "hybrid" produces an image that is more like what we'd +expect. + +In conclusion, prompt blending is great for exploring creative space, but can be +difficult to direct. A forthcoming release of InvokeAI will feature more +deterministic prompt weighting. diff --git a/docs/features/TEXTUAL_INVERSION.md b/docs/features/TEXTUAL_INVERSION.md index 3641732e79..7ce0f41c5a 100644 --- a/docs/features/TEXTUAL_INVERSION.md +++ b/docs/features/TEXTUAL_INVERSION.md @@ -1,70 +1,92 @@ -# **Personalizing Text-to-Image Generation** +--- +title: Textual-Inversion +--- -You may personalize the generated images to provide your own styles or objects by training a new LDM checkpoint and introducing a new vocabulary to the fixed model as a (.pt) embeddings file. Alternatively, you may use or train HuggingFace Concepts embeddings files (.bin) from https://huggingface.co/sd-concepts-library and its associated notebooks. +# :material-file-document: Textual Inversion -**Training** +## **Personalizing Text-to-Image Generation** -To train, prepare a folder that contains images sized at 512x512 and execute the following: +You may personalize the generated images to provide your own styles or objects +by training a new LDM checkpoint and introducing a new vocabulary to the fixed +model as a (.pt) embeddings file. Alternatively, you may use or train +HuggingFace Concepts embeddings files (.bin) from + and its associated notebooks. -**WINDOWS**: As the default backend is not available on Windows, if you're using that platform, set the environment variable `PL_TORCH_DISTRIBUTED_BACKEND=gloo` +## **Training** -``` -(ldm) ~/stable-diffusion$ python3 ./main.py --base ./configs/stable-diffusion/v1-finetune.yaml \ - -t \ - --actual_resume ./models/ldm/stable-diffusion-v1/model.ckpt \ - -n my_cat \ - --gpus 0, \ - --data_root D:/textual-inversion/my_cat \ - --init_word 'cat' +To train, prepare a folder that contains images sized at 512x512 and execute the +following: + +### WINDOWS + +As the default backend is not available on Windows, if you're using that +platform, set the environment variable `PL_TORCH_DISTRIBUTED_BACKEND` to `gloo` + +```bash +python3 ./main.py -t \ + --base ./configs/stable-diffusion/v1-finetune.yaml \ + --actual_resume ./models/ldm/stable-diffusion-v1/model.ckpt \ + -n my_cat \ + --gpus 0 \ + --data_root D:/textual-inversion/my_cat \ + --init_word 'cat' ``` During the training process, files will be created in -/logs/[project][time][project]/ where you can see the process. +`/logs/[project][time][project]/` where you can see the process. -Conditioning contains the training prompts inputs, reconstruction the -input images for the training epoch samples, samples scaled for a -sample of the prompt and one with the init word provided. +Conditioning contains the training prompts inputs, reconstruction the input +images for the training epoch samples, samples scaled for a sample of the prompt +and one with the init word provided. On a RTX3090, the process for SD will take ~1h @1.6 iterations/sec. -_Note_: According to the associated paper, the optimal number of -images is 3-5. Your model may not converge if you use more images than -that. +!!! note -Training will run indefinitely, but you may wish to stop it (with -ctrl-c) before the heat death of the universe, when you find a low -loss epoch or around ~5000 iterations. Note that you can set a fixed -limit on the number of training steps by decreasing the "max_steps" -option in configs/stable_diffusion/v1-finetune.yaml (currently set to -4000000) + According to the associated paper, the optimal number of + images is 3-5. Your model may not converge if you use more images than + that. -**Running** +Training will run indefinitely, but you may wish to stop it (with ctrl-c) before +the heat death of the universe, when you find a low loss epoch or around ~5000 +iterations. Note that you can set a fixed limit on the number of training steps +by decreasing the "max_steps" option in +configs/stable_diffusion/v1-finetune.yaml (currently set to 4000000) -Once the model is trained, specify the trained .pt or .bin file when -starting dream using +## **Run the Model** -``` -(ldm) ~/stable-diffusion$ python3 ./scripts/dream.py --embedding_path /path/to/embedding.pt --full_precision +Once the model is trained, specify the trained .pt or .bin file when starting +invoke using + +```bash +python3 ./scripts/invoke.py \ + --embedding_path /path/to/embedding.pt ``` -Then, to utilize your subject at the dream prompt +Then, to utilize your subject at the invoke prompt -``` -dream> "a photo of *" +```bash +invoke> "a photo of *" ``` This also works with image2image -``` -dream> "waterfall and rainbow in the style of *" --init_img=./init-images/crude_drawing.png --strength=0.5 -s100 -n4 +```bash +invoke> "waterfall and rainbow in the style of *" --init_img=./init-images/crude_drawing.png --strength=0.5 -s100 -n4 ``` -For .pt files it's also possible to train multiple tokens (modify the placeholder string in `configs/stable-diffusion/v1-finetune.yaml`) and combine LDM checkpoints using: +For .pt files it's also possible to train multiple tokens (modify the +placeholder string in `configs/stable-diffusion/v1-finetune.yaml`) and combine +LDM checkpoints using: -``` -(ldm) ~/stable-diffusion$ python3 ./scripts/merge_embeddings.py \ - --manager_ckpts /path/to/first/embedding.pt /path/to/second/embedding.pt [...] \ - --output_path /path/to/output/embedding.pt +```bash +python3 ./scripts/merge_embeddings.py \ + --manager_ckpts /path/to/first/embedding.pt \ + [
,[...]] \ + --output_path /path/to/output/embedding.pt ``` -Credit goes to rinongal and the repository located at https://github.com/rinongal/textual_inversion Please see the repository and associated paper for details and limitations. +Credit goes to rinongal and the repository + +Please see [the repository](https://github.com/rinongal/textual_inversion) and +associated paper for details and limitations. diff --git a/docs/features/UPSCALE.md b/docs/features/UPSCALE.md deleted file mode 100644 index 381d2b90ec..0000000000 --- a/docs/features/UPSCALE.md +++ /dev/null @@ -1,105 +0,0 @@ -# **GFPGAN and Real-ESRGAN Support** - -The script also provides the ability to do face restoration and -upscaling with the help of GFPGAN and Real-ESRGAN respectively. - -As of version 1.14, environment.yaml will install the Real-ESRGAN package into the -standard install location for python packages, and will put GFPGAN into a subdirectory of "src" -in the stable-diffusion directory. -(The reason for this is that the standard GFPGAN distribution has a minor bug that adversely affects image -color.) Upscaling with Real-ESRGAN should "just work" without further intervention. Simply pass the --upscale (-U) -option on the dream> command line, or indicate the desired scale on the popup in the Web GUI. - -For **GFPGAN** to work, there is one additional step needed. You will need to download and -copy the GFPGAN [models file](https://github.com/TencentARC/GFPGAN/releases/download/v1.3.0/GFPGANv1.3.pth) -into **src/gfpgan/experiments/pretrained_models**. On Mac and Linux systems, here's how you'd do it using -**wget**: -~~~~ -> wget https://github.com/TencentARC/GFPGAN/releases/download/v1.3.0/GFPGANv1.3.pth -P src/gfpgan/experiments/pretrained_models/ -~~~~ - -Make sure that you're in the stable-diffusion directory when you do this. - -Alternatively, if you have GFPGAN installed elsewhere, or if you are using -an earlier version of this package which asked you to install GFPGAN in a -sibling directory, you may use the `--gfpgan_dir` argument with `dream.py` to set a -custom path to your GFPGAN directory. _There are other GFPGAN related -boot arguments if you wish to customize further._ - -**Note: Internet connection needed:** -Users whose GPU machines are isolated from the Internet (e.g. on a -University cluster) should be aware that the first time you run -dream.py with GFPGAN and Real-ESRGAN turned on, it will try to -download model files from the Internet. To rectify this, you may run -`python3 scripts/preload_models.py` after you have installed GFPGAN -and all its dependencies. - -**Usage** - -You will now have access to two new prompt arguments. - -**Upscaling** - -`-U : ` - -The upscaling prompt argument takes two values. The first value is a -scaling factor and should be set to either `2` or `4` only. This will -either scale the image 2x or 4x respectively using different models. - -You can set the scaling stength between `0` and `1.0` to control -intensity of the of the scaling. This is handy because AI upscalers -generally tend to smooth out texture details. If you wish to retain -some of those for natural looking results, we recommend using values -between `0.5 to 0.8`. - -If you do not explicitly specify an upscaling_strength, it will -default to 0.75. - -**Face Restoration** - -`-G : ` - -This prompt argument controls the strength of the face restoration -that is being applied. Similar to upscaling, values between `0.5 to 0.8` are recommended. - -You can use either one or both without any conflicts. In cases where -you use both, the image will be first upscaled and then the face -restoration process will be executed to ensure you get the highest -quality facial features. - -`--save_orig` - -When you use either `-U` or `-G`, the final result you get is upscaled -or face modified. If you want to save the original Stable Diffusion -generation, you can use the `-save_orig` prompt argument to save the -original unaffected version too. - -**Example Usage** - -``` -dream > superman dancing with a panda bear -U 2 0.6 -G 0.4 -``` - -This also works with img2img: - -``` -dream> a man wearing a pineapple hat -I path/to/your/file.png -U 2 0.5 -G 0.6 -``` - -**Note** - -GFPGAN and Real-ESRGAN are both memory intensive. In order to avoid -crashes and memory overloads during the Stable Diffusion process, -these effects are applied after Stable Diffusion has completed its -work. - -In single image generations, you will see the output right away but -when you are using multiple iterations, the images will first be -generated and then upscaled and face restored after that process is -complete. While the image generation is taking place, you will still -be able to preview the base images. - -If you wish to stop during the image generation but want to upscale or -face restore a particular generated image, pass it again with the same -prompt and generated seed along with the `-U` and `-G` prompt -arguments to perform those actions. diff --git a/docs/features/VARIATIONS.md b/docs/features/VARIATIONS.md index a6c5c936c1..aeeb57d52c 100644 --- a/docs/features/VARIATIONS.md +++ b/docs/features/VARIATIONS.md @@ -1,29 +1,39 @@ -# **Variations** +--- +title: Variations +--- + +# :material-tune-variant: Variations + +## Intro Release 1.13 of SD-Dream adds support for image variations. You are able to do the following: -1. Generate a series of systematic variations of an image, given a prompt. The amount of variation from one image to the next can be controlled. +1. Generate a series of systematic variations of an image, given a prompt. The + amount of variation from one image to the next can be controlled. -2. Given two or more variations that you like, you can combine them in a weighted fashion. +2. Given two or more variations that you like, you can combine them in a + weighted fashion. ---- +!!! Information "" -This cheat sheet provides a quick guide for how this works in practice, using variations to create the desired image of Xena, Warrior Princess. - ---- + This cheat sheet provides a quick guide for how this works in practice, using + variations to create the desired image of Xena, Warrior Princess. ## Step 1 -- Find a base image that you like -The prompt we will use throughout is `lucy lawless as xena, warrior princess, character portrait, high resolution.` +The prompt we will use throughout is: -This will be indicated as `prompt` in the examples below. +`#!bash "lucy lawless as xena, warrior princess, character portrait, high resolution."` -First we let SD create a series of images in the usual way, in this case requesting six iterations: +This will be indicated as `#!bash "prompt"` in the examples below. -``` -dream> lucy lawless as xena, warrior princess, character portrait, high resolution -n6 +First we let SD create a series of images in the usual way, in this case +requesting six iterations: + +```bash +invoke> lucy lawless as xena, warrior princess, character portrait, high resolution -n6 ... Outputs: ./outputs/Xena/000001.1579445059.png: "prompt" -s50 -W512 -H512 -C7.5 -Ak_lms -S1579445059 @@ -34,20 +44,22 @@ Outputs: ./outputs/Xena/000001.3357757885.png: "prompt" -s50 -W512 -H512 -C7.5 -Ak_lms -S3357757885 ``` -The one with seed 3357757885 looks nice: - - +
+![var1](../assets/variation_walkthru/000001.3357757885.png) +
Seed 3357757885 looks nice
+
--- ## Step 2 - Generating Variations -Let's try to generate some variations. Using the same seed, we pass the argument `-v0.1` (or --variant_amount), which generates a series of -variations each differing by a variation amount of 0.2. This number ranges from `0` to `1.0`, with higher numbers being larger amounts of -variation. +Let's try to generate some variations. Using the same seed, we pass the argument +`-v0.1` (or --variant_amount), which generates a series of variations each +differing by a variation amount of 0.2. This number ranges from `0` to `1.0`, +with higher numbers being larger amounts of variation. -``` -dream> "prompt" -n6 -S3357757885 -v0.2 +```bash +invoke> "prompt" -n6 -S3357757885 -v0.2 ... Outputs: ./outputs/Xena/000002.784039624.png: "prompt" -s50 -W512 -H512 -C7.5 -Ak_lms -V 784039624:0.2 -S3357757885 @@ -60,33 +72,51 @@ Outputs: ### **Variation Sub Seeding** -Note that the output for each image has a `-V` option giving the "variant subseed" for that image, consisting of a seed followed by the -variation amount used to generate it. +Note that the output for each image has a `-V` option giving the "variant +subseed" for that image, consisting of a seed followed by the variation amount +used to generate it. -This gives us a series of closely-related variations, including the two shown here. +This gives us a series of closely-related variations, including the two shown +here. - - +
+![var2](../assets/variation_walkthru/000002.3647897225.png) +
subseed 3647897225
+
-I like the expression on Xena's face in the first one (subseed 3647897225), and the armor on her shoulder in the second one (subseed 1614299449). Can we combine them to get the best of both worlds? +
+![var3](../assets/variation_walkthru/000002.1614299449.png) +
subseed 1614299449
+
-We combine the two variations using `-V` (--with_variations). Again, we must provide the seed for the originally-chosen image in order for -this to work. +I like the expression on Xena's face in the first one (subseed 3647897225), and +the armor on her shoulder in the second one (subseed 1614299449). Can we combine +them to get the best of both worlds? -``` -dream> "prompt" -S3357757885 -V3647897225,0.1;1614299449,0.1 +We combine the two variations using `-V` (`--with_variations`). Again, we must +provide the seed for the originally-chosen image in order for this to work. + +```bash +invoke> "prompt" -S3357757885 -V3647897225,0.1,1614299449,0.1 Outputs: ./outputs/Xena/000003.1614299449.png: "prompt" -s50 -W512 -H512 -C7.5 -Ak_lms -V 3647897225:0.1,1614299449:0.1 -S3357757885 ``` -Here we are providing equal weights (0.1 and 0.1) for both the subseeds. The resulting image is close, but not exactly what I wanted: +Here we are providing equal weights (0.1 and 0.1) for both the subseeds. The +resulting image is close, but not exactly what I wanted: - +
+![var4](../assets/variation_walkthru/000003.1614299449.png) +
subseed 1614299449
+
-We could either try combining the images with different weights, or we can generate more variations around the almost-but-not-quite image. We do the latter, using both the `-V` (combining) and `-v` (variation strength) options. Note that we use `-n6` to generate 6 variations: +We could either try combining the images with different weights, or we can +generate more variations around the almost-but-not-quite image. We do the +latter, using both the `-V` (combining) and `-v` (variation strength) options. +Note that we use `-n6` to generate 6 variations: -``` -dream> "prompt" -S3357757885 -V3647897225,0.1;1614299449,0.1 -v0.05 -n6 +```bash +invoke> "prompt" -S3357757885 -V3647897225,0.1,1614299449,0.1 -v0.05 -n6 Outputs: ./outputs/Xena/000004.3279757577.png: "prompt" -s50 -W512 -H512 -C7.5 -Ak_lms -V 3647897225:0.1,1614299449:0.1,3279757577:0.05 -S3357757885 ./outputs/Xena/000004.2853129515.png: "prompt" -s50 -W512 -H512 -C7.5 -Ak_lms -V 3647897225:0.1,1614299449:0.1,2853129515:0.05 -S3357757885 @@ -96,9 +126,26 @@ Outputs: ./outputs/Xena/000004.2183375608.png: "prompt" -s50 -W512 -H512 -C7.5 -Ak_lms -V 3647897225:0.1,1614299449:0.1,2183375608:0.05 -S3357757885 ``` -This produces six images, all slight variations on the combination of the chosen two images. Here's the one I like best: +This produces six images, all slight variations on the combination of the chosen +two images. Here's the one I like best: - +
+![var5](../assets/variation_walkthru/000004.3747154981.png) +
subseed 3747154981
+
-As you can see, this is a very powerful tool, which when combined with subprompt weighting, gives you great control over the content and -quality of your generated images. +As you can see, this is a very powerful tool, which when combined with subprompt +weighting, gives you great control over the content and quality of your +generated images. + +## Variations and Samplers + +The sampler you choose has a strong effect on variation strength. Some +samplers, such as `k_euler_a` are very "creative" and produce significant +amounts of image-to-image variation even when the seed is fixed and the +`-v` argument is very low. Others are more deterministic. Feel free to +experiment until you find the combination that you like. + +Also be aware of the [Perlin Noise](OTHER.md#thresholding-and-perlin-noise-initialization-options) +feature, which provides another way of introducing variability into your +image generation requests. diff --git a/docs/features/WEB.md b/docs/features/WEB.md index 9eb6aa5bfc..795d9cf962 100644 --- a/docs/features/WEB.md +++ b/docs/features/WEB.md @@ -1,13 +1,369 @@ -# Barebones Web Server +--- +title: InvokeAI Web Server +--- -As of version 1.10, this distribution comes with a bare bones web server (see screenshot). To use it, run the `dream.py` script by adding the `**--web**` option. +# :material-web: InvokeAI Web Server -``` -(ldm) ~/stable-diffusion$ python3 scripts/dream.py --web +As of version 2.0.0, this distribution comes with a full-featured web server +(see screenshot). To use it, run the `invoke.py` script by adding the `--web` +option: + +```bash +(invokeai) ~/InvokeAI$ python3 scripts/invoke.py --web ``` -You can then connect to the server by pointing your web browser at http://localhost:9090, or to the network name or IP address of the server. +You can then connect to the server by pointing your web browser at +http://localhost:9090. To reach the server from a different machine on your LAN, +you may launch the web server with the `--host` argument and either the IP +address of the host you are running it on, or the wildcard `0.0.0.0`. For +example: -Kudos to [Tesseract Cat](https://github.com/TesseractCat) for contributing this code, and to [dagf2101](https://github.com/dagf2101) for refining it. +```bash +(invokeai) ~/InvokeAI$ python3 scripts/invoke.py --web --host 0.0.0.0 +``` -![Dream Web Server](../assets/dream_web_server.png) +## Quick guided walkthrough of the WebGUI's features + +While most of the WebGUI's features are intuitive, here is a guided walkthrough +through its various components. + +![Invoke Web Server - Major Components](../assets/invoke-web-server-1.png){:width="640px"} + +The screenshot above shows the Text to Image tab of the WebGUI. There are three +main sections: + +1. A **control panel** on the left, which contains various settings for text to + image generation. The most important part is the text field (currently + showing `strawberry sushi`) for entering the text prompt, and the camera icon + directly underneath that will render the image. We'll call this the _Invoke_ + button from now on. + +2. The **current image** section in the middle, which shows a large format + version of the image you are currently working on. A series of buttons at the + top ("image to image", "Use All", "Use Seed", etc) lets you modify the image + in various ways. + +3. A \*_gallery_ section on the left that contains a history of the images you + have generated. These images are read and written to the directory specified + at launch time in `--outdir`. + +In addition to these three elements, there are a series of icons for changing +global settings, reporting bugs, and changing the theme on the upper right. + +There are also a series of icons to the left of the control panel (see +highlighted area in the screenshot below) which select among a series of tabs +for performing different types of operations. + +
+![Invoke Web Server - Control Panel](../assets/invoke-web-server-2.png){:width="512px"} +
+ +From top to bottom, these are: + +1. Text to Image - generate images from text +2. Image to Image - from an uploaded starting image (drawing or photograph) + generate a new one, modified by the text prompt +3. Inpainting (pending) - Interactively erase portions of a starting image and + have the AI fill in the erased region from a text prompt. +4. Outpainting (pending) - Interactively add blank space to the borders of a + starting image and fill in the background from a text prompt. +5. Postprocessing (pending) - Interactively postprocess generated images using a + variety of filters. + +The inpainting, outpainting and postprocessing tabs are currently in +development. However, limited versions of their features can already be accessed +through the Text to Image and Image to Image tabs. + +## Walkthrough + +The following walkthrough will exercise most (but not all) of the WebGUI's +feature set. + +### Text to Image + +1. Launch the WebGUI using `python scripts/invoke.py --web` and connect to it + with your browser by accessing `http://localhost:9090`. If the browser and + server are running on different machines on your LAN, add the option + `--host 0.0.0.0` to the launch command line and connect to the machine + hosting the web server using its IP address or domain name. + +2. If all goes well, the WebGUI should come up and you'll see a green + `connected` message on the upper right. + +#### Basics + +1. Generate an image by typing _strawberry sushi_ into the large prompt field + on the upper left and then clicking on the Invoke button (the one with the + Camera icon). After a short wait, you'll see a large image of sushi in the + image panel, and a new thumbnail in the gallery on the right. + + If you need more room on the screen, you can turn the gallery off by + clicking on the **x** to the right of "Your Invocations". You can turn it + back on later by clicking the image icon that appears in the gallery's + place. + + The images are written into the directory indicated by the `--outdir` option + provided at script launch time. By default, this is `outputs/img-samples` + under the InvokeAI directory. + +2. Generate a bunch of strawberry sushi images by increasing the number of + requested images by adjusting the Images counter just below the Camera + button. As each is generated, it will be added to the gallery. You can + switch the active image by clicking on the gallery thumbnails. + +3. Try playing with different settings, including image width and height, the + Sampler, the Steps and the CFG scale. + + Image _Width_ and _Height_ do what you'd expect. However, be aware that + larger images consume more VRAM memory and take longer to generate. + + The _Sampler_ controls how the AI selects the image to display. Some + samplers are more "creative" than others and will produce a wider range of + variations (see next section). Some samplers run faster than others. + + _Steps_ controls how many noising/denoising/sampling steps the AI will take. + The higher this value, the more refined the image will be, but the longer + the image will take to generate. A typical strategy is to generate images + with a low number of steps in order to select one to work on further, and + then regenerate it using a higher number of steps. + + The _CFG Scale_ controls how hard the AI tries to match the generated image + to the input prompt. You can go as high or low as you like, but generally + values greater than 20 won't improve things much, and values lower than 5 + will produce unexpected images. There are complex interactions between + _Steps_, _CFG Scale_ and the _Sampler_, so experiment to find out what works + for you. + +4. To regenerate a previously-generated image, select the image you want and + click _Use All_. This loads the text prompt and other original settings into + the control panel. If you then press _Invoke_ it will regenerate the image + exactly. You can also selectively modify the prompt or other settings to + tweak the image. + + Alternatively, you may click on _Use Seed_ to load just the image's seed, + and leave other settings unchanged. + +5. To regenerate a Stable Diffusion image that was generated by another SD + package, you need to know its text prompt and its _Seed_. Copy-paste the + prompt into the prompt box, unset the _Randomize Seed_ control in the + control panel, and copy-paste the desired _Seed_ into its text field. When + you Invoke, you will get something similar to the original image. It will + not be exact unless you also set the correct values for the original + sampler, CFG, steps and dimensions, but it will (usually) be close. + +#### Variations on a theme + +1. Let's try generating some variations. Select your favorite sushi image from + the gallery to load it. Then select "Use All" from the list of buttons + above. This will load up all the settings used to generate this image, + including its unique seed. + + Go down to the Variations section of the Control Panel and set the button to + On. Set Variation Amount to 0.2 to generate a modest number of variations on + the image, and also set the Image counter to `4`. Press the `invoke` button. + This will generate a series of related images. To obtain smaller variations, + just lower the Variation Amount. You may also experiment with changing the + Sampler. Some samplers generate more variability than others. _k_euler_a_ is + particularly creative, while _ddim_ is pretty conservative. + +2. For even more variations, experiment with increasing the setting for + _Perlin_. This adds a bit of noise to the image generation process. Note + that values of Perlin noise greater than 0.15 produce poor images for + several of the samplers. + +#### Facial reconstruction and upscaling + +Stable Diffusion frequently produces mangled faces, particularly when there are +multiple figures in the same scene. Stable Diffusion has particular issues with +generating reallistic eyes. InvokeAI provides the ability to reconstruct faces +using either the GFPGAN or CodeFormer libraries. For more information see +[POSTPROCESS](POSTPROCESS.md). + +1. Invoke a prompt that generates a mangled face. A prompt that often gives + this is "portrait of a lawyer, 3/4 shot" (this is not intended as a slur + against lawyers!) Once you have an image that needs some touching up, load + it into the Image panel, and press the button with the face icon + (highlighted in the first screenshot below). A dialog box will appear. Leave + _Strength_ at 0.8 and press \*Restore Faces". If all goes well, the eyes and + other aspects of the face will be improved (see the second screenshot) + + ![Invoke Web Server - Original Image](../assets/invoke-web-server-3.png) + + ![Invoke Web Server - Retouched Image](../assets/invoke-web-server-4.png) + + The facial reconstruction _Strength_ field adjusts how aggressively the face + library will try to alter the face. It can be as high as 1.0, but be aware + that this often softens the face airbrush style, losing some details. The + default 0.8 is usually sufficient. + +2. "Upscaling" is the process of increasing the size of an image while + retaining the sharpness. InvokeAI uses an external library called "ESRGAN" + to do this. To invoke upscaling, simply select an image and press the _HD_ + button above it. You can select between 2X and 4X upscaling, and adjust the + upscaling strength, which has much the same meaning as in facial + reconstruction. Try running this on one of your previously-generated images. + +3. Finally, you can run facial reconstruction and/or upscaling automatically + after each Invocation. Go to the Advanced Options section of the Control + Panel and turn on _Restore Face_ and/or _Upscale_. + +### Image to Image + +InvokeAI lets you take an existing image and use it as the basis for a new +creation. You can use any sort of image, including a photograph, a scanned +sketch, or a digital drawing, as long as it is in PNG or JPEG format. + +For this tutorial, we'll use files named +[Lincoln-and-Parrot-512.png](../assets/Lincoln-and-Parrot-512.png), and +[Lincoln-and-Parrot-512-transparent.png](../assets/Lincoln-and-Parrot-512-transparent.png). +Download these images to your local machine now to continue with the +walkthrough. + +1. Click on the _Image to Image_ tab icon, which is the second icon from the + top on the left-hand side of the screen: + +
+ ![Invoke Web Server - Image to Image Icon](../assets/invoke-web-server-5.png) +
+ + This will bring you to a screen similar to the one shown here: + +
+ ![Invoke Web Server - Image to Image Tab](../assets/invoke-web-server-6.png){:width="640px"} +
+ +2. Drag-and-drop the Lincoln-and-Parrot image into the Image panel, or click + the blank area to get an upload dialog. The image will load into an area + marked _Initial Image_. (The WebGUI will also load the most + recently-generated image from the gallery into a section on the left, but + this image will be replaced in the next step.) + +3. Go to the prompt box and type _old sea captain with raven on shoulder_ and + press Invoke. A derived image will appear to the right of the original one: + + ![Invoke Web Server - Image to Image example](../assets/invoke-web-server-7.png){:width="640px"} + +4. Experiment with the different settings. The most influential one in Image to + Image is _Image to Image Strength_ located about midway down the control + panel. By default it is set to 0.75, but can range from 0.0 to 0.99. The + higher the value, the more of the original image the AI will replace. A + value of 0 will leave the initial image completely unchanged, while 0.99 + will replace it completely. However, the Sampler and CFG Scale also + influence the final result. You can also generate variations in the same way + as described in Text to Image. + +5. What if we only want to change certain part(s) of the image and leave the + rest intact? This is called Inpainting, and a future version of the InvokeAI + web server will provide an interactive painting canvas on which you can + directly draw the areas you wish to Inpaint into. For now, you can achieve + this effect by using an external photoeditor tool to make one or more + regions of the image transparent as described in [INPAINTING.md] and + uploading that. + + The file + [Lincoln-and-Parrot-512-transparent.png](../assets/Lincoln-and-Parrot-512-transparent.png) + is a version of the earlier image in which the area around the parrot has + been replaced with transparency. Click on the "x" in the upper right of the + Initial Image and upload the transparent version. Using the same prompt "old + sea captain with raven on shoulder" try Invoking an image. This time, only + the parrot will be replaced, leaving the rest of the original image intact: + +
+ ![Invoke Web Server - Inpainting](../assets/invoke-web-server-8.png){:width="640px"} +
+ +6. Would you like to modify a previously-generated image using the Image to + Image facility? Easy! While in the Image to Image panel, hover over any of + the gallery images to see a little menu of icons pop up. Click the picture + icon to instantly send the selected image to Image to Image as the initial + image. + +You can do the same from the Text to Image tab by clicking on the picture icon +above the central image panel. The screenshot below shows where the "use as +initial image" icons are located. + +![Invoke Web Server - Use as Image Links](../assets/invoke-web-server-9.png){:width="640px"} + +## Parting remarks + +This concludes the walkthrough, but there are several more features that you can +explore. Please check out the [Command Line Interface](CLI.md) documentation for +further explanation of the advanced features that were not covered here. + +The WebGUI is only rapid development. Check back regularly for updates! + +## Reference + +### Additional Options + +| parameter | effect | +| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | +| `--web_develop` | Starts the web server in development mode. | +| `--web_verbose` | Enables verbose logging | +| `--cors [CORS ...]` | Additional allowed origins, comma-separated | +| `--host HOST` | Web server: Host or IP to listen on. Set to 0.0.0.0 to accept traffic from other devices on your network. | +| `--port PORT` | Web server: Port to listen on | +| `--gui` | Start InvokeAI GUI - This is the "desktop mode" version of the web app. It uses Flask to create a desktop app experience of the webserver. | + +### Web Specific Features + +The web experience offers an incredibly easy-to-use experience for interacting +with the InvokeAI toolkit. For detailed guidance on individual features, see the +Feature-specific help documents available in this directory. Note that the +latest functionality available in the CLI may not always be available in the Web +interface. + +#### Dark Mode & Light Mode + +The InvokeAI interface is available in a nano-carbon black & purple Dark Mode, +and a "burn your eyes out Nosferatu" Light Mode. These can be toggled by +clicking the Sun/Moon icons at the top right of the interface. + +![InvokeAI Web Server - Dark Mode](../assets/invoke_web_dark.png) + +![InvokeAI Web Server - Light Mode](../assets/invoke_web_light.png) + +#### Invocation Toolbar + +The left side of the InvokeAI interface is available for customizing the prompt +and the settings used for invoking your new image. Typing your prompt into the +open text field and clicking the Invoke button will produce the image based on +the settings configured in the toolbar. + +See below for additional documentation related to each feature: + +- [Core Prompt Settings](./CLI.md) +- [Variations](./VARIATIONS.md) +- [Upscaling](./POSTPROCESS.md#upscaling) +- [Image to Image](./IMG2IMG.md) +- [Inpainting](./INPAINTING.md) +- [Other](./OTHER.md) + +#### Invocation Gallery + +The currently selected --outdir (or the default outputs folder) will display all +previously generated files on load. As new invocations are generated, these will +be dynamically added to the gallery, and can be previewed by selecting them. +Each image also has a simple set of actions (e.g., Delete, Use Seed, Use All +Parameters, etc.) that can be accessed by hovering over the image. + +#### Image Workspace + +When an image from the Invocation Gallery is selected, or is generated, the +image will be displayed within the center of the interface. A quickbar of common +image interactions are displayed along the top of the image, including: + +- Use image in the `Image to Image` workflow +- Initialize Face Restoration on the selected file +- Initialize Upscaling on the selected file +- View File metadata and details +- Delete the file + +## Acknowledgements + +A huge shout-out to the core team working to make this vision a reality, +including [psychedelicious](https://github.com/psychedelicious), +[Kyle0654](https://github.com/Kyle0654) and +[blessedcoolant](https://github.com/blessedcoolant). +[hipsterusername](https://github.com/hipsterusername) was the team's unofficial +cheerleader and added tooltips/docs. diff --git a/docs/features/WEBUIHOTKEYS.md b/docs/features/WEBUIHOTKEYS.md new file mode 100644 index 0000000000..89432687dc --- /dev/null +++ b/docs/features/WEBUIHOTKEYS.md @@ -0,0 +1,62 @@ +--- +title: WebUI Hotkey List +--- + +# **WebUI Hotkey List** + +## General + +| Setting | Hotkey | +| ----------------- | ---------------------- | +| ++a++ | Set All Parameters | +| ++s++ | Set Seed | +| ++u++ | Upscale | +| ++r++ | Restoration | +| ++i++ | Show Metadata | +| ++d++ ++d++ ++l++ | Delete Image | +| ++alt+a++ | Focus prompt input | +| ++shift+i++ | Send To Image to Image | +| ++ctrl+enter++ | Start processing | +| ++shift+x++ | cancel Processing | +| ++shift+d++ | Toggle Dark Mode | +| ` | Toggle console | + +## Tabs + +| Setting | Hotkey | +| ------- | ------------------------- | +| ++1++ | Go to Text To Image Tab | +| ++2++ | Go to Image to Image Tab | +| ++3++ | Go to Inpainting Tab | +| ++4++ | Go to Outpainting Tab | +| ++5++ | Go to Nodes Tab | +| ++6++ | Go to Post Processing Tab | + +## Gallery + +| Setting | Hotkey | +| -------------- | ------------------------------- | +| ++g++ | Toggle Gallery | +| ++left++ | Go to previous image in gallery | +| ++right++ | Go to next image in gallery | +| ++shift+p++ | Pin gallery | +| ++shift+up++ | Increase gallery image size | +| ++shift+down++ | Decrease gallery image size | +| ++shift+r++ | Reset image gallery size | + +## Inpainting + +| Setting | Hotkey | +| ---------------------------- | --------------------- | +| [ | Decrease brush size | +| ] | Increase brush size | +| alt + [ | Decrease mask opacity | +| alt + ] | Increase mask opacity | +| ++b++ | Select brush | +| ++e++ | Select eraser | +| ++ctrl+z++ | Undo brush stroke | +| ++ctrl+shift+z++, ++ctrl+y++ | Redo brush stroke | +| ++h++ | Hide mask | +| ++shift+m++ | Invert mask | +| ++shift+c++ | Clear mask | +| ++shift+j++ | Expand canvas | diff --git a/docs/help/SAMPLER_CONVERGENCE.md b/docs/help/SAMPLER_CONVERGENCE.md new file mode 100644 index 0000000000..638f686bcd --- /dev/null +++ b/docs/help/SAMPLER_CONVERGENCE.md @@ -0,0 +1,151 @@ +--- +title: Sampler Convergence +--- + +# :material-palette-advanced: *Sampler Convergence* + +As features keep increasing, making the right choices for your needs can become increasingly difficult. What sampler to use? And for how many steps? Do you change the CFG value? Do you use prompt weighting? Do you allow variations? + +Even once you have a result, do you blend it with other images? Pass it through `img2img`? With what strength? Do you use inpainting to correct small details? Outpainting to extend cropped sections? + +The purpose of this series of documents is to help you better understand these tools, so you can make the best out of them. Feel free to contribute with your own findings! + +In this document, we will talk about sampler convergence. + +Looking for a short version? Here's a TL;DR in 3 tables. + +!!! note "Remember" + + - Results converge as steps (`-s`) are increased (except for `K_DPM_2_A` and `K_EULER_A`). Often at ≥ `-s100`, but may require ≥ `-s700`). + - Producing a batch of candidate images at low (`-s8` to `-s30`) step counts can save you hours of computation. + - `K_HEUN` and `K_DPM_2` converge in less steps (but are slower). + - `K_DPM_2_A` and `K_EULER_A` incorporate a lot of creativity/variability. + +
+ +| Sampler | (3 sample avg) it/s (M1 Max 64GB, 512x512) | +|---|---| +| `DDIM` | 1.89 | +| `PLMS` | 1.86 | +| `K_EULER` | 1.86 | +| `K_LMS` | 1.91 | +| `K_HEUN` | 0.95 (slower) | +| `K_DPM_2` | 0.95 (slower) | +| `K_DPM_2_A` | 0.95 (slower) | +| `K_EULER_A` | 1.86 | + +
+ +!!! tip "suggestions" + + For most use cases, `K_LMS`, `K_HEUN` and `K_DPM_2` are the best choices (the latter 2 run 0.5x as quick, but tend to converge 2x as quick as `K_LMS`). At very low steps (≤ `-s8`), `K_HEUN` and `K_DPM_2` are not recommended. Use `K_LMS` instead. + + For variability, use `K_EULER_A` (runs 2x as quick as `K_DPM_2_A`). + +--- + +### *Sampler results* + +Let's start by choosing a prompt and using it with each of our 8 samplers, running it for 10, 20, 30, 40, 50 and 100 steps. + +Anime. `"an anime girl" -W512 -H512 -C7.5 -S3031912972` + +![191636411-083c8282-6ed1-4f78-9273-ee87c0a0f1b6-min (1)](https://user-images.githubusercontent.com/50542132/191868725-7f7af991-e254-4c1f-83e7-bed8c9b2d34f.png) + +### *Sampler convergence* + +Immediately, you can notice results tend to converge -that is, as `-s` (step) values increase, images look more and more similar until there comes a point where the image no longer changes. + +You can also notice how `DDIM` and `PLMS` eventually tend to converge to K-sampler results as steps are increased. +Among K-samplers, `K_HEUN` and `K_DPM_2` seem to require the fewest steps to converge, and even at low step counts they are good indicators of the final result. And finally, `K_DPM_2_A` and `K_EULER_A` seem to do a bit of their own thing and don't keep much similarity with the rest of the samplers. + +### *Batch generation speedup* + +This realization is very useful because it means you don't need to create a batch of 100 images (`-n100`) at `-s100` to choose your favorite 2 or 3 images. +You can produce the same 100 images at `-s10` to `-s30` using a K-sampler (since they converge faster), get a rough idea of the final result, choose your 2 or 3 favorite ones, and then run `-s100` on those images to polish some details. +The latter technique is 3-8x as quick. + +!!! example + + At 60s per 100 steps. + + A) 60s * 100 images = 6000s (100 images at `-s100`, manually picking 3 favorites) + + B) 6s *100 images + 60s* 3 images = 780s (100 images at `-s10`, manually picking 3 favorites, and running those 3 at `-s100` to polish details) + + The result is __1 hour and 40 minutes__ for Variant A, vs __13 minutes__ for Variant B. + +### *Topic convergance* + +Now, these results seem interesting, but do they hold for other topics? How about nature? Food? People? Animals? Let's try! + +Nature. `"valley landscape wallpaper, d&d art, fantasy, painted, 4k, high detail, sharp focus, washed colors, elaborate excellent painted illustration" -W512 -H512 -C7.5 -S1458228930` + +![191736091-dda76929-00d1-4590-bef4-7314ea4ea419-min (1)](https://user-images.githubusercontent.com/50542132/191868763-b151c69e-0a72-4cf1-a151-5a64edd0c93e.png) + +With nature, you can see how initial results are even more indicative of final result -more so than with characters/people. `K_HEUN` and `K_DPM_2` are again the quickest indicators, almost right from the start. Results also converge faster (e.g. `K_HEUN` converged at `-s21`). + +Food. `"a hamburger with a bowl of french fries" -W512 -H512 -C7.5 -S4053222918` + +![191639011-f81d9d38-0a15-45f0-9442-a5e8d5c25f1f-min (1)](https://user-images.githubusercontent.com/50542132/191868898-98801a62-885f-4ea1-aee8-563503522aa9.png) + +Again, `K_HEUN` and `K_DPM_2` take the fewest number of steps to be good indicators of the final result. `K_DPM_2_A` and `K_EULER_A` seem to incorporate a lot of creativity/variability, capable of producing rotten hamburgers, but also of adding lettuce to the mix. And they're the only samplers that produced an actual 'bowl of fries'! + +Animals. `"grown tiger, full body" -W512 -H512 -C7.5 -S3721629802` + +![191771922-6029a4f5-f707-4684-9011-c6f96e25fe56-min (1)](https://user-images.githubusercontent.com/50542132/191868870-9e3b7d82-b909-429f-893a-13f6ec343454.png) + +`K_HEUN` and `K_DPM_2` once again require the least number of steps to be indicative of the final result (around `-s30`), while other samplers are still struggling with several tails or malformed back legs. + +It also takes longer to converge (for comparison, `K_HEUN` required around 150 steps to converge). This is normal, as producing human/animal faces/bodies is one of the things the model struggles the most with. For these topics, running for more steps will often increase coherence within the composition. + +People. `"Ultra realistic photo, (Miranda Bloom-Kerr), young, stunning model, blue eyes, blond hair, beautiful face, intricate, highly detailed, smooth, art by artgerm and greg rutkowski and alphonse mucha, stained glass" -W512 -H512 -C7.5 -S2131956332`. This time, we will go up to 300 steps. + +![Screenshot 2022-09-23 at 02 05 48-min (1)](https://user-images.githubusercontent.com/50542132/191871743-6802f199-0ffd-4986-98c5-df2d8db30d18.png) + +Observing the results, it again takes longer for all samplers to converge (`K_HEUN` took around 150 steps), but we can observe good indicative results much earlier (see: `K_HEUN`). Conversely, `DDIM` and `PLMS` are still undergoing moderate changes (see: lace around her neck), even at `-s300`. + +In fact, as we can see in this other experiment, some samplers can take 700+ steps to converge when generating people. + +![191988191-c586b75a-2d7f-4351-b705-83cc1149881a-min (1)](https://user-images.githubusercontent.com/50542132/191992123-7e0759d6-6220-42c4-a961-88c7071c5ee6.png) + +Note also the point of convergence may not be the most desirable state (e.g. I prefer an earlier version of the face, more rounded), but it will probably be the most coherent arms/hands/face attributes-wise. You can always merge different images with a photo editing tool and pass it through `img2img` to smoothen the composition. + +### *Sampler generation times* + +Once we understand the concept of sampler convergence, we must look into the performance of each sampler in terms of steps (iterations) per second, as not all samplers run at the same speed. + +
+ +On my M1 Max with 64GB of RAM, for a 512x512 image + +| Sampler | (3 sample average) it/s | +| :--- | :--- | +| `DDIM` | 1.89 | +| `PLMS` | 1.86 | +| `K_EULER` | 1.86 | +| `K_LMS` | 1.91 | +| `K_HEUN` | 0.95 (slower) | +| `K_DPM_2` | 0.95 (slower) | +| `K_DPM_2_A` | 0.95 (slower) | +| `K_EULER_A` | 1.86 | + +
+ +Combining our results with the steps per second of each sampler, three choices come out on top: `K_LMS`, `K_HEUN` and `K_DPM_2` (where the latter two run 0.5x as quick but tend to converge 2x as quick as `K_LMS`). For creativity and a lot of variation between iterations, `K_EULER_A` can be a good choice (which runs 2x as quick as `K_DPM_2_A`). + +Additionally, image generation at very low steps (≤ `-s8`) is not recommended for `K_HEUN` and `K_DPM_2`. Use `K_LMS` instead. + +![K-compare](https://user-images.githubusercontent.com/50542132/192046823-2714cb29-bbf3-4eb1-9213-e27a0963905c.png){ width=600} + +### *Three key points* + +Finally, it is relevant to mention that, in general, there are 3 important moments in the process of image formation as steps increase: + +* The (earliest) point at which an image becomes a good indicator of the final result (useful for batch generation at low step values, to then improve the quality/coherence of the chosen images via running the same prompt and seed for more steps). + +* The (earliest) point at which an image becomes coherent, even if different from the result if steps are increased (useful for batch generation at low step values, where quality/coherence is improved via techniques other than increasing the steps -e.g. via inpainting). + +* The point at which an image fully converges. + +Hence, remember that your workflow/strategy should define your optimal number of steps, even for the same prompt and seed (for example, if you seek full convergence, you may run `K_LMS` for `-s200` in the case of the red-haired girl, but `K_LMS` and `-s20`-taking one tenth the time- may do as well if your workflow includes adding small details, such as the missing shoulder strap, via `img2img`). diff --git a/docs/help/TROUBLESHOOT.md b/docs/help/TROUBLESHOOT.md index cac5dddf23..dc2a9a8e41 100644 --- a/docs/help/TROUBLESHOOT.md +++ b/docs/help/TROUBLESHOOT.md @@ -1,68 +1,127 @@ -# **Frequently Asked Questions** +--- +title: F.A.Q. +hide: + - toc +--- -Here are a few common installation problems and their solutions. Often these are caused by incomplete installations or crashes during the -install process. +# :material-frequently-asked-questions: F.A.Q. + +## **Frequently-Asked-Questions** + +Here are a few common installation problems and their solutions. Often these are caused by +incomplete installations or crashes during the install process. --- -**QUESTION** +### **QUESTION** -During `conda env create -f environment.yaml`, conda hangs indefinitely. +During `conda env create`, conda hangs indefinitely. + +If it is because of the last PIP step (usually stuck in the Git Clone step, you can check the detailed log by this method): +```bash +export PIP_LOG="/tmp/pip_log.txt" +touch ${PIP_LOG} +tail -f ${PIP_LOG} & +conda env create -f environment-mac.yaml --debug --verbose +killall tail +rm ${PIP_LOG} +``` **SOLUTION** -Enter the stable-diffusion directory and completely remove the `src` directory and all its contents. The safest way to do this is to enter the stable-diffusion directory and give the command `git clean -f`. If this still doesn't fix the problem, try "conda clean -all" and then restart at the `conda env create` step. +Conda sometimes gets stuck at the last PIP step, in which several git repositories are +cloned and built. + +Enter the stable-diffusion directory and completely remove the `src` +directory and all its contents. The safest way to do this is to enter +the stable-diffusion directory and give the command `git clean -f`. If +this still doesn't fix the problem, try "conda clean -all" and then +restart at the `conda env create` step. + +To further understand the problem to checking the install lot using this method: + +```bash +export PIP_LOG="/tmp/pip_log.txt" +touch ${PIP_LOG} +tail -f ${PIP_LOG} & +conda env create -f environment-mac.yaml --debug --verbose +killall tail +rm ${PIP_LOG} +``` --- -**QUESTION** +### **QUESTION** -`dream.py` crashes with the complaint that it can't find `ldm.simplet2i.py`. Or it complains that function is being passed incorrect parameters. +`invoke.py` crashes with the complaint that it can't find `ldm.simplet2i.py`. Or it complains that +function is being passed incorrect parameters. -**SOLUTION** +### **SOLUTION** -Reinstall the stable diffusion modules. Enter the `stable-diffusion` directory and give the command `pip install -e .` +Reinstall the stable diffusion modules. Enter the `stable-diffusion` directory and give the command +`pip install -e .` --- -**QUESTION** +### **QUESTION** -`dream.py` dies, complaining of various missing modules, none of which starts with `ldm``. +`invoke.py` dies, complaining of various missing modules, none of which starts with `ldm`. -**SOLUTION** +### **SOLUTION** -From within the `stable-diffusion` directory, run `conda env update -f environment.yaml` This is also frequently the solution to +From within the `InvokeAI` directory, run `conda env update` This is also frequently the solution to complaints about an unknown function in a module. --- -**QUESTION** +### **QUESTION** There's a feature or bugfix in the Stable Diffusion GitHub that you want to try out. -**SOLUTION** +### **SOLUTION** -**Main Branch** +#### **Main Branch** -If the fix/feature is on the `main` branch, enter the stable-diffusion directory and do a `git pull`. +If the fix/feature is on the `main` branch, enter the stable-diffusion directory and do a +`git pull`. -Usually this will be sufficient, but if you start to see errors about missing or incorrect modules, use the command `pip install -e .` and/or `conda env update -f environment.yaml` (These commands won't break anything.) +Usually this will be sufficient, but if you start to see errors about +missing or incorrect modules, use the command `pip install -e .` +and/or `conda env update` (These commands won't break anything.) -**Sub Branch** +`pip install -e .` and/or `conda env update -f environment.yaml` -If the feature/fix is on a branch (e.g. "_foo-bugfix_"), the recipe is similar, but do a `git pull `. +(These commands won't break anything.) -**Not Committed** +#### **Sub Branch** -If the feature/fix is in a pull request that has not yet been made part of the main branch or a feature/bugfix branch, then from the page for the desired pull request, look for the line at the top that reads "_xxxx wants to merge xx commits into lstein:main from YYYYYY_". Copy the URL in YYYY. It should have the format `https://github.com//stable-diffusion/tree/` +If the feature/fix is on a branch (e.g. "_foo-bugfix_"), the recipe is similar, but do a +`git pull `. -Then **go to the directory above stable-diffusion** and rename the directory to "_stable-diffusion.lstein_", "_stable-diffusion.old_", or anything else. You can then git clone the branch that contains the pull request: +#### **Not Committed** -``` -git clone https://github.com//stable-diffusion/tree/ -``` +If the feature/fix is in a pull request that has not yet been made part of the main branch or a +feature/bugfix branch, then from the page for the desired pull request, look for the line at the top +that reads "_xxxx wants to merge xx commits into lstein:main from YYYYYY_". Copy the URL in YYYY. It +should have the format -You will need to go through the install procedure again, but it should be fast because all the dependencies are already loaded. +`https://github.com//stable-diffusion/tree/` + +Then **go to the directory above stable-diffusion** and rename the directory to +"_stable-diffusion.lstein_", "_stable-diffusion.old_", or anything else. You can then git clone the +branch that contains the pull request: + +`git clone https://github.com//stable-diffusion/tree/` + +You will need to go through the install procedure again, but it should be fast because all the +dependencies are already loaded. --- + +### **QUESTION** + +Image generation crashed with CUDA out of memory error after successful sampling. + +### **SOLUTION** + +Try to run script with option `--free_gpu_mem` This will free memory before image decoding step. diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000000..d58b25e628 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,19 @@ + + + + + + Swagger UI + + + + + + + +
+ + + + + diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000000..25275b56a9 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,175 @@ +--- +title: Home +--- + + +
+ +# ^^**InvokeAI: A Stable Diffusion Toolkit**^^ :tools:
Formerly known as lstein/stable-diffusion + +![project logo](assets/logo.png) + +[![discord badge]][discord link] + +[![latest release badge]][latest release link] [![github stars badge]][github stars link] [![github forks badge]][github forks link] + +[![CI checks on main badge]][CI checks on main link] [![CI checks on dev badge]][CI checks on dev link] [![latest commit to dev badge]][latest commit to dev link] + +[![github open issues badge]][github open issues link] [![github open prs badge]][github open prs link] + +[CI checks on dev badge]: https://flat.badgen.net/github/checks/invoke-ai/InvokeAI/development?label=CI%20status%20on%20dev&cache=900&icon=github +[CI checks on dev link]: https://github.com/invoke-ai/InvokeAI/actions?query=branch%3Adevelopment +[CI checks on main badge]: https://flat.badgen.net/github/checks/invoke-ai/InvokeAI/main?label=CI%20status%20on%20main&cache=900&icon=github +[CI checks on main link]: https://github.com/invoke-ai/InvokeAI/actions/workflows/test-invoke-conda.yml +[discord badge]: https://flat.badgen.net/discord/members/ZmtBAhwWhy?icon=discord +[discord link]: https://discord.gg/ZmtBAhwWhy +[github forks badge]: https://flat.badgen.net/github/forks/invoke-ai/InvokeAI?icon=github +[github forks link]: https://useful-forks.github.io/?repo=lstein%2Fstable-diffusion +[github open issues badge]: https://flat.badgen.net/github/open-issues/invoke-ai/InvokeAI?icon=github +[github open issues link]: https://github.com/invoke-ai/InvokeAI/issues?q=is%3Aissue+is%3Aopen +[github open prs badge]: https://flat.badgen.net/github/open-prs/invoke-ai/InvokeAI?icon=github +[github open prs link]: https://github.com/invoke-ai/InvokeAI/pulls?q=is%3Apr+is%3Aopen +[github stars badge]: https://flat.badgen.net/github/stars/invoke-ai/InvokeAI?icon=github +[github stars link]: https://github.com/invoke-ai/InvokeAI/stargazers +[latest commit to dev badge]: https://flat.badgen.net/github/last-commit/invoke-ai/InvokeAI/development?icon=github&color=yellow&label=last%20dev%20commit&cache=900 +[latest commit to dev link]: https://github.com/invoke-ai/InvokeAI/commits/development +[latest release badge]: https://flat.badgen.net/github/release/invoke-ai/InvokeAI/development?icon=github +[latest release link]: https://github.com/invoke-ai/InvokeAI/releases + +
+ +InvokeAI is an +implementation of Stable Diffusion, the open source text-to-image and +image-to-image generator. It provides a streamlined process with +various new features and options to aid the image generation +process. It runs on Windows, Mac and Linux machines, and runs on GPU +cards with as little as 4 GB or RAM. + +**Quick links**: [Discord Server] [Code and Downloads] [Bug Reports] [Discussion, Ideas & Q&A] + +
+ +!!! note + + This fork is rapidly evolving. Please use the [Issues tab](https://github.com/invoke-ai/InvokeAI/issues) to report bugs and make feature requests. Be sure to use the provided templates. They will help aid diagnose issues faster. + +## :octicons-package-dependencies-24: Installation + +This fork is supported across multiple platforms. You can find individual installation instructions +below. + +- :fontawesome-brands-linux: [Linux](installation/INSTALL_LINUX.md) +- :fontawesome-brands-windows: [Windows](installation/INSTALL_WINDOWS.md) +- :fontawesome-brands-apple: [Macintosh](installation/INSTALL_MAC.md) + +## :fontawesome-solid-computer: Hardware Requirements + +### :octicons-cpu-24: System + +You wil need one of the following: + +- :simple-nvidia: An NVIDIA-based graphics card with 4 GB or more VRAM memory. +- :fontawesome-brands-apple: An Apple computer with an M1 chip. + +### :fontawesome-solid-memory: Memory + +- At least 12 GB Main Memory RAM. + +### :fontawesome-regular-hard-drive: Disk + +- At least 12 GB of free disk space for the machine learning model, Python, and all its dependencies. + +!!! info + + If you are have a Nvidia 10xx series card (e.g. the 1080ti), please run the invoke script in + full-precision mode as shown below. + + Similarly, specify full-precision mode on Apple M1 hardware. + + Precision is auto configured based on the device. If however you encounter errors like + `expected type Float but found Half` or `not implemented for Half` you can try starting + `invoke.py` with the `--precision=float32` flag: + + ```bash + (invokeai) ~/InvokeAI$ python scripts/invoke.py --full_precision + ``` + +## :octicons-log-16: Latest Changes + +### v2.0.1 (13 October 2022) + +- fix noisy images at high step count when using k* samplers +- dream.py script now calls invoke.py module directly rather than + via a new python process (which could break the environment) + +### v2.0.0 (9 October 2022) + +- `dream.py` script renamed `invoke.py`. A `dream.py` script wrapper remains + for backward compatibility. +- Completely new WebGUI - launch with `python3 scripts/invoke.py --web` +- Support for inpainting and outpainting +- img2img runs on all k* samplers +- Support for negative prompts +- Support for CodeFormer face reconstruction +- Support for Textual Inversion on Macintoshes +- Support in both WebGUI and CLI for post-processing of previously-generated images + using facial reconstruction, ESRGAN upscaling, outcropping (similar to DALL-E infinite canvas), + and "embiggen" upscaling. See the `!fix` command. +- New `--hires` option on `invoke>` line allows larger images to be created without duplicating elements, at the cost of some performance. +- New `--perlin` and `--threshold` options allow you to add and control variation + during image generation (see Thresholding and Perlin Noise Initialization +- Extensive metadata now written into PNG files, allowing reliable regeneration of images + and tweaking of previous settings. +- Command-line completion in `invoke.py` now works on Windows, Linux and Mac platforms. +- Improved command-line completion behavior. + New commands added: + - List command-line history with `!history` + - Search command-line history with `!search` + - Clear history with `!clear` +- Deprecated `--full_precision` / `-F`. Simply omit it and `invoke.py` will auto + configure. To switch away from auto use the new flag like `--precision=float32`. + +For older changelogs, please visit the **[CHANGELOG](CHANGELOG.md#v114-11-september-2022)**. + +## :material-target: Troubleshooting + +Please check out our **[:material-frequently-asked-questions: Q&A](help/TROUBLESHOOT.md)** to get solutions for common installation +problems and other issues. + +## :octicons-repo-push-24: Contributing + +Anyone who wishes to contribute to this project, whether documentation, features, bug fixes, code +cleanup, testing, or code reviews, is very much encouraged to do so. If you are unfamiliar with how +to contribute to GitHub projects, here is a +[Getting Started Guide](https://opensource.com/article/19/7/create-pull-request-github). + +A full set of contribution guidelines, along with templates, are in progress, but for now the most +important thing is to **make your pull request against the "development" branch**, and not against +"main". This will help keep public breakage to a minimum and will allow you to propose more radical +changes. + +## :octicons-person-24: Contributors + +This fork is a combined effort of various people from across the world. +[Check out the list of all these amazing people](other/CONTRIBUTORS.md). We thank them for their +time, hard work and effort. + +## :octicons-question-24: Support + +For support, please use this repository's GitHub Issues tracking service. Feel free to send me an +email if you use and like the script. + +Original portions of the software are Copyright (c) 2020 +[Lincoln D. Stein](https://github.com/lstein) + +## :octicons-book-24: Further Reading + +Please see the original README for more information on this software and underlying algorithm, +located in the file [README-CompViz.md](other/README-CompViz.md). diff --git a/docs/installation/INSTALLING_MODELS.md b/docs/installation/INSTALLING_MODELS.md new file mode 100644 index 0000000000..b5d659b0d1 --- /dev/null +++ b/docs/installation/INSTALLING_MODELS.md @@ -0,0 +1,267 @@ +--- +title: Installing Models +--- + +# :octicons-paintbrush-16: Installing Models + +## Model Weight Files + +The model weight files ('*.ckpt') are the Stable Diffusion "secret +sauce". They are the product of training the AI on millions of +captioned images gathered from multiple sources. + +Originally there was only a single Stable Diffusion weights file, +which many people named `model.ckpt`. Now there are dozens or more +that have been "fine tuned" to provide particulary styles, genres, or +other features. InvokeAI allows you to install and run multiple model +weight files and switch between them quickly in the command-line and +web interfaces. + +This manual will guide you through installing and configuring model +weight files. + +## Base Models + +InvokeAI comes with support for a good initial set of models listed in +the model configuration file `configs/models.yaml`. They are: + +| Model | Weight File | Description | DOWNLOAD FROM | +| ---------------------- | ----------------------------- |--------------------------------- | ----------------| +| stable-diffusion-1.5 | v1-5-pruned-emaonly.ckpt | Most recent version of base Stable Diffusion model| https://huggingface.co/runwayml/stable-diffusion-v1-5 | +| stable-diffusion-1.4 | sd-v1-4.ckpt | Previous version of base Stable Diffusion model | https://huggingface.co/CompVis/stable-diffusion-v-1-4-original | +| inpainting-1.5 | sd-v1-5-inpainting.ckpt | Stable Diffusion 1.5 model specialized for inpainting | https://huggingface.co/runwayml/stable-diffusion-inpainting | +| waifu-diffusion-1.3 | model-epoch09-float32.ckpt | Stable Diffusion 1.4 trained to produce anime images | https://huggingface.co/hakurei/waifu-diffusion-v1-3 | +| | vae-ft-mse-840000-ema-pruned.ckpt | A fine-tune file add-on file that improves face generation | https://huggingface.co/stabilityai/sd-vae-ft-mse-original/ | + + +Note that these files are covered by an "Ethical AI" license which +forbids certain uses. You will need to create an account on the +Hugging Face website and accept the license terms before you can +access the files. + +The predefined configuration file for InvokeAI (located at +`configs/models.yaml`) provides entries for each of these weights +files. `stable-diffusion-1.5` is the default model used, and we +strongly recommend that you install this weights file if nothing else. + +## Community-Contributed Models + +There are too many to list here and more are being contributed every +day. Hugging Face maintains a [fast-growing +repository](https://huggingface.co/sd-concepts-library) of fine-tune +(".bin") models that can be imported into InvokeAI by passing the +`--embedding_path` option to the `invoke.py` command. + +[This page](https://rentry.org/sdmodels) hosts a large list of +official and unofficial Stable Diffusion models and where they can be +obtained. + +## Installation + +There are three ways to install weights files: + +1. During InvokeAI installation, the `preload_models.py` script can +download them for you. + +2. You can use the command-line interface (CLI) to import, configure +and modify new models files. + +3. You can download the files manually and add the appropriate entries +to `models.yaml`. + +### Installation via `preload_models.py` + +This is the most automatic way. Run `scripts/preload_models.py` from +the console. It will ask you to select which models to download and +lead you through the steps of setting up a Hugging Face account if you +haven't done so already. + +To start, from within the InvokeAI directory run the command `python +scripts/preload_models.py` (Linux/MacOS) or `python +scripts\preload_models.py` (Windows): + +``` +Loading Python libraries... + +** INTRODUCTION ** +Welcome to InvokeAI. This script will help download the Stable Diffusion weight files +and other large models that are needed for text to image generation. At any point you may interrupt +this program and resume later. + +** WEIGHT SELECTION ** +Would you like to download the Stable Diffusion model weights now? [y] + +Choose the weight file(s) you wish to download. Before downloading you +will be given the option to view and change your selections. + +[1] stable-diffusion-1.5: + The newest Stable Diffusion version 1.5 weight file (4.27 GB) (recommended) + Download? [y] +[2] inpainting-1.5: + RunwayML SD 1.5 model optimized for inpainting (4.27 GB) (recommended) + Download? [y] +[3] stable-diffusion-1.4: + The original Stable Diffusion version 1.4 weight file (4.27 GB) + Download? [n] n +[4] waifu-diffusion-1.3: + Stable Diffusion 1.4 fine tuned on anime-styled images (4.27) + Download? [n] y +[5] ft-mse-improved-autoencoder-840000: + StabilityAI improved autoencoder fine-tuned for human faces (recommended; 335 MB) (recommended) + Download? [y] y +The following weight files will be downloaded: + [1] stable-diffusion-1.5* + [2] inpainting-1.5 + [4] waifu-diffusion-1.3 + [5] ft-mse-improved-autoencoder-840000 +*default +Ok to download? [y] +** LICENSE AGREEMENT FOR WEIGHT FILES ** + +1. To download the Stable Diffusion weight files you need to read and accept the + CreativeML Responsible AI license. If you have not already done so, please + create an account using the "Sign Up" button: + + https://huggingface.co + + You will need to verify your email address as part of the HuggingFace + registration process. + +2. After creating the account, login under your account and accept + the license terms located here: + + https://huggingface.co/CompVis/stable-diffusion-v-1-4-original + +Press when you are ready to continue: +... +``` + +When the script is complete, you will find the downloaded weights +files in `models/ldm/stable-diffusion-v1` and a matching configuration +file in `configs/models.yaml`. + +You can run the script again to add any models you didn't select the +first time. Note that as a safety measure the script will _never_ +remove a previously-installed weights file. You will have to do this +manually. + +### Installation via the CLI + +You can install a new model, including any of the community-supported +ones, via the command-line client's `!import_model` command. + +1. First download the desired model weights file and place it under `models/ldm/stable-diffusion-v1/`. + You may rename the weights file to something more memorable if you wish. Record the path of the + weights file (e.g. `models/ldm/stable-diffusion-v1/arabian-nights-1.0.ckpt`) + +2. Launch the `invoke.py` CLI with `python scripts/invoke.py`. + +3. At the `invoke>` command-line, enter the command `!import_model `. + For example: + + `invoke> !import_model models/ldm/stable-diffusion-v1/arabian-nights-1.0.ckpt` + + (Hint - the CLI supports file path autocompletion. Type a bit of the path + name and hit in order to get a choice of possible completions.) + +4. Follow the wizard's instructions to complete installation as shown in the example + here: + +``` +invoke> !import_model models/ldm/stable-diffusion-v1/arabian-nights-1.0.ckpt +>> Model import in process. Please enter the values needed to configure this model: + +Name for this model: arabian-nights +Description of this model: Arabian Nights Fine Tune v1.0 +Configuration file for this model: configs/stable-diffusion/v1-inference.yaml +Default image width: 512 +Default image height: 512 +>> New configuration: +arabian-nights: + config: configs/stable-diffusion/v1-inference.yaml + description: Arabian Nights Fine Tune v1.0 + height: 512 + weights: models/ldm/stable-diffusion-v1/arabian-nights-1.0.ckpt + width: 512 +OK to import [n]? y +>> Caching model stable-diffusion-1.4 in system RAM +>> Loading waifu-diffusion from models/ldm/stable-diffusion-v1/arabian-nights-1.0.ckpt + | LatentDiffusion: Running in eps-prediction mode + | DiffusionWrapper has 859.52 M params. + | Making attention of type 'vanilla' with 512 in_channels + | Working with z of shape (1, 4, 32, 32) = 4096 dimensions. + | Making attention of type 'vanilla' with 512 in_channels + | Using faster float16 precision + +``` + +If you've previously installed the fine-tune VAE file `vae-ft-mse-840000-ema-pruned.ckpt`, +the wizard will also ask you if you want to add this VAE to the model. + +The appropriate entry for this model will be added to `configs/models.yaml` and it will +be available to use in the CLI immediately. + +The CLI has additional commands for switching among, viewing, editing, +deleting the available models. These are described in [Command Line +Client](../features/CLI.md#model-selection-and-importation), but the two most +frequently-used are `!models` and `!switch `. The first +prints a table of models that InvokeAI knows about and their load +status. The second will load the requested model and lets you switch +back and forth quickly among loaded models. + +### Manually editing of `configs/models.yaml` + +If you are comfortable with a text editor then you may simply edit +`models.yaml` directly. + +First you need to download the desired .ckpt file and place it in +`models/ldm/stable-diffusion-v1` as descirbed in step #1 in the +previous section. Record the path to the weights file, +e.g. `models/ldm/stable-diffusion-v1/arabian-nights-1.0.ckpt` + +Then using a **text** editor (e.g. the Windows Notepad application), +open the file `configs/models.yaml`, and add a new stanza that follows +this model: + +``` +arabian-nights-1.0: + description: A great fine-tune in Arabian Nights style + weights: ./models/ldm/stable-diffusion-v1/arabian-nights-1.0.ckpt + config: ./configs/stable-diffusion/v1-inference.yaml + width: 512 + height: 512 + vae: ./models/ldm/stable-diffusion-v1/vae-ft-mse-840000-ema-pruned.ckpt + default: false +``` + +* arabian-nights-1.0 + - This is the name of the model that you will refer to from within the + CLI and the WebGUI when you need to load and use the model. + +* description + - Any description that you want to add to the model to remind you what + it is. + +* weights + - Relative path to the .ckpt weights file for this model. + +* config + - This is the confusingly-named configuration file for the model itself. + Use `./configs/stable-diffusion/v1-inference.yaml` unless the model happens + to need a custom configuration, in which case the place you downloaded it + from will tell you what to use instead. For example, the runwayML custom + inpainting model requires the file `configs/stable-diffusion/v1-inpainting-inference.yaml`. + This is already inclued in the InvokeAI distribution and is configured automatically + for you by the `preload_models.py` script. + +* vae + - If you want to add a VAE file to the model, then enter its path here. + +* width, height + - This is the width and height of the images used to train the model. + Currently they are always 512 and 512. + +Save the `models.yaml` and relaunch InvokeAI. The new model should now be +available for your use. + + diff --git a/docs/installation/INSTALL_DOCKER.md b/docs/installation/INSTALL_DOCKER.md new file mode 100644 index 0000000000..50c3d89c81 --- /dev/null +++ b/docs/installation/INSTALL_DOCKER.md @@ -0,0 +1,223 @@ +--- +title: Docker +--- + +# :fontawesome-brands-docker: Docker + +## Before you begin + +- For end users: Install Stable Diffusion locally using the instructions for + your OS. +- For developers: For container-related development tasks or for enabling easy + deployment to other environments (on-premises or cloud), follow these + instructions. For general use, install locally to leverage your machine's GPU. + +## Why containers? + +They provide a flexible, reliable way to build and deploy Stable Diffusion. +You'll also use a Docker volume to store the largest model files and image +outputs as a first step in decoupling storage and compute. Future enhancements +can do this for other assets. See [Processes](https://12factor.net/processes) +under the Twelve-Factor App methodology for details on why running applications +in such a stateless fashion is important. + +You can specify the target platform when building the image and running the +container. You'll also need to specify the Stable Diffusion requirements file +that matches the container's OS and the architecture it will run on. + +Developers on Apple silicon (M1/M2): You +[can't access your GPU cores from Docker containers](https://github.com/pytorch/pytorch/issues/81224) +and performance is reduced compared with running it directly on macOS but for +development purposes it's fine. Once you're done with development tasks on your +laptop you can build for the target platform and architecture and deploy to +another environment with NVIDIA GPUs on-premises or in the cloud. + +## Installation on a Linux container + +### Prerequisites + +#### Install [Docker](https://github.com/santisbon/guides#docker) + +On the Docker Desktop app, go to Preferences, Resources, Advanced. Increase the +CPUs and Memory to avoid this +[Issue](https://github.com/invoke-ai/InvokeAI/issues/342). You may need to +increase Swap and Disk image size too. + +#### Get a Huggingface-Token + +Go to [Hugging Face](https://huggingface.co/settings/tokens), create a token and +temporary place it somewhere like a open texteditor window (but dont save it!, +only keep it open, we need it in the next step) + +### Setup + +Set the fork you want to use and other variables. + +!!! tip + + I preffer to save my env vars + in the repository root in a `.env` (or `.envrc`) file to automatically re-apply + them when I come back. + +The build- and run- scripts contain default values for almost everything, +besides the [Hugging Face Token](https://huggingface.co/settings/tokens) you +created in the last step. + +Some Suggestions of variables you may want to change besides the Token: + +| Environment-Variable | Description | +| ------------------------------------------------------------------- | ------------------------------------------------------------------------ | +| `HUGGINGFACE_TOKEN="hg_aewirhghlawrgkjbarug2"` | This is the only required variable, without you can't get the checkpoint | +| `ARCH=aarch64` | if you are using a ARM based CPU | +| `INVOKEAI_TAG=yourname/invokeai:latest` | the Container Repository / Tag which will be used | +| `INVOKEAI_CONDA_ENV_FILE=environment-linux-aarch64.yml` | since environment.yml wouldn't work with aarch | +| `INVOKEAI_GIT="-b branchname https://github.com/username/reponame"` | if you want to use your own fork | + +#### Build the Image + +I provided a build script, which is located in `docker-build/build.sh` but still +needs to be executed from the Repository root. + +```bash +docker-build/build.sh +``` + +The build Script not only builds the container, but also creates the docker +volume if not existing yet, or if empty it will just download the models. When +it is done you can run the container via the run script + +```bash +docker-build/run.sh +``` + +When used without arguments, the container will start the website and provide +you the link to open it. But if you want to use some other parameters you can +also do so. + +!!! warning "Deprecated" + + From here on it is the rest of the previous Docker-Docs, which will still + provide usefull informations for one or the other. + +## Usage (time to have fun) + +### Startup + +If you're on a **Linux container** the `invoke` script is **automatically +started** and the output dir set to the Docker volume you created earlier. + +If you're **directly on macOS follow these startup instructions**. +With the Conda environment activated (`conda activate ldm`), run the interactive +interface that combines the functionality of the original scripts `txt2img` and +`img2img`: +Use the more accurate but VRAM-intensive full precision math because +half-precision requires autocast and won't work. +By default the images are saved in `outputs/img-samples/`. + +```Shell +python3 scripts/invoke.py --full_precision +``` + +You'll get the script's prompt. You can see available options or quit. + +```Shell +invoke> -h +invoke> q +``` + +### Text to Image + +For quick (but bad) image results test with 5 steps (default 50) and 1 sample +image. This will let you know that everything is set up correctly. +Then increase steps to 100 or more for good (but slower) results. +The prompt can be in quotes or not. + +```Shell +invoke> The hulk fighting with sheldon cooper -s5 -n1 +invoke> "woman closeup highly detailed" -s 150 +# Reuse previous seed and apply face restoration +invoke> "woman closeup highly detailed" --steps 150 --seed -1 -G 0.75 +``` + +You'll need to experiment to see if face restoration is making it better or +worse for your specific prompt. + +If you're on a container the output is set to the Docker volume. You can copy it +wherever you want. +You can download it from the Docker Desktop app, Volumes, my-vol, data. +Or you can copy it from your Mac terminal. Keep in mind `docker cp` can't expand +`*.png` so you'll need to specify the image file name. + +On your host Mac (you can use the name of any container that mounted the +volume): + +```Shell +docker cp dummy:/data/000001.928403745.png /Users//Pictures +``` + +### Image to Image + +You can also do text-guided image-to-image translation. For example, turning a +sketch into a detailed drawing. + +`strength` is a value between 0.0 and 1.0 that controls the amount of noise that +is added to the input image. Values that approach 1.0 allow for lots of +variations but will also produce images that are not semantically consistent +with the input. 0.0 preserves image exactly, 1.0 replaces it completely. + +Make sure your input image size dimensions are multiples of 64 e.g. 512x512. +Otherwise you'll get `Error: product of dimension sizes > 2**31'`. If you still +get the error +[try a different size](https://support.apple.com/guide/preview/resize-rotate-or-flip-an-image-prvw2015/mac#:~:text=image's%20file%20size-,In%20the%20Preview%20app%20on%20your%20Mac%2C%20open%20the%20file,is%20shown%20at%20the%20bottom.) +like 512x256. + +If you're on a Docker container, copy your input image into the Docker volume + +```Shell +docker cp /Users//Pictures/sketch-mountains-input.jpg dummy:/data/ +``` + +Try it out generating an image (or more). The `invoke` script needs absolute +paths to find the image so don't use `~`. + +If you're on your Mac + +```Shell +invoke> "A fantasy landscape, trending on artstation" -I /Users//Pictures/sketch-mountains-input.jpg --strength 0.75 --steps 100 -n4 +``` + +If you're on a Linux container on your Mac + +```Shell +invoke> "A fantasy landscape, trending on artstation" -I /data/sketch-mountains-input.jpg --strength 0.75 --steps 50 -n1 +``` + +### Web Interface + +You can use the `invoke` script with a graphical web interface. Start the web +server with: + +```Shell +python3 scripts/invoke.py --full_precision --web +``` + +If it's running on your Mac point your Mac web browser to + + +Press Control-C at the command line to stop the web server. + +### Notes + +Some text you can add at the end of the prompt to make it very pretty: + +```Shell +cinematic photo, highly detailed, cinematic lighting, ultra-detailed, ultrarealistic, photorealism, Octane Rendering, cyberpunk lights, Hyper Detail, 8K, HD, Unreal Engine, V-Ray, full hd, cyberpunk, abstract, 3d octane render + 4k UHD + immense detail + dramatic lighting + well lit + black, purple, blue, pink, cerulean, teal, metallic colours, + fine details, ultra photoreal, photographic, concept art, cinematic composition, rule of thirds, mysterious, eerie, photorealism, breathtaking detailed, painting art deco pattern, by hsiao, ron cheng, john james audubon, bizarre compositions, exquisite detail, extremely moody lighting, painted by greg rutkowski makoto shinkai takashi takeuchi studio ghibli, akihiko yoshida +``` + +The original scripts should work as well. + +```Shell +python3 scripts/orig_scripts/txt2img.py --help +python3 scripts/orig_scripts/txt2img.py --ddim_steps 100 --n_iter 1 --n_samples 1 --plms --prompt "new born baby kitten. Hyper Detail, Octane Rendering, Unreal Engine, V-Ray" +python3 scripts/orig_scripts/txt2img.py --ddim_steps 5 --n_iter 1 --n_samples 1 --plms --prompt "ocean" # or --klms +``` diff --git a/docs/installation/INSTALL_LINUX.md b/docs/installation/INSTALL_LINUX.md index 2a64f1eb41..0bbfd8cda0 100644 --- a/docs/installation/INSTALL_LINUX.md +++ b/docs/installation/INSTALL_LINUX.md @@ -1,89 +1,124 @@ -# **Linux Installation** +--- +title: Manual Installation, Linux +--- -1. You will need to install the following prerequisites if they are not already available. Use your operating system's preferred installer +# :fontawesome-brands-linux: Linux -- Python (version 3.8.5 recommended; higher may work) -- git +## Installation -2. Install the Python Anaconda environment manager. +1. You will need to install the following prerequisites if they are not already + available. Use your operating system's preferred installer. -``` -~$ wget https://repo.anaconda.com/archive/Anaconda3-2022.05-Linux-x86_64.sh -~$ chmod +x Anaconda3-2022.05-Linux-x86_64.sh -~$ ./Anaconda3-2022.05-Linux-x86_64.sh -``` + - Python (version 3.8.5 recommended; higher may work) + - git -After installing anaconda, you should log out of your system and log back in. If the installation -worked, your command prompt will be prefixed by the name of the current anaconda environment - `(base)`. +2. Install the Python Anaconda environment manager. -3. Copy the InvokeAI source code from GitHub: + ```bash + ~$ wget https://repo.anaconda.com/archive/Anaconda3-2022.05-Linux-x86_64.sh + ~$ chmod +x Anaconda3-2022.05-Linux-x86_64.sh + ~$ ./Anaconda3-2022.05-Linux-x86_64.sh + ``` -``` -(base) ~$ git clone https://github.com/invoke-ai/InvokeAI.git -``` + After installing anaconda, you should log out of your system and log back + in. If the installation worked, your command prompt will be prefixed by the + name of the current anaconda environment - `(base)`. -This will create InvokeAI folder where you will follow the rest of the steps. +3. Copy the InvokeAI source code from GitHub: -4. Enter the newly-created InvokeAI folder. From this step forward make sure that you are working in the InvokeAI directory! + ```bash + (base) ~$ git clone https://github.com/invoke-ai/InvokeAI.git + ``` -``` -(base) ~$ cd InvokeAI -(base) ~/InvokeAI$ -``` + This will create InvokeAI folder where you will follow the rest of the + steps. -5. Use anaconda to copy necessary python packages, create a new python environment named `ldm` and activate the environment. +4. Enter the newly-created InvokeAI folder. From this step forward make sure + that you are working in the InvokeAI directory! -``` -(base) ~/InvokeAI$ conda env create -f environment.yaml -(base) ~/InvokeAI$ conda activate ldm -(ldm) ~/InvokeAI$ -``` + ```bash + (base) ~$ cd InvokeAI + (base) ~/InvokeAI$ + ``` -After these steps, your command prompt will be prefixed by `(ldm)` as shown above. +5. Use anaconda to copy necessary python packages, create a new python + environment named `invokeai` and activate the environment. -6. Load a couple of small machine-learning models required by stable diffusion: + ```bash + (base) rm -rf src # (this is a precaution in case there is already a src directory) + (base) ~/InvokeAI$ conda env create + (base) ~/InvokeAI$ conda activate invokeai + (invokeai) ~/InvokeAI$ + ``` -``` -(ldm) ~/InvokeAI$ python3 scripts/preload_models.py -``` + After these steps, your command prompt will be prefixed by `(invokeai)` as + shown above. -Note that this step is necessary because I modified the original just-in-time model loading scheme to allow the script to work on GPU machines that are not internet connected. See [Preload Models](../features/OTHER.md#preload-models) +6. Load the big stable diffusion weights files and a couple of smaller + machine-learning models: -7. Now you need to install the weights for the stable diffusion model. + ```bash + (invokeai) ~/InvokeAI$ python3 scripts/preload_models.py + ``` -- For running with the released weights, you will first need to set up an acount with Hugging Face (https://huggingface.co). -- Use your credentials to log in, and then point your browser at https://huggingface.co/CompVis/stable-diffusion-v-1-4-original. -- You may be asked to sign a license agreement at this point. -- Click on "Files and versions" near the top of the page, and then click on the file named "sd-v1-4.ckpt". You'll be taken to a page that prompts you to click the "download" link. Save the file somewhere safe on your local machine. + !!! note -Now run the following commands from within the stable-diffusion directory. This will create a symbolic link from the stable-diffusion model.ckpt file, to the true location of the sd-v1-4.ckpt file. + This script will lead you through the process of creating an account on Hugging Face, + accepting the terms and conditions of the Stable Diffusion model license, + and obtaining an access token for downloading. It will then download and + install the weights files for you. -``` -(ldm) ~/InvokeAI$ mkdir -p models/ldm/stable-diffusion-v1 -(ldm) ~/InvokeAI$ ln -sf /path/to/sd-v1-4.ckpt models/ldm/stable-diffusion-v1/model.ckpt -``` + Please look [here](INSTALLING_MODELS.md) for a manual process for doing + the same thing. -8. Start generating images! +7. Start generating images! -``` -# for the pre-release weights use the -l or --liaon400m switch -(ldm) ~/InvokeAI$ python3 scripts/dream.py -l + !!! todo "Run InvokeAI!" -# for the post-release weights do not use the switch -(ldm) ~/InvokeAI$ python3 scripts/dream.py + !!! warning "IMPORTANT" -# for additional configuration switches and arguments, use -h or --help -(ldm) ~/InvokeAI$ python3 scripts/dream.py -h -``` + Make sure that the conda environment is activated, which should create + `(invokeai)` in front of your prompt! -9. Subsequently, to relaunch the script, be sure to run "conda activate ldm" (step 5, second command), enter the `InvokeAI` directory, and then launch the dream script (step 8). If you forget to activate the ldm environment, the script will fail with multiple `ModuleNotFound` errors. + === "CLI" -### Updating to newer versions of the script + ```bash + python scripts/invoke.py + ``` -This distribution is changing rapidly. If you used the `git clone` method (step 5) to download the InvokeAI directory, then to update to the latest and greatest version, launch the Anaconda window, enter `InvokeAI` and type: + === "local Webserver" -``` -(ldm) ~/InvokeAI$ git pull + ```bash + python scripts/invoke.py --web + ``` + + === "Public Webserver" + + ```bash + python scripts/invoke.py --web --host 0.0.0.0 + ``` + + To use an alternative model you may invoke the `!switch` command in + the CLI, or pass `--model ` during `invoke.py` launch for + either the CLI or the Web UI. See [Command Line + Client](../features/CLI.md#model-selection-and-importation). The + model names are defined in `configs/models.yaml`. + +8. Subsequently, to relaunch the script, be sure to run "conda activate + invokeai" (step 5, second command), enter the `InvokeAI` directory, and then + launch the invoke script (step 8). If you forget to activate the 'invokeai' + environment, the script will fail with multiple `ModuleNotFound` errors. + +## Updating to newer versions of the script + +This distribution is changing rapidly. If you used the `git clone` method +(step 5) to download the InvokeAI directory, then to update to the latest and +greatest version, launch the Anaconda window, enter `InvokeAI` and type: + +```bash +(invokeai) ~/InvokeAI$ git pull +(invokeai) ~/InvokeAI$ rm -rf src # prevents conda freezing errors +(invokeai) ~/InvokeAI$ conda env update -f environment.yml ``` This will bring your local copy into sync with the remote one. diff --git a/docs/installation/INSTALL_MAC.md b/docs/installation/INSTALL_MAC.md index 43fa2bdc88..af39cd0de1 100644 --- a/docs/installation/INSTALL_MAC.md +++ b/docs/installation/INSTALL_MAC.md @@ -1,222 +1,322 @@ -# **macOS Instructions** +--- +title: Manual Installation, macOS +--- -Invoke AI runs quite well on M1 Macs and we have a number of M1 users in the community. +# :fontawesome-brands-apple: macOS -While the repo does run on Intel Macs, we only have a couple reports. If you have an Intel Mac and run into issues, please create an issue on Github and we will do our best to help. +Invoke AI runs quite well on M1 Macs and we have a number of M1 users in the +community. + +While the repo does run on Intel Macs, we only have a couple reports. If you +have an Intel Mac and run into issues, please create an issue on Github and we +will do our best to help. ## Requirements - macOS 12.3 Monterey or later -- About 10GB of storage (and 10GB of data if your internet connection has data caps) +- About 10GB of storage (and 10GB of data if your internet connection has data + caps) - Any M1 Macs or an Intel Macs with 4GB+ of VRAM (ideally more) ## Installation -First you need to download a large checkpoint file. +!!! todo "Homebrew" -1. Sign up at https://huggingface.co -2. Go to the [Stable diffusion diffusion model page](https://huggingface.co/CompVis/stable-diffusion-v-1-4-original) -3. Accept the terms and click Access Repository -4. Download [sd-v1-4.ckpt (4.27 GB)](https://huggingface.co/CompVis/stable-diffusion-v-1-4-original/blob/main/sd-v1-4.ckpt) and note where you have saved it (probably the Downloads folder). You may want to move it somewhere else for longer term storage - SD needs this file to run. + First you will install the "brew" package manager. Skip this if brew is already installed. -While that is downloading, open Terminal and run the following commands one at a time, reading the comments and taking care to run the appropriate command for your Mac's architecture (Intel or M1). + ```bash title="install brew (and Xcode command line tools)" + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + ``` -Do not just copy and paste the whole thing into your terminal! +!!! todo "Conda Installation" -```bash -# Install brew (and Xcode command line tools): -/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + Now there are two different ways to set up the Python (miniconda) environment: -# Now there are two options to get the Python (miniconda) environment up and running: -# 1. Alongside pyenv -# 2. Standalone -# -# If you don't know what we are talking about, choose 2. -# -# If you are familiar with python environments, you'll know there are other options -# for setting up the environment - you are on your own if you go one of those routes. + 1. Standalone + 2. with pyenv -##### BEGIN TWO DIFFERENT OPTIONS ##### + If you don't know what we are talking about, choose Standalone. If you are familiar with python environments, choose "with pyenv" -### BEGIN OPTION 1: Installing alongside pyenv ### -brew install pyenv-virtualenv # you might have this from before, no problem -pyenv install anaconda3-2022.05 -pyenv virtualenv anaconda3-2022.05 -eval "$(pyenv init -)" -pyenv activate anaconda3-2022.05 -### END OPTION 1 ### + === "Standalone" + ```bash title="Install cmake, protobuf, and rust" + brew install cmake protobuf rust + ``` -### BEGIN OPTION 2: Installing standalone ### -# Install cmake, protobuf, and rust: -brew install cmake protobuf rust + ```bash title="Clone the InvokeAI repository" + # Clone the Invoke AI repo + git clone https://github.com/invoke-ai/InvokeAI.git + cd InvokeAI + ``` -# BEGIN ARCHITECTURE-DEPENDENT STEP # -# For M1: install miniconda (M1 arm64 version): -curl https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.sh -o Miniconda3-latest-MacOSX-arm64.sh -/bin/bash Miniconda3-latest-MacOSX-arm64.sh + Choose the appropriate architecture for your system and install miniconda: -# For Intel: install miniconda (Intel x86-64 version): -curl https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-x86_64.sh -o Miniconda3-latest-MacOSX-x86_64.sh -/bin/bash Miniconda3-latest-MacOSX-x86_64.sh -# END ARCHITECTURE-DEPENDENT STEP # + === "M1 arm64" -### END OPTION 2 ### + ```bash title="Install miniconda for M1 arm64" + curl https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.sh \ + -o Miniconda3-latest-MacOSX-arm64.sh + /bin/bash Miniconda3-latest-MacOSX-arm64.sh + ``` -##### END TWO DIFFERENT OPTIONS ##### + === "Intel x86_64" -# Clone the Invoke AI repo -git clone https://github.com/invoke-ai/InvokeAI.git -cd InvokeAI + ```bash title="Install miniconda for Intel" + curl https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-x86_64.sh \ + -o Miniconda3-latest-MacOSX-x86_64.sh + /bin/bash Miniconda3-latest-MacOSX-x86_64.sh + ``` -### WAIT FOR THE CHECKPOINT FILE TO DOWNLOAD, THEN PROCEED ### + === "with pyenv" -# We will leave the big checkpoint wherever you stashed it for long-term storage, -# and make a link to it from the repo's folder. This allows you to use it for -# other repos, and if you need to delete Invoke AI, you won't have to download it again. + ```bash + brew install pyenv-virtualenv + pyenv install anaconda3-2022.05 + pyenv virtualenv anaconda3-2022.05 + eval "$(pyenv init -)" + pyenv activate anaconda3-2022.05 + ``` -# Make the directory in the repo for the symlink -mkdir -p models/ldm/stable-diffusion-v1/ +!!! todo "Clone the Invoke AI repo" -# This is the folder where you put the checkpoint file `sd-v1-4.ckpt` -PATH_TO_CKPT="$HOME/Downloads" + ```bash + git clone https://github.com/invoke-ai/InvokeAI.git + cd InvokeAI + ``` -# Create a link to the checkpoint -ln -s "$PATH_TO_CKPT/sd-v1-4.ckpt" models/ldm/stable-diffusion-v1/model.ckpt +!!! todo "Create the environment & install packages" -# BEGIN ARCHITECTURE-DEPENDENT STEP # -# For M1: Create the environment & install packages -PIP_EXISTS_ACTION=w CONDA_SUBDIR=osx-arm64 conda env create -f environment-mac.yaml + === "M1 Mac" -# For Intel: Create the environment & install packages -PIP_EXISTS_ACTION=w CONDA_SUBDIR=osx-64 conda env create -f environment-mac.yaml -# END ARCHITECTURE-DEPENDENT STEP # + ```bash + PIP_EXISTS_ACTION=w CONDA_SUBDIR=osx-arm64 conda env create -f environment-mac.yml + ``` -# Activate the environment (you need to do this every time you want to run SD) -conda activate ldm + === "Intel x86_64 Mac" -# This will download some bits and pieces and make take a while -python scripts/preload_models.py + ```bash + PIP_EXISTS_ACTION=w CONDA_SUBDIR=osx-64 conda env create -f environment-mac.yml + ``` -# Run SD! -python scripts/dream.py -``` + ```bash + # Activate the environment (you need to do this every time you want to run SD) + conda activate invokeai + ``` -The original scripts should work as well. + !!! info -``` -python scripts/orig_scripts/txt2img.py --prompt "a photograph of an astronaut riding a horse" --plms -``` + `export PIP_EXISTS_ACTION=w` is a precaution to fix `conda env + create -f environment-mac.yml` never finishing in some situations. So + it isn't required but won't hurt. -Note, `export PIP_EXISTS_ACTION=w` is a precaution to fix `conda env -create -f environment-mac.yaml` never finishing in some situations. So -it isn't required but wont hurt. +!!! todo "Download the model weight files" -After you follow all the instructions and run dream.py you might get several errors. Here's the errors I've seen and found solutions for. + The `preload_models.py` script downloads and installs the model weight + files for you. It will lead you through the process of getting a Hugging Face + account, accepting the Stable Diffusion model weight license agreement, and + creating a download token: + + ```bash + # This will take some time, depending on the speed of your internet connection + # and will consume about 10GB of space + python scripts/preload_models.py + ``` + +!!! todo "Run InvokeAI!" + + !!! warning "IMPORTANT" + + Make sure that the conda environment is activated, which should create + `(invokeai)` in front of your prompt! + + === "CLI" + + ```bash + python scripts/invoke.py + ``` + + === "local Webserver" + + ```bash + python scripts/invoke.py --web + ``` + + === "Public Webserver" + + ```bash + python scripts/invoke.py --web --host 0.0.0.0 + ``` + + To use an alternative model you may invoke the `!switch` command in + the CLI, or pass `--model ` during `invoke.py` launch for + either the CLI or the Web UI. See [Command Line + Client](../features/CLI.md#model-selection-and-importation). The + model names are defined in `configs/models.yaml`. + +--- + +## Common problems + +After you followed all the instructions and try to run invoke.py, you might get +several errors. Here's the errors I've seen and found solutions for. ### Is it slow? -Be sure to specify 1 sample and 1 iteration. +```bash title="Be sure to specify 1 sample and 1 iteration." +python ./scripts/orig_scripts/txt2img.py \ + --prompt "ocean" \ + --ddim_steps 5 \ + --n_samples 1 \ + --n_iter 1 +``` - python ./scripts/orig_scripts/txt2img.py --prompt "ocean" --ddim_steps 5 --n_samples 1 --n_iter 1 +--- ### Doesn't work anymore? -PyTorch nightly includes support for MPS. Because of this, this setup is inherently unstable. One morning I woke up and it no longer worked no matter what I did until I switched to miniforge. However, I have another Mac that works just fine with Anaconda. If you can't get it to work, please search a little first because many of the errors will get posted and solved. If you can't find a solution please [create an issue](https://github.com/invoke-ai/InvokeAI/issues). +PyTorch nightly includes support for MPS. Because of this, this setup is +inherently unstable. One morning I woke up and it no longer worked no matter +what I did until I switched to miniforge. However, I have another Mac that works +just fine with Anaconda. If you can't get it to work, please search a little +first because many of the errors will get posted and solved. If you can't find a +solution please [create an issue](https://github.com/invoke-ai/InvokeAI/issues). One debugging step is to update to the latest version of PyTorch nightly. - conda install pytorch torchvision torchaudio -c pytorch-nightly +```bash +conda install \ + pytorch \ + torchvision \ + -c pytorch-nightly \ + -n invokeai +``` -If `conda env create -f environment-mac.yaml` takes forever run this. +If it takes forever to run `conda env create -f environment-mac.yml`, try this: - git clean -f +```bash +git clean -f +conda clean \ + --yes \ + --all +``` -And run this. +Or you could try to completley reset Anaconda: - conda clean --yes --all +```bash +conda update \ + --force-reinstall \ + -y \ + -n base \ + -c defaults conda +``` -Or you could reset Anaconda. +--- - conda update --force-reinstall -y -n base -c defaults conda +### "No module named cv2", torch, 'invokeai', 'transformers', 'taming', etc -### "No module named cv2", torch, 'ldm', 'transformers', 'taming', etc. +There are several causes of these errors: -There are several causes of these errors. +1. Did you remember to `conda activate invokeai`? If your terminal prompt begins + with "(invokeai)" then you activated it. If it begins with "(base)" or + something else you haven't. -First, did you remember to `conda activate ldm`? If your terminal prompt -begins with "(ldm)" then you activated it. If it begins with "(base)" -or something else you haven't. +2. You might've run `./scripts/preload_models.py` or `./scripts/invoke.py` + instead of `python ./scripts/preload_models.py` or + `python ./scripts/invoke.py`. The cause of this error is long so it's below. -Second, you might've run `./scripts/preload_models.py` or `./scripts/dream.py` -instead of `python ./scripts/preload_models.py` or `python ./scripts/dream.py`. -The cause of this error is long so it's below. + -Third, if it says you're missing taming you need to rebuild your virtual -environment. +3. if it says you're missing taming you need to rebuild your virtual + environment. - conda env remove -n ldm - conda env create -f environment-mac.yaml + ```bash + conda deactivate + conda env remove -n invokeai + conda env create -f environment-mac.yml + ``` -Fourth, If you have activated the ldm virtual environment and tried rebuilding it, maybe the problem could be that I have something installed that you don't and you'll just need to manually install it. Make sure you activate the virtual environment so it installs there instead of -globally. +4. If you have activated the invokeai virtual environment and tried rebuilding + it, maybe the problem could be that I have something installed that you don't + and you'll just need to manually install it. Make sure you activate the + virtual environment so it installs there instead of globally. - conda activate ldm - pip install *name* + ```bash + conda activate invokeai + pip install + ``` You might also need to install Rust (I mention this again below). +--- + ### How many snakes are living in your computer? You might have multiple Python installations on your system, in which case it's -important to be explicit and consistent about which one to use for a given project. -This is because virtual environments are coupled to the Python that created it (and all -the associated 'system-level' modules). +important to be explicit and consistent about which one to use for a given +project. This is because virtual environments are coupled to the Python that +created it (and all the associated 'system-level' modules). -When you run `python` or `python3`, your shell searches the colon-delimited locations -in the `PATH` environment variable (`echo $PATH` to see that list) in that order - first match wins. -You can ask for the location of the first `python3` found in your `PATH` with the `which` command like this: +When you run `python` or `python3`, your shell searches the colon-delimited +locations in the `PATH` environment variable (`echo $PATH` to see that list) in +that order - first match wins. You can ask for the location of the first +`python3` found in your `PATH` with the `which` command like this: - % which python3 - /usr/bin/python3 +```bash +% which python3 +/usr/bin/python3 +``` -Anything in `/usr/bin` is [part of the OS](https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html#//apple_ref/doc/uid/TP40010672-CH2-SW6). However, `/usr/bin/python3` is not actually python3, but -rather a stub that offers to install Xcode (which includes python 3). If you have Xcode installed already, -`/usr/bin/python3` will execute `/Library/Developer/CommandLineTools/usr/bin/python3` or +Anything in `/usr/bin` is +[part of the OS](https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html#//apple_ref/doc/uid/TP40010672-CH2-SW6). +However, `/usr/bin/python3` is not actually python3, but rather a stub that +offers to install Xcode (which includes python 3). If you have Xcode installed +already, `/usr/bin/python3` will execute +`/Library/Developer/CommandLineTools/usr/bin/python3` or `/Applications/Xcode.app/Contents/Developer/usr/bin/python3` (depending on which Xcode you've selected with `xcode-select`). -Note that `/usr/bin/python` is an entirely different python - specifically, python 2. Note: starting in -macOS 12.3, `/usr/bin/python` no longer exists. +Note that `/usr/bin/python` is an entirely different python - specifically, +python 2. Note: starting in macOS 12.3, `/usr/bin/python` no longer exists. - % which python3 - /opt/homebrew/bin/python3 +```bash +% which python3 +/opt/homebrew/bin/python3 +``` If you installed python3 with Homebrew and you've modified your path to search for Homebrew binaries before system ones, you'll see the above path. - % which python - /opt/anaconda3/bin/python +```bash +% which python +/opt/anaconda3/bin/python +``` If you have Anaconda installed, you will see the above path. There is a -`/opt/anaconda3/bin/python3` also. We expect that `/opt/anaconda3/bin/python` -and `/opt/anaconda3/bin/python3` should actually be the *same python*, which you can -verify by comparing the output of `python3 -V` and `python -V`. +`/opt/anaconda3/bin/python3` also. - (ldm) % which python - /Users/name/miniforge3/envs/ldm/bin/python +We expect that `/opt/anaconda3/bin/python` and `/opt/anaconda3/bin/python3` +should actually be the _same python_, which you can verify by comparing the +output of `python3 -V` and `python -V`. -The above is what you'll see if you have miniforge and you've correctly activated -the ldm environment, and you used option 2 in the setup instructions above ("no pyenv"). +```bash +(invokeai) % which python +/Users/name/miniforge3/envs/invokeai/bin/python +``` - (anaconda3-2022.05) % which python - /Users/name/.pyenv/shims/python - -... and the above is what you'll see if you used option 1 ("Alongside pyenv"). +The above is what you'll see if you have miniforge and correctly activated the +invokeai environment, while usingd the standalone setup instructions above. -It's all a mess and you should know [how to modify the path environment variable](https://support.apple.com/guide/terminal/use-environment-variables-apd382cc5fa-4f58-4449-b20a-41c53c006f8f/mac) -if you want to fix it. Here's a brief hint of all the ways you can modify it -(don't really have the time to explain it all here). +If you otherwise installed via pyenv, you will get this result: + +```bash +(anaconda3-2022.05) % which python +/Users/name/.pyenv/shims/python +``` + +It's all a mess and you should know +[how to modify the path environment variable](https://support.apple.com/guide/terminal/use-environment-variables-apd382cc5fa-4f58-4449-b20a-41c53c006f8f/mac) +if you want to fix it. Here's a brief hint of the most common ways you can +modify it (don't really have the time to explain it all here). - ~/.zshrc - ~/.bash_profile @@ -224,53 +324,84 @@ if you want to fix it. Here's a brief hint of all the ways you can modify it - /etc/paths.d - /etc/path -Which one you use will depend on what you have installed except putting a file -in /etc/paths.d is what I prefer to do. +Which one you use will depend on what you have installed, except putting a file +in /etc/paths.d - which also is the way I prefer to do. -Finally, to answer the question posed by this section's title, it may help to list -all of the `python` / `python3` things found in `$PATH` instead of just the one that -will be executed by default. To do that, add the `-a` switch to `which`: +Finally, to answer the question posed by this section's title, it may help to +list all of the `python` / `python3` things found in `$PATH` instead of just the +first hit. To do so, add the `-a` switch to `which`: - % which -a python3 - ... +```bash +% which -a python3 +... +``` + +This will show a list of all binaries which are actually available in your PATH. + +--- ### Debugging? -Tired of waiting for your renders to finish before you can see if it -works? Reduce the steps! The image quality will be horrible but at least you'll -get quick feedback. +Tired of waiting for your renders to finish before you can see if it works? +Reduce the steps! The image quality will be horrible but at least you'll get +quick feedback. - python ./scripts/txt2img.py --prompt "ocean" --ddim_steps 5 --n_samples 1 --n_iter 1 +```bash +python ./scripts/txt2img.py \ + --prompt "ocean" \ + --ddim_steps 5 \ + --n_samples 1 \ + --n_iter 1 +``` -### OSError: Can't load tokenizer for 'openai/clip-vit-large-patch14'... +--- - python scripts/preload_models.py +### OSError: Can't load tokenizer for 'openai/clip-vit-large-patch14' + +```bash +python scripts/preload_models.py +``` + +--- ### "The operator [name] is not current implemented for the MPS device." (sic) -Example error. +!!! example "example error" -``` -... -NotImplementedError: The operator 'aten::_index_put_impl_' is not current implemented for the MPS device. If you want this op to be added in priority during the prototype phase of this feature, please comment on [https://github.com/pytorch/pytorch/issues/77764](https://github.com/pytorch/pytorch/issues/77764). As a temporary fix, you can set the environment variable `PYTORCH_ENABLE_MPS_FALLBACK=1` to use the CPU as a fallback for this op. WARNING: this will be slower than running natively on MPS. -``` + ```bash + ... NotImplementedError: The operator 'aten::_index_put_impl_' is not current + implemented for the MPS device. If you want this op to be added in priority + during the prototype phase of this feature, please comment on + https://github.com/pytorch/pytorch/issues/77764. + As a temporary fix, you can set the environment variable + `PYTORCH_ENABLE_MPS_FALLBACK=1` to use the CPU as a fallback for this op. + WARNING: this will be slower than running natively on MPS. + ``` -The InvokeAI version includes this fix in [environment-mac.yaml](https://github.com/invoke-ai/InvokeAI/blob/main/environment-mac.yaml). +The InvokeAI version includes this fix in +[environment-mac.yml](https://github.com/invoke-ai/InvokeAI/blob/main/environment-mac.yml). ### "Could not build wheels for tokenizers" -I have not seen this error because I had Rust installed on my computer before I started playing with Stable Diffusion. The fix is to install Rust. +I have not seen this error because I had Rust installed on my computer before I +started playing with Stable Diffusion. The fix is to install Rust. - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +```bash +curl \ + --proto '=https' \ + --tlsv1.2 \ + -sSf https://sh.rustup.rs | sh +``` + +--- ### How come `--seed` doesn't work? -First this: +!!! Information -> Completely reproducible results are not guaranteed across PyTorch -> releases, individual commits, or different platforms. Furthermore, -> results may not be reproducible between CPU and GPU executions, even -> when using identical seeds. + Completely reproducible results are not guaranteed across PyTorch releases, + individual commits, or different platforms. Furthermore, results may not be + reproducible between CPU and GPU executions, even when using identical seeds. [PyTorch docs](https://pytorch.org/docs/stable/notes/randomness.html) @@ -279,55 +410,65 @@ still working on it. ### libiomp5.dylib error? - OMP: Error #15: Initializing libiomp5.dylib, but found libomp.dylib already initialized. +```bash +OMP: Error #15: Initializing libiomp5.dylib, but found libomp.dylib already initialized. +``` -You are likely using an Intel package by mistake. Be sure to run conda with -the environment variable `CONDA_SUBDIR=osx-arm64`, like so: +You are likely using an Intel package by mistake. Be sure to run conda with the +environment variable `CONDA_SUBDIR=osx-arm64`, like so: `CONDA_SUBDIR=osx-arm64 conda install ...` -This error happens with Anaconda on Macs when the Intel-only `mkl` is pulled in by -a dependency. [nomkl](https://stackoverflow.com/questions/66224879/what-is-the-nomkl-python-package-used-for) +This error happens with Anaconda on Macs when the Intel-only `mkl` is pulled in +by a dependency. +[nomkl](https://stackoverflow.com/questions/66224879/what-is-the-nomkl-python-package-used-for) is a metapackage designed to prevent this, by making it impossible to install `mkl`, but if your environment is already broken it may not work. Do _not_ use `os.environ['KMP_DUPLICATE_LIB_OK']='True'` or equivalents as this masks the underlying issue of using Intel packages. -### Not enough memory. +--- -This seems to be a common problem and is probably the underlying -problem for a lot of symptoms (listed below). The fix is to lower your -image size or to add `model.half()` right after the model is loaded. I -should probably test it out. I've read that the reason this fixes -problems is because it converts the model from 32-bit to 16-bit and -that leaves more RAM for other things. I have no idea how that would -affect the quality of the images though. +### Not enough memory + +This seems to be a common problem and is probably the underlying problem for a +lot of symptoms (listed below). The fix is to lower your image size or to add +`model.half()` right after the model is loaded. I should probably test it out. +I've read that the reason this fixes problems is because it converts the model +from 32-bit to 16-bit and that leaves more RAM for other things. I have no idea +how that would affect the quality of the images though. See [this issue](https://github.com/CompVis/stable-diffusion/issues/71). +--- + ### "Error: product of dimension sizes > 2\*\*31'" -This error happens with img2img, which I haven't played with too much -yet. But I know it's because your image is too big or the resolution -isn't a multiple of 32x32. Because the stable-diffusion model was -trained on images that were 512 x 512, it's always best to use that -output size (which is the default). However, if you're using that size -and you get the above error, try 256 x 256 or 512 x 256 or something -as the source image. +This error happens with img2img, which I haven't played with too much yet. But I +know it's because your image is too big or the resolution isn't a multiple of +32x32. Because the stable-diffusion model was trained on images that were 512 x +512, it's always best to use that output size (which is the default). However, +if you're using that size and you get the above error, try 256 x 256 or 512 x +256 or something as the source image. -BTW, 2\*\*31-1 = [2,147,483,647](https://en.wikipedia.org/wiki/2,147,483,647#In_computing), which is also 32-bit signed [LONG_MAX](https://en.wikipedia.org/wiki/C_data_types) in C. +BTW, 2\*\*31-1 = +[2,147,483,647](https://en.wikipedia.org/wiki/2,147,483,647#In_computing), which +is also 32-bit signed [LONG_MAX](https://en.wikipedia.org/wiki/C_data_types) in +C. + +--- ### I just got Rickrolled! Do I have a virus? You don't have a virus. It's part of the project. Here's -[Rick](https://github.com/invoke-ai/InvokeAI/blob/main/assets/rick.jpeg) -and here's [the -code](https://github.com/invoke-ai/InvokeAI/blob/69ae4b35e0a0f6ee1af8bb9a5d0016ccb27e36dc/scripts/txt2img.py#L79) -that swaps him in. It's a NSFW filter, which IMO, doesn't work very -good (and we call this "computer vision", sheesh). +[Rick](https://github.com/invoke-ai/InvokeAI/blob/main/assets/rick.jpeg) and +here's +[the code](https://github.com/invoke-ai/InvokeAI/blob/69ae4b35e0a0f6ee1af8bb9a5d0016ccb27e36dc/scripts/txt2img.py#L79) +that swaps him in. It's a NSFW filter, which IMO, doesn't work very good (and we +call this "computer vision", sheesh). -Actually, this could be happening because there's not enough RAM. You could try the `model.half()` suggestion or specify smaller output images. +--- ### My images come out black @@ -335,31 +476,30 @@ We might have this fixed, we are still testing. There's a [similar issue](https://github.com/CompVis/stable-diffusion/issues/69) on CUDA GPU's where the images come out green. Maybe it's the same issue? -Someone in that issue says to use "--precision full", but this fork -actually disables that flag. I don't know why, someone else provided -that code and I don't know what it does. Maybe the `model.half()` -suggestion above would fix this issue too. I should probably test it. +Someone in that issue says to use "--precision full", but this fork actually +disables that flag. I don't know why, someone else provided that code and I +don't know what it does. Maybe the `model.half()` suggestion above would fix +this issue too. I should probably test it. ### "view size is not compatible with input tensor's size and stride" -``` - File "/opt/anaconda3/envs/ldm/lib/python3.10/site-packages/torch/nn/functional.py", line 2511, in layer_norm - return torch.layer_norm(input, normalized_shape, weight, bias, eps, torch.backends.cudnn.enabled) +```bash +File "/opt/anaconda3/envs/invokeai/lib/python3.10/site-packages/torch/nn/functional.py", line 2511, in layer_norm +return torch.layer_norm(input, normalized_shape, weight, bias, eps, torch.backends.cudnn.enabled) RuntimeError: view size is not compatible with input tensor's size and stride (at least one dimension spans across two contiguous subspaces). Use .reshape(...) instead. ``` -Update to the latest version of invoke-ai/InvokeAI. We were -patching pytorch but we found a file in stable-diffusion that we could -change instead. This is a 32-bit vs 16-bit problem. +Update to the latest version of invoke-ai/InvokeAI. We were patching pytorch but +we found a file in stable-diffusion that we could change instead. This is a +32-bit vs 16-bit problem. ### The processor must support the Intel bla bla bla What? Intel? On an Apple Silicon? - Intel MKL FATAL ERROR: This system does not meet the minimum requirements for use of the Intel(R) Math Kernel Library. - The processor must support the Intel(R) Supplemental Streaming SIMD Extensions 3 (Intel(R) SSSE3) instructions. - The processor must support the Intel(R) Streaming SIMD Extensions 4.2 (Intel(R) SSE4.2) instructions. - The processor must support the Intel(R) Advanced Vector Extensions (Intel(R) AVX) instructions. +```bash +Intel MKL FATAL ERROR: This system does not meet the minimum requirements for use of the Intel(R) Math Kernel Library. The processor must support the Intel(R) Supplemental Streaming SIMD Extensions 3 (Intel(R) SSSE3) instructions. The processor must support the Intel(R) Streaming SIMD Extensions 4.2 (Intel(R) SSE4.2) instructions. The processor must support the Intel(R) Advanced Vector Extensions (Intel(R) AVX) instructions. +``` This is due to the Intel `mkl` package getting picked up when you try to install something that depends on it-- Rosetta can translate some Intel instructions but @@ -367,19 +507,19 @@ not the specialized ones here. To avoid this, make sure to use the environment variable `CONDA_SUBDIR=osx-arm64`, which restricts the Conda environment to only use ARM packages, and use `nomkl` as described above. +--- + ### input types 'tensor<2x1280xf32>' and 'tensor<\*xf16>' are not broadcast compatible May appear when just starting to generate, e.g.: -``` -dream> clouds +```bash +invoke> clouds Generating: 0%| | 0/1 [00:00' and 'tensor<*xf16>' are not broadcast compatible LLVM ERROR: Failed to infer result type(s). Abort trap: 6 -/Users/[...]/opt/anaconda3/envs/ldm/lib/python3.9/multiprocessing/resource_tracker.py:216: UserWarning: resource_tracker: There appear to be 1 leaked semaphore objects to clean up at shutdown +/Users/[...]/opt/anaconda3/envs/invokeai/lib/python3.9/multiprocessing/resource_tracker.py:216: UserWarning: resource_tracker: There appear to be 1 leaked semaphore objects to clean up at shutdown warnings.warn('resource_tracker: There appear to be %d ' ``` - -Macs do not support autocast/mixed-precision. Supply `--full_precision` to use float32 everywhere. diff --git a/docs/installation/INSTALL_WINDOWS.md b/docs/installation/INSTALL_WINDOWS.md index a6a733e8b5..bab02cd261 100644 --- a/docs/installation/INSTALL_WINDOWS.md +++ b/docs/installation/INSTALL_WINDOWS.md @@ -1,112 +1,144 @@ -# **Windows Installation** +--- +title: Manual Installation, Windows +--- + +# :fontawesome-brands-windows: Windows ## **Notebook install (semi-automated)** -We have a [Jupyter -notebook](https://github.com/lstein/stable-diffusion/blob/main/notebooks/Stable-Diffusion-local-Windows.ipynb) -with cell-by-cell installation steps. It will download the code in -this repo as one of the steps, so instead of cloning this repo, simply -download the notebook from the link above and load it up in VSCode -(with the appropriate extensions installed)/Jupyter/JupyterLab and -start running the cells one-by-one. +We have a +[Jupyter notebook](https://github.com/invoke-ai/InvokeAI/blob/main/notebooks/Stable-Diffusion-local-Windows.ipynb) +with cell-by-cell installation steps. It will download the code in this repo as +one of the steps, so instead of cloning this repo, simply download the notebook +from the link above and load it up in VSCode (with the appropriate extensions +installed)/Jupyter/JupyterLab and start running the cells one-by-one. Note that you will need NVIDIA drivers, Python 3.10, and Git installed -beforehand - simplified [step-by-step -instructions](https://github.com/lstein/stable-diffusion/wiki/Easy-peasy-Windows-install) +beforehand - simplified +[step-by-step instructions](https://github.com/invoke-ai/InvokeAI/wiki/Easy-peasy-Windows-install) are available in the wiki (you'll only need steps 1, 2, & 3 ). ## **Manual Install** ### **pip** -See [Easy-peasy Windows install](https://github.com/lstein/stable-diffusion/wiki/Easy-peasy-Windows-install) +See +[Easy-peasy Windows install](https://github.com/invoke-ai/InvokeAI/wiki/Easy-peasy-Windows-install) in the wiki +--- + ### **Conda** -1. Install Anaconda3 (miniconda3 version) from here: https://docs.anaconda.com/anaconda/install/windows/ +1. Install Anaconda3 (miniconda3 version) from [here](https://docs.anaconda.com/anaconda/install/windows/) -2. Install Git from here: https://git-scm.com/download/win +2. Install Git from [here](https://git-scm.com/download/win) -3. Launch Anaconda from the Windows Start menu. This will bring up a command window. Type all the remaining commands in this window. +3. Launch Anaconda from the Windows Start menu. This will bring up a command + window. Type all the remaining commands in this window. 4. Run the command: -``` -git clone https://github.com/invoke-ai/InvokeAI.git -``` + ```batch + git clone https://github.com/invoke-ai/InvokeAI.git + ``` -This will create stable-diffusion folder where you will follow the rest of the steps. + This will create stable-diffusion folder where you will follow the rest of + the steps. 5. Enter the newly-created InvokeAI folder. From this step forward make sure that you are working in the InvokeAI directory! -``` -cd InvokeAI -``` + ```batch + cd InvokeAI + ``` 6. Run the following two commands: -``` -conda env create -f environment.yaml (step 6a) -conda activate ldm (step 6b) -``` + ```batch title="step 6a" + conda env create + ``` -This will install all python requirements and activate the "ldm" -environment which sets PATH and other environment variables properly. + ```batch title="step 6b" + conda activate invokeai + ``` -7. Run the command: + This will install all python requirements and activate the "invokeai" environment + which sets PATH and other environment variables properly. -``` -python scripts\preload_models.py -``` + Note that the long form of the first command is `conda env create -f environment.yml`. If the + environment file isn't specified, conda will default to `environment.yml`. You will need + to provide the `-f` option if you wish to load a different environment file at any point. -This installs several machine learning models that stable diffusion requires. +7. Load the big stable diffusion weights files and a couple of smaller machine-learning models: -Note: This step is required. This was done because some users may might be blocked by firewalls or have limited internet connectivity for the models to be downloaded just-in-time. + ```bash + python scripts/preload_models.py + ``` -8. Now you need to install the weights for the big stable diffusion model. + !!! note -- For running with the released weights, you will first need to set up an acount with Hugging Face (https://huggingface.co). -- Use your credentials to log in, and then point your browser at https://huggingface.co/CompVis/stable-diffusion-v-1-4-original. -- You may be asked to sign a license agreement at this point. -- Click on "Files and versions" near the top of the page, and then click on the file named `sd-v1-4.ckpt`. You'll be taken to a page that - prompts you to click the "download" link. Now save the file somewhere safe on your local machine. -- The weight file is >4 GB in size, so - downloading may take a while. + This script will lead you through the process of creating an account on Hugging Face, + accepting the terms and conditions of the Stable Diffusion model license, and + obtaining an access token for downloading. It will then download and install the + weights files for you. -Now run the following commands from **within the InvokeAI directory** to copy the weights file to the right place: + Please look [here](INSTALLING_MODELS.md) for a manual process for doing the + same thing. -``` -mkdir -p models\ldm\stable-diffusion-v1 -copy C:\path\to\sd-v1-4.ckpt models\ldm\stable-diffusion-v1\model.ckpt -``` +8. Start generating images! -Please replace `C:\path\to\sd-v1.4.ckpt` with the correct path to wherever you stashed this file. If you prefer not to copy or move the .ckpt file, -you may instead create a shortcut to it from within `models\ldm\stable-diffusion-v1\`. + !!! example "" -9. Start generating images! + !!! warning "IMPORTANT" -``` -# for the pre-release weights -python scripts\dream.py -l + Make sure that the conda environment is activated, which should create + `(invokeai)` in front of your prompt! -# for the post-release weights -python scripts\dream.py -``` + === "CLI" -10. Subsequently, to relaunch the script, first activate the Anaconda command window (step 3),enter the InvokeAI directory (step 5, `cd \path\to\InvokeAI`), run `conda activate ldm` (step 6b), and then launch the dream script (step 9). + ```bash + python scripts/invoke.py + ``` -**Note:** Tildebyte has written an alternative ["Easy peasy Windows -install"](https://github.com/lstein/stable-diffusion/wiki/Easy-peasy-Windows-install) -which uses the Windows Powershell and pew. If you are having trouble with Anaconda on Windows, give this a try (or try it first!) + === "local Webserver" -### Updating to newer versions of the script + ```bash + python scripts/invoke.py --web + ``` -This distribution is changing rapidly. If you used the `git clone` method (step 5) to download the InvokeAI directory, then to update to the latest and greatest version, launch the Anaconda window, enter `InvokeAI`, and type: + === "Public Webserver" -``` + ```bash + python scripts/invoke.py --web --host 0.0.0.0 + ``` + + To use an alternative model you may invoke the `!switch` command in + the CLI, or pass `--model ` during `invoke.py` launch for + either the CLI or the Web UI. See [Command Line + Client](../features/CLI.md#model-selection-and-importation). The + model names are defined in `configs/models.yaml`. + +9. Subsequently, to relaunch the script, first activate the Anaconda +command window (step 3),enter the InvokeAI directory (step 5, `cd +\path\to\InvokeAI`), run `conda activate invokeai` (step 6b), and then +launch the invoke script (step 9). + +!!! tip "Tildebyte has written an alternative" + + ["Easy peasy Windows install"](https://github.com/invoke-ai/InvokeAI/wiki/Easy-peasy-Windows-install) + which uses the Windows Powershell and pew. If you are having trouble with + Anaconda on Windows, give this a try (or try it first!) + +--- + +This distribution is changing rapidly. If you used the `git clone` method +(step 5) to download the stable-diffusion directory, then to update to the +latest and greatest version, launch the Anaconda window, enter +`stable-diffusion`, and type: + +```bash git pull -conda env update -f environment.yaml +conda env update ``` This will bring your local copy into sync with the remote one. diff --git a/docs/openapi3_0.yaml b/docs/openapi3_0.yaml new file mode 100644 index 0000000000..86dfca6783 --- /dev/null +++ b/docs/openapi3_0.yaml @@ -0,0 +1,73 @@ +openapi: 3.0.3 +info: + title: Stable Diffusion + description: |- + TODO: Description Here + + Some useful links: + - [Stable Diffusion Dream Server](https://github.com/lstein/stable-diffusion) + + license: + name: MIT License + url: https://github.com/lstein/stable-diffusion/blob/main/LICENSE + version: 1.0.0 +servers: + - url: http://localhost:9090/api +tags: + - name: images + description: Retrieve and manage generated images +paths: + /images/{imageId}: + get: + tags: + - images + summary: Get image by ID + description: Returns a single image + operationId: getImageById + parameters: + - name: imageId + in: path + description: ID of image to return + required: true + schema: + type: string + responses: + '200': + description: successful operation + content: + image/png: + schema: + type: string + format: binary + '404': + description: Image not found + /intermediates/{intermediateId}/{step}: + get: + tags: + - images + summary: Get intermediate image by ID + description: Returns a single intermediate image + operationId: getIntermediateById + parameters: + - name: intermediateId + in: path + description: ID of intermediate to return + required: true + schema: + type: string + - name: step + in: path + description: The generation step of the intermediate + required: true + schema: + type: string + responses: + '200': + description: successful operation + content: + image/png: + schema: + type: string + format: binary + '404': + description: Intermediate not found diff --git a/docs/CONTRIBUTORS.md b/docs/other/CONTRIBUTORS.md similarity index 71% rename from docs/CONTRIBUTORS.md rename to docs/other/CONTRIBUTORS.md index 57a9d5cd38..e016685405 100644 --- a/docs/CONTRIBUTORS.md +++ b/docs/other/CONTRIBUTORS.md @@ -1,14 +1,19 @@ -# Contributors +--- +title: Contributors +--- -The list of all the amazing people who have contributed to the various features that you get to experience in this fork. +# :octicons-person-24: Contributors + +The list of all the amazing people who have contributed to the various features that you get to +experience in this fork. We thank them for all of their time and hard work. -_Original Author:_ +## **Original Author:** -- Lincoln D. Stein +- [Lincoln D. Stein](mailto:lincoln.stein@gmail.com) -_Contributions by:_ +## **Contributions by:** - [Sean McLellan](https://github.com/Oceanswave) - [Kevin Gibbons](https://github.com/bakkot) @@ -45,8 +50,19 @@ _Contributions by:_ - [Paul Sajna](https://github.com/sajattack) - [Samuel Husso](https://github.com/shusso) - [nicolai256](https://github.com/nicolai256) +- [Mihai](https://github.com/mh-dm) +- [Any Winter](https://github.com/any-winter-4079) +- [Doggettx](https://github.com/doggettx) +- [Matthias Wild](https://github.com/mauwii) +- [Kyle Schouviller](https://github.com/kyle0654) +- [rabidcopy](https://github.com/rabidcopy) +- [Dominic Letz](https://github.com/dominicletz) +- [Dmitry T.](https://github.com/ArDiouscuros) +- [Kent Keirsey](https://github.com/hipsterusername) +- [psychedelicious](https://github.com/psychedelicious) +- [damian0815](https://github.com/damian0815) -_Original CompVis Authors:_ +## **Original CompVis Authors:** - [Robin Rombach](https://github.com/rromb) - [Patrick von Platen](https://github.com/patrickvonplaten) @@ -58,4 +74,5 @@ _Original CompVis Authors:_ --- -_If you have contributed and don't see your name on the list of contributors, please let one of the collaborators know about the omission, or feel free to make a pull request._ +_If you have contributed and don't see your name on the list of contributors, please let one of the +collaborators know about the omission, or feel free to make a pull request._ diff --git a/docs/README-CompViz.md b/docs/other/README-CompViz.md similarity index 51% rename from docs/README-CompViz.md rename to docs/other/README-CompViz.md index ed7df6a4ea..cb3a207b2e 100644 --- a/docs/README-CompViz.md +++ b/docs/other/README-CompViz.md @@ -1,6 +1,12 @@ -# Original README from CompViz/stable-diffusion +--- +title: CompViz-Readme +--- -_Stable Diffusion was made possible thanks to a collaboration with [Stability AI](https://stability.ai/) and [Runway](https://runwayml.com/) and builds upon our previous work:_ +# _README from [CompViz/stable-diffusion](https://github.com/CompVis/stable-diffusion)_ + +_Stable Diffusion was made possible thanks to a collaboration with +[Stability AI](https://stability.ai/) and [Runway](https://runwayml.com/) and +builds upon our previous work:_ [**High-Resolution Image Synthesis with Latent Diffusion Models**](https://ommer-lab.com/research/latent-diffusion-models/)
[Robin Rombach](https://github.com/rromb)\*, @@ -9,32 +15,43 @@ _Stable Diffusion was made possible thanks to a collaboration with [Stability AI [Patrick Esser](https://github.com/pesser), [Björn Ommer](https://hci.iwr.uni-heidelberg.de/Staff/bommer)
-**CVPR '22 Oral** +## **CVPR '22 Oral** -which is available on [GitHub](https://github.com/CompVis/latent-diffusion). PDF at [arXiv](https://arxiv.org/abs/2112.10752). Please also visit our [Project page](https://ommer-lab.com/research/latent-diffusion-models/). +which is available on [GitHub](https://github.com/CompVis/latent-diffusion). PDF +at [arXiv](https://arxiv.org/abs/2112.10752). Please also visit our +[Project page](https://ommer-lab.com/research/latent-diffusion-models/). ![txt2img-stable2](../assets/stable-samples/txt2img/merged-0006.png) [Stable Diffusion](#stable-diffusion-v1) is a latent text-to-image diffusion -model. -Thanks to a generous compute donation from [Stability AI](https://stability.ai/) and support from [LAION](https://laion.ai/), we were able to train a Latent Diffusion Model on 512x512 images from a subset of the [LAION-5B](https://laion.ai/blog/laion-5b/) database. -Similar to Google's [Imagen](https://arxiv.org/abs/2205.11487), -this model uses a frozen CLIP ViT-L/14 text encoder to condition the model on text prompts. -With its 860M UNet and 123M text encoder, the model is relatively lightweight and runs on a GPU with at least 10GB VRAM. -See [this section](#stable-diffusion-v1) below and the [model card](https://huggingface.co/CompVis/stable-diffusion). +model. Thanks to a generous compute donation from +[Stability AI](https://stability.ai/) and support from +[LAION](https://laion.ai/), we were able to train a Latent Diffusion Model on +512x512 images from a subset of the [LAION-5B](https://laion.ai/blog/laion-5b/) +database. Similar to Google's [Imagen](https://arxiv.org/abs/2205.11487), this +model uses a frozen CLIP ViT-L/14 text encoder to condition the model on text +prompts. With its 860M UNet and 123M text encoder, the model is relatively +lightweight and runs on a GPU with at least 10GB VRAM. See +[this section](#stable-diffusion-v1) below and the +[model card](https://huggingface.co/CompVis/stable-diffusion). ## Requirements -A suitable [conda](https://conda.io/) environment named `ldm` can be created -and activated with: +A suitable [conda](https://conda.io/) environment named `ldm` can be created and +activated with: ``` -conda env create -f environment.yaml +conda env create conda activate ldm ``` -You can also update an existing [latent diffusion](https://github.com/CompVis/latent-diffusion) environment by running +Note that the first line may be abbreviated `conda env create`, since conda will +look for `environment.yml` by default. -``` +You can also update an existing +[latent diffusion](https://github.com/CompVis/latent-diffusion) environment by +running + +```bash conda install pytorch torchvision -c pytorch pip install transformers==4.19.2 pip install -e . @@ -42,42 +59,57 @@ pip install -e . ## Stable Diffusion v1 -Stable Diffusion v1 refers to a specific configuration of the model -architecture that uses a downsampling-factor 8 autoencoder with an 860M UNet -and CLIP ViT-L/14 text encoder for the diffusion model. The model was pretrained on 256x256 images and -then finetuned on 512x512 images. +Stable Diffusion v1 refers to a specific configuration of the model architecture +that uses a downsampling-factor 8 autoencoder with an 860M UNet and CLIP +ViT-L/14 text encoder for the diffusion model. The model was pretrained on +256x256 images and then finetuned on 512x512 images. -\*Note: Stable Diffusion v1 is a general text-to-image diffusion model and therefore mirrors biases and (mis-)conceptions that are present -in its training data. -Details on the training procedure and data, as well as the intended use of the model can be found in the corresponding [model card](https://huggingface.co/CompVis/stable-diffusion). -Research into the safe deployment of general text-to-image models is an ongoing effort. To prevent misuse and harm, we currently provide access to the checkpoints only for [academic research purposes upon request](https://stability.ai/academia-access-form). -**This is an experiment in safe and community-driven publication of a capable and general text-to-image model. We are working on a public release with a more permissive license that also incorporates ethical considerations.\*** +\*Note: Stable Diffusion v1 is a general text-to-image diffusion model and +therefore mirrors biases and (mis-)conceptions that are present in its training +data. Details on the training procedure and data, as well as the intended use of +the model can be found in the corresponding +[model card](https://huggingface.co/CompVis/stable-diffusion). Research into the +safe deployment of general text-to-image models is an ongoing effort. To prevent +misuse and harm, we currently provide access to the checkpoints only for +[academic research purposes upon request](https://stability.ai/academia-access-form). +**This is an experiment in safe and community-driven publication of a capable +and general text-to-image model. We are working on a public release with a more +permissive license that also incorporates ethical considerations.\*** [Request access to Stable Diffusion v1 checkpoints for academic research](https://stability.ai/academia-access-form) ### Weights -We currently provide three checkpoints, `sd-v1-1.ckpt`, `sd-v1-2.ckpt` and `sd-v1-3.ckpt`, -which were trained as follows, +We currently provide three checkpoints, `sd-v1-1.ckpt`, `sd-v1-2.ckpt` and +`sd-v1-3.ckpt`, which were trained as follows, -- `sd-v1-1.ckpt`: 237k steps at resolution `256x256` on [laion2B-en](https://huggingface.co/datasets/laion/laion2B-en). - 194k steps at resolution `512x512` on [laion-high-resolution](https://huggingface.co/datasets/laion/laion-high-resolution) (170M examples from LAION-5B with resolution `>= 1024x1024`). -- `sd-v1-2.ckpt`: Resumed from `sd-v1-1.ckpt`. - 515k steps at resolution `512x512` on "laion-improved-aesthetics" (a subset of laion2B-en, - filtered to images with an original size `>= 512x512`, estimated aesthetics score `> 5.0`, and an estimated watermark probability `< 0.5`. The watermark estimate is from the LAION-5B metadata, the aesthetics score is estimated using an [improved aesthetics estimator](https://github.com/christophschuhmann/improved-aesthetic-predictor)). -- `sd-v1-3.ckpt`: Resumed from `sd-v1-2.ckpt`. 195k steps at resolution `512x512` on "laion-improved-aesthetics" and 10\% dropping of the text-conditioning to improve [classifier-free guidance sampling](https://arxiv.org/abs/2207.12598). +- `sd-v1-1.ckpt`: 237k steps at resolution `256x256` on + [laion2B-en](https://huggingface.co/datasets/laion/laion2B-en). 194k steps at + resolution `512x512` on + [laion-high-resolution](https://huggingface.co/datasets/laion/laion-high-resolution) + (170M examples from LAION-5B with resolution `>= 1024x1024`). +- `sd-v1-2.ckpt`: Resumed from `sd-v1-1.ckpt`. 515k steps at resolution + `512x512` on "laion-improved-aesthetics" (a subset of laion2B-en, filtered to + images with an original size `>= 512x512`, estimated aesthetics score `> 5.0`, + and an estimated watermark probability `< 0.5`. The watermark estimate is from + the LAION-5B metadata, the aesthetics score is estimated using an + [improved aesthetics estimator](https://github.com/christophschuhmann/improved-aesthetic-predictor)). +- `sd-v1-3.ckpt`: Resumed from `sd-v1-2.ckpt`. 195k steps at resolution + `512x512` on "laion-improved-aesthetics" and 10\% dropping of the + text-conditioning to improve + [classifier-free guidance sampling](https://arxiv.org/abs/2207.12598). Evaluations with different classifier-free guidance scales (1.5, 2.0, 3.0, 4.0, -5.0, 6.0, 7.0, 8.0) and 50 PLMS sampling -steps show the relative improvements of the checkpoints: -![sd evaluation results](../assets/v1-variants-scores.jpg) +5.0, 6.0, 7.0, 8.0) and 50 PLMS sampling steps show the relative improvements of +the checkpoints: ![sd evaluation results](../assets/v1-variants-scores.jpg) ### Text-to-Image with Stable Diffusion ![txt2img-stable2](../assets/stable-samples/txt2img/merged-0005.png) ![txt2img-stable2](../assets/stable-samples/txt2img/merged-0007.png) -Stable Diffusion is a latent diffusion model conditioned on the (non-pooled) text embeddings of a CLIP ViT-L/14 text encoder. +Stable Diffusion is a latent diffusion model conditioned on the (non-pooled) +text embeddings of a CLIP ViT-L/14 text encoder. #### Sampling Script @@ -94,8 +126,11 @@ and sample with python scripts/txt2img.py --prompt "a photograph of an astronaut riding a horse" --plms ``` -By default, this uses a guidance scale of `--scale 7.5`, [Katherine Crowson's implementation](https://github.com/CompVis/latent-diffusion/pull/51) of the [PLMS](https://arxiv.org/abs/2202.09778) sampler, -and renders images of size 512x512 (which it was trained on) in 50 steps. All supported arguments are listed below (type `python scripts/txt2img.py --help`). +By default, this uses a guidance scale of `--scale 7.5`, +[Katherine Crowson's implementation](https://github.com/CompVis/latent-diffusion/pull/51) +of the [PLMS](https://arxiv.org/abs/2202.09778) sampler, and renders images of +size 512x512 (which it was trained on) in 50 steps. All supported arguments are +listed below (type `python scripts/txt2img.py --help`). ```commandline usage: txt2img.py [-h] [--prompt [PROMPT]] [--outdir [OUTDIR]] [--skip_grid] [--skip_save] [--ddim_steps DDIM_STEPS] [--plms] [--laion400m] [--fixed_code] [--ddim_eta DDIM_ETA] [--n_iter N_ITER] [--H H] [--W W] [--C C] [--f F] [--n_samples N_SAMPLES] [--n_rows N_ROWS] @@ -133,14 +168,17 @@ optional arguments: ``` -Note: The inference config for all v1 versions is designed to be used with EMA-only checkpoints. -For this reason `use_ema=False` is set in the configuration, otherwise the code will try to switch from -non-EMA to EMA weights. If you want to examine the effect of EMA vs no EMA, we provide "full" checkpoints -which contain both types of weights. For these, `use_ema=False` will load and use the non-EMA weights. +Note: The inference config for all v1 versions is designed to be used with +EMA-only checkpoints. For this reason `use_ema=False` is set in the +configuration, otherwise the code will try to switch from non-EMA to EMA +weights. If you want to examine the effect of EMA vs no EMA, we provide "full" +checkpoints which contain both types of weights. For these, `use_ema=False` will +load and use the non-EMA weights. #### Diffusers Integration -Another way to download and sample Stable Diffusion is by using the [diffusers library](https://github.com/huggingface/diffusers/tree/main#new--stable-diffusion-is-now-fully-compatible-with-diffusers) +Another way to download and sample Stable Diffusion is by using the +[diffusers library](https://github.com/huggingface/diffusers/tree/main#new--stable-diffusion-is-now-fully-compatible-with-diffusers) ```py # make sure you're logged in with `huggingface-cli login` @@ -161,18 +199,23 @@ image.save("astronaut_rides_horse.png") ### Image Modification with Stable Diffusion -By using a diffusion-denoising mechanism as first proposed by [SDEdit](https://arxiv.org/abs/2108.01073), the model can be used for different -tasks such as text-guided image-to-image translation and upscaling. Similar to the txt2img sampling script, -we provide a script to perform image modification with Stable Diffusion. +By using a diffusion-denoising mechanism as first proposed by +[SDEdit](https://arxiv.org/abs/2108.01073), the model can be used for different +tasks such as text-guided image-to-image translation and upscaling. Similar to +the txt2img sampling script, we provide a script to perform image modification +with Stable Diffusion. -The following describes an example where a rough sketch made in [Pinta](https://www.pinta-project.com/) is converted into a detailed artwork. +The following describes an example where a rough sketch made in +[Pinta](https://www.pinta-project.com/) is converted into a detailed artwork. ``` python scripts/img2img.py --prompt "A fantasy landscape, trending on artstation" --init-img --strength 0.8 ``` -Here, strength is a value between 0.0 and 1.0, that controls the amount of noise that is added to the input image. -Values that approach 1.0 allow for lots of variations but will also produce images that are not semantically consistent with the input. See the following example. +Here, strength is a value between 0.0 and 1.0, that controls the amount of noise +that is added to the input image. Values that approach 1.0 allow for lots of +variations but will also produce images that are not semantically consistent +with the input. See the following example. **Input** @@ -183,15 +226,19 @@ Values that approach 1.0 allow for lots of variations but will also produce imag ![out3](../assets/stable-samples/img2img/mountains-3.png) ![out2](../assets/stable-samples/img2img/mountains-2.png) -This procedure can, for example, also be used to upscale samples from the base model. +This procedure can, for example, also be used to upscale samples from the base +model. ## Comments -- Our codebase for the diffusion models builds heavily on [OpenAI's ADM codebase](https://github.com/openai/guided-diffusion) - and [https://github.com/lucidrains/denoising-diffusion-pytorch](https://github.com/lucidrains/denoising-diffusion-pytorch). +- Our codebase for the diffusion models builds heavily on + [OpenAI's ADM codebase](https://github.com/openai/guided-diffusion) and + [https://github.com/lucidrains/denoising-diffusion-pytorch](https://github.com/lucidrains/denoising-diffusion-pytorch). Thanks for open-sourcing! -- The implementation of the transformer encoder is from [x-transformers](https://github.com/lucidrains/x-transformers) by [lucidrains](https://github.com/lucidrains?tab=repositories). +- The implementation of the transformer encoder is from + [x-transformers](https://github.com/lucidrains/x-transformers) by + [lucidrains](https://github.com/lucidrains?tab=repositories). ## BibTeX diff --git a/docs/swagger-ui/favicon-16x16.png b/docs/swagger-ui/favicon-16x16.png new file mode 100644 index 0000000000..8b194e617a Binary files /dev/null and b/docs/swagger-ui/favicon-16x16.png differ diff --git a/docs/swagger-ui/favicon-32x32.png b/docs/swagger-ui/favicon-32x32.png new file mode 100644 index 0000000000..249737fe44 Binary files /dev/null and b/docs/swagger-ui/favicon-32x32.png differ diff --git a/docs/swagger-ui/index.css b/docs/swagger-ui/index.css new file mode 100644 index 0000000000..f2376fdaa8 --- /dev/null +++ b/docs/swagger-ui/index.css @@ -0,0 +1,16 @@ +html { + box-sizing: border-box; + overflow: -moz-scrollbars-vertical; + overflow-y: scroll; +} + +*, +*:before, +*:after { + box-sizing: inherit; +} + +body { + margin: 0; + background: #fafafa; +} diff --git a/docs/swagger-ui/oauth2-redirect.html b/docs/swagger-ui/oauth2-redirect.html new file mode 100644 index 0000000000..5640917181 --- /dev/null +++ b/docs/swagger-ui/oauth2-redirect.html @@ -0,0 +1,79 @@ + + + + Swagger UI: OAuth2 Redirect + + + + + diff --git a/docs/swagger-ui/swagger-initializer.js b/docs/swagger-ui/swagger-initializer.js new file mode 100644 index 0000000000..5ab64bd9f9 --- /dev/null +++ b/docs/swagger-ui/swagger-initializer.js @@ -0,0 +1,20 @@ +window.onload = function() { + // + + // the following lines will be replaced by docker/configurator, when it runs in a docker-container + window.ui = SwaggerUIBundle({ + url: "openapi3_0.yaml", + dom_id: '#swagger-ui', + deepLinking: true, + presets: [ + SwaggerUIBundle.presets.apis, + SwaggerUIStandalonePreset + ], + plugins: [ + SwaggerUIBundle.plugins.DownloadUrl + ], + layout: "StandaloneLayout" + }); + + // +}; diff --git a/docs/swagger-ui/swagger-ui-bundle.js b/docs/swagger-ui/swagger-ui-bundle.js new file mode 100644 index 0000000000..3d6c34e73a --- /dev/null +++ b/docs/swagger-ui/swagger-ui-bundle.js @@ -0,0 +1,3 @@ +/*! For license information please see swagger-ui-bundle.js.LICENSE.txt */ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.SwaggerUIBundle=t():e.SwaggerUIBundle=t()}(this,(function(){return(()=>{var e={17967:(e,t)=>{"use strict";t.N=void 0;var r=/^([^\w]*)(javascript|data|vbscript)/im,n=/&#(\w+)(^\w|;)?/g,o=/[\u0000-\u001F\u007F-\u009F\u2000-\u200D\uFEFF]/gim,a=/^([^:]+):/gm,i=[".","/"];t.N=function(e){var t,s=(t=e||"",t.replace(n,(function(e,t){return String.fromCharCode(t)}))).replace(o,"").trim();if(!s)return"about:blank";if(function(e){return i.indexOf(e[0])>-1}(s))return s;var l=s.match(a);if(!l)return s;var u=l[0];return r.test(u)?"about:blank":s}},53795:(e,t,r)=>{"use strict";r.d(t,{Z:()=>P});var n=r(23101),o=r.n(n),a=r(61125),i=r.n(a),s=r(11882),l=r.n(s),u=r(97606),c=r.n(u),p=r(67294),f=r(43393);function h(e){return h="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},h(e)}function d(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function m(e,t){for(var r=0;r1&&void 0!==arguments[1]?arguments[1]:{},r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},n=k(t,r),o=e||Object.keys(y({},r,{},t));return o.every(n)}function k(e,t){return function(r){if("string"==typeof r)return(0,f.is)(t[r],e[r]);if(Array.isArray(r))return(0,f.is)(S(t,r),S(e,r));throw new TypeError("Invalid key: expected Array or string: "+r)}}var C=function(e){function t(){return d(this,t),E(this,b(t).apply(this,arguments))}var r,n,o;return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&w(e,t)}(t,e),r=t,n=[{key:"shouldComponentUpdate",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return!A(this.updateOnProps,this.props,e,"updateOnProps")||!A(this.updateOnStates,this.state,t,"updateOnStates")}}],n&&m(r.prototype,n),o&&m(r,o),t}(p.Component);const O=C;var j=r(23930),I=r.n(j),N=r(45697),T=r.n(N);class P extends O{constructor(){super(...arguments),i()(this,"getModelName",(e=>-1!==l()(e).call(e,"#/definitions/")?e.replace(/^.*#\/definitions\//,""):-1!==l()(e).call(e,"#/components/schemas/")?e.replace(/^.*#\/components\/schemas\//,""):void 0)),i()(this,"getRefSchema",(e=>{let{specSelectors:t}=this.props;return t.findDefinition(e)}))}render(){let{getComponent:e,getConfigs:t,specSelectors:n,schema:a,required:i,name:s,isRef:l,specPath:u,displayName:c,includeReadOnly:f,includeWriteOnly:h}=this.props;const d=e("ObjectModel"),m=e("ArrayModel"),g=e("PrimitiveModel");let v="object",y=a&&a.get("$$ref");if(!s&&y&&(s=this.getModelName(y)),!a&&y&&(a=this.getRefSchema(s)),!a)return p.createElement("span",{className:"model model-title"},p.createElement("span",{className:"model-title__text"},c||s),p.createElement("img",{src:r(2517),height:"20px",width:"20px"}));const b=n.isOAS3()&&a.get("deprecated");switch(l=void 0!==l?l:!!y,v=a&&a.get("type")||v,v){case"object":return p.createElement(d,o()({className:"object"},this.props,{specPath:u,getConfigs:t,schema:a,name:s,deprecated:b,isRef:l,includeReadOnly:f,includeWriteOnly:h}));case"array":return p.createElement(m,o()({className:"array"},this.props,{getConfigs:t,schema:a,name:s,deprecated:b,required:i,includeReadOnly:f,includeWriteOnly:h}));default:return p.createElement(g,o()({},this.props,{getComponent:e,getConfigs:t,schema:a,name:s,deprecated:b,required:i}))}}}i()(P,"propTypes",{schema:c()(I()).isRequired,getComponent:T().func.isRequired,getConfigs:T().func.isRequired,specSelectors:T().object.isRequired,name:T().string,displayName:T().string,isRef:T().bool,required:T().bool,expandDepth:T().number,depth:T().number,specPath:I().list.isRequired,includeReadOnly:T().bool,includeWriteOnly:T().bool})},5623:(e,t,r)=>{"use strict";r.d(t,{Z:()=>f});var n=r(61125),o=r.n(n),a=r(28222),i=r.n(a),s=r(67294),l=r(84564),u=r.n(l),c=r(90242),p=r(27504);class f extends s.Component{constructor(e,t){super(e,t),o()(this,"getDefinitionUrl",(()=>{let{specSelectors:e}=this.props;return new(u())(e.url(),p.Z.location).toString()}));let{getConfigs:r}=e,{validatorUrl:n}=r();this.state={url:this.getDefinitionUrl(),validatorUrl:void 0===n?"https://validator.swagger.io/validator":n}}UNSAFE_componentWillReceiveProps(e){let{getConfigs:t}=e,{validatorUrl:r}=t();this.setState({url:this.getDefinitionUrl(),validatorUrl:void 0===r?"https://validator.swagger.io/validator":r})}render(){let{getConfigs:e}=this.props,{spec:t}=e(),r=(0,c.Nm)(this.state.validatorUrl);return"object"==typeof t&&i()(t).length?null:this.state.url&&(0,c.hW)(this.state.validatorUrl)&&(0,c.hW)(this.state.url)?s.createElement("span",{className:"float-right"},s.createElement("a",{target:"_blank",rel:"noopener noreferrer",href:`${r}/debug?url=${encodeURIComponent(this.state.url)}`},s.createElement(h,{src:`${r}?url=${encodeURIComponent(this.state.url)}`,alt:"Online validator badge"}))):null}}class h extends s.Component{constructor(e){super(e),this.state={loaded:!1,error:!1}}componentDidMount(){const e=new Image;e.onload=()=>{this.setState({loaded:!0})},e.onerror=()=>{this.setState({error:!0})},e.src=this.props.src}UNSAFE_componentWillReceiveProps(e){if(e.src!==this.props.src){const t=new Image;t.onload=()=>{this.setState({loaded:!0})},t.onerror=()=>{this.setState({error:!0})},t.src=e.src}}render(){return this.state.error?s.createElement("img",{alt:"Error"}):this.state.loaded?s.createElement("img",{src:this.props.src,alt:this.props.alt}):null}}},86019:(e,t,r)=>{"use strict";r.d(t,{Z:()=>me,s:()=>ge});var n=r(67294),o=r(89927);function a(e,t){if(Array.prototype.indexOf)return e.indexOf(t);for(var r=0,n=e.length;r=0;r--)!0===t(e[r])&&e.splice(r,1)}function s(e){throw new Error("Unhandled case for value: '"+e+"'")}var l=function(){function e(e){void 0===e&&(e={}),this.tagName="",this.attrs={},this.innerHTML="",this.whitespaceRegex=/\s+/,this.tagName=e.tagName||"",this.attrs=e.attrs||{},this.innerHTML=e.innerHtml||e.innerHTML||""}return e.prototype.setTagName=function(e){return this.tagName=e,this},e.prototype.getTagName=function(){return this.tagName||""},e.prototype.setAttr=function(e,t){return this.getAttrs()[e]=t,this},e.prototype.getAttr=function(e){return this.getAttrs()[e]},e.prototype.setAttrs=function(e){return Object.assign(this.getAttrs(),e),this},e.prototype.getAttrs=function(){return this.attrs||(this.attrs={})},e.prototype.setClass=function(e){return this.setAttr("class",e)},e.prototype.addClass=function(e){for(var t,r=this.getClass(),n=this.whitespaceRegex,o=r?r.split(n):[],i=e.split(n);t=i.shift();)-1===a(o,t)&&o.push(t);return this.getAttrs().class=o.join(" "),this},e.prototype.removeClass=function(e){for(var t,r=this.getClass(),n=this.whitespaceRegex,o=r?r.split(n):[],i=e.split(n);o.length&&(t=i.shift());){var s=a(o,t);-1!==s&&o.splice(s,1)}return this.getAttrs().class=o.join(" "),this},e.prototype.getClass=function(){return this.getAttrs().class||""},e.prototype.hasClass=function(e){return-1!==(" "+this.getClass()+" ").indexOf(" "+e+" ")},e.prototype.setInnerHTML=function(e){return this.innerHTML=e,this},e.prototype.setInnerHtml=function(e){return this.setInnerHTML(e)},e.prototype.getInnerHTML=function(){return this.innerHTML||""},e.prototype.getInnerHtml=function(){return this.getInnerHTML()},e.prototype.toAnchorString=function(){var e=this.getTagName(),t=this.buildAttrsStr();return["<",e,t=t?" "+t:"",">",this.getInnerHtml(),""].join("")},e.prototype.buildAttrsStr=function(){if(!this.attrs)return"";var e=this.getAttrs(),t=[];for(var r in e)e.hasOwnProperty(r)&&t.push(r+'="'+e[r]+'"');return t.join(" ")},e}();var u=function(){function e(e){void 0===e&&(e={}),this.newWindow=!1,this.truncate={},this.className="",this.newWindow=e.newWindow||!1,this.truncate=e.truncate||{},this.className=e.className||""}return e.prototype.build=function(e){return new l({tagName:"a",attrs:this.createAttrs(e),innerHtml:this.processAnchorText(e.getAnchorText())})},e.prototype.createAttrs=function(e){var t={href:e.getAnchorHref()},r=this.createCssClass(e);return r&&(t.class=r),this.newWindow&&(t.target="_blank",t.rel="noopener noreferrer"),this.truncate&&this.truncate.length&&this.truncate.length=s)return l.host.length==t?(l.host.substr(0,t-o)+r).substr(0,s+n):i(c,s).substr(0,s+n);var p="";if(l.path&&(p+="/"+l.path),l.query&&(p+="?"+l.query),p){if((c+p).length>=s)return(c+p).length==t?(c+p).substr(0,t):(c+i(p,s-c.length)).substr(0,s+n);c+=p}if(l.fragment){var f="#"+l.fragment;if((c+f).length>=s)return(c+f).length==t?(c+f).substr(0,t):(c+i(f,s-c.length)).substr(0,s+n);c+=f}if(l.scheme&&l.host){var h=l.scheme+"://";if((c+h).length0&&(d=c.substr(-1*Math.floor(s/2))),(c.substr(0,Math.ceil(s/2))+r+d).substr(0,s+n)}(e,r):"middle"===n?function(e,t,r){if(e.length<=t)return e;var n,o;null==r?(r="…",n=8,o=3):(n=r.length,o=r.length);var a=t-o,i="";return a>0&&(i=e.substr(-1*Math.floor(a/2))),(e.substr(0,Math.ceil(a/2))+r+i).substr(0,a+n)}(e,r):function(e,t,r){return function(e,t,r){var n;return e.length>t&&(null==r?(r="…",n=3):n=r.length,e=e.substring(0,t-n)+r),e}(e,t,r)}(e,r)},e}(),c=function(){function e(e){this.__jsduckDummyDocProp=null,this.matchedText="",this.offset=0,this.tagBuilder=e.tagBuilder,this.matchedText=e.matchedText,this.offset=e.offset}return e.prototype.getMatchedText=function(){return this.matchedText},e.prototype.setOffset=function(e){this.offset=e},e.prototype.getOffset=function(){return this.offset},e.prototype.getCssClassSuffixes=function(){return[this.getType()]},e.prototype.buildTag=function(){return this.tagBuilder.build(this)},e}(),p=function(e,t){return p=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r])},p(e,t)};function f(e,t){function r(){this.constructor=e}p(e,t),e.prototype=null===t?Object.create(t):(r.prototype=t.prototype,new r)}var h=function(){return h=Object.assign||function(e){for(var t,r=1,n=arguments.length;r-1},e.isValidUriScheme=function(e){var t=e.match(this.uriSchemeRegex),r=t&&t[0].toLowerCase();return"javascript:"!==r&&"vbscript:"!==r},e.urlMatchDoesNotHaveProtocolOrDot=function(e,t){return!(!e||t&&this.hasFullProtocolRegex.test(t)||-1!==e.indexOf("."))},e.urlMatchDoesNotHaveAtLeastOneWordChar=function(e,t){return!(!e||!t)&&(!this.hasFullProtocolRegex.test(t)&&!this.hasWordCharAfterProtocolRegex.test(e))},e.hasFullProtocolRegex=/^[A-Za-z][-.+A-Za-z0-9]*:\/\//,e.uriSchemeRegex=/^[A-Za-z][-.+A-Za-z0-9]*:/,e.hasWordCharAfterProtocolRegex=new RegExp(":[^\\s]*?["+C+"]"),e.ipRegex=/[0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?(:[0-9]*)?\/?$/,e}(),V=(d=new RegExp("[/?#](?:["+N+"\\-+&@#/%=~_()|'$*\\[\\]{}?!:,.;^✓]*["+N+"\\-+&@#/%=~_()|'$*\\[\\]{}✓])?"),new RegExp(["(?:","(",/(?:[A-Za-z][-.+A-Za-z0-9]{0,63}:(?![A-Za-z][-.+A-Za-z0-9]{0,63}:\/\/)(?!\d+\/?)(?:\/\/)?)/.source,M(2),")","|","(","(//)?",/(?:www\.)/.source,M(6),")","|","(","(//)?",M(10)+"\\.",L.source,"(?![-"+I+"])",")",")","(?::[0-9]+)?","(?:"+d.source+")?"].join(""),"gi")),$=new RegExp("["+N+"]"),W=function(e){function t(t){var r=e.call(this,t)||this;return r.stripPrefix={scheme:!0,www:!0},r.stripTrailingSlash=!0,r.decodePercentEncoding=!0,r.matcherRegex=V,r.wordCharRegExp=$,r.stripPrefix=t.stripPrefix,r.stripTrailingSlash=t.stripTrailingSlash,r.decodePercentEncoding=t.decodePercentEncoding,r}return f(t,e),t.prototype.parseMatches=function(e){for(var t,r=this.matcherRegex,n=this.stripPrefix,o=this.stripTrailingSlash,a=this.decodePercentEncoding,i=this.tagBuilder,s=[],l=function(){var r=t[0],l=t[1],c=t[4],p=t[5],f=t[9],h=t.index,d=p||f,m=e.charAt(h-1);if(!q.isValid(r,l))return"continue";if(h>0&&"@"===m)return"continue";if(h>0&&d&&u.wordCharRegExp.test(m))return"continue";if(/\?$/.test(r)&&(r=r.substr(0,r.length-1)),u.matchHasUnbalancedClosingParen(r))r=r.substr(0,r.length-1);else{var g=u.matchHasInvalidCharAfterTld(r,l);g>-1&&(r=r.substr(0,g))}var v=["http://","https://"].find((function(e){return!!l&&-1!==l.indexOf(e)}));if(v){var y=r.indexOf(v);r=r.substr(y),l=l.substr(y),h+=y}var w=l?"scheme":c?"www":"tld",E=!!l;s.push(new b({tagBuilder:i,matchedText:r,offset:h,urlMatchType:w,url:r,protocolUrlMatch:E,protocolRelativeMatch:!!d,stripPrefix:n,stripTrailingSlash:o,decodePercentEncoding:a}))},u=this;null!==(t=r.exec(e));)l();return s},t.prototype.matchHasUnbalancedClosingParen=function(e){var t,r=e.charAt(e.length-1);if(")"===r)t="(";else if("]"===r)t="[";else{if("}"!==r)return!1;t="{"}for(var n=0,o=0,a=e.length-1;o"===e?(m=new ne(h(h({},m),{name:H()})),W()):E.test(e)||x.test(e)||":"===e||V()}function w(e){">"===e?V():E.test(e)?f=3:V()}function _(e){S.test(e)||("/"===e?f=12:">"===e?W():"<"===e?$():"="===e||A.test(e)||k.test(e)?V():f=5)}function C(e){S.test(e)?f=6:"/"===e?f=12:"="===e?f=7:">"===e?W():"<"===e?$():A.test(e)&&V()}function O(e){S.test(e)||("/"===e?f=12:"="===e?f=7:">"===e?W():"<"===e?$():A.test(e)?V():f=5)}function j(e){S.test(e)||('"'===e?f=8:"'"===e?f=9:/[>=`]/.test(e)?V():"<"===e?$():f=10)}function I(e){'"'===e&&(f=11)}function N(e){"'"===e&&(f=11)}function T(e){S.test(e)?f=4:">"===e?W():"<"===e&&$()}function P(e){S.test(e)?f=4:"/"===e?f=12:">"===e?W():"<"===e?$():(f=4,c--)}function R(e){">"===e?(m=new ne(h(h({},m),{isClosing:!0})),W()):f=4}function M(t){"--"===e.substr(c,2)?(c+=2,m=new ne(h(h({},m),{type:"comment"})),f=14):"DOCTYPE"===e.substr(c,7).toUpperCase()?(c+=7,m=new ne(h(h({},m),{type:"doctype"})),f=20):V()}function D(e){"-"===e?f=15:">"===e?V():f=16}function L(e){"-"===e?f=18:">"===e?V():f=16}function B(e){"-"===e&&(f=17)}function F(e){f="-"===e?18:16}function z(e){">"===e?W():"!"===e?f=19:"-"===e||(f=16)}function U(e){"-"===e?f=17:">"===e?W():f=16}function q(e){">"===e?W():"<"===e&&$()}function V(){f=0,m=u}function $(){f=1,m=new ne({idx:c})}function W(){var t=e.slice(d,m.idx);t&&a(t,d),"comment"===m.type?i(m.idx):"doctype"===m.type?l(m.idx):(m.isOpening&&n(m.name,m.idx),m.isClosing&&o(m.name,m.idx)),V(),d=c+1}function H(){var t=m.idx+(m.isClosing?2:1);return e.slice(t,c).toLowerCase()}d=0&&n++},onText:function(e,r){if(0===n){var a=function(e,t){if(!t.global)throw new Error("`splitRegex` must have the 'g' flag set");for(var r,n=[],o=0;r=t.exec(e);)n.push(e.substring(o,r.index)),n.push(r[0]),o=r.index+r[0].length;return n.push(e.substring(o)),n}(e,/( | |<|<|>|>|"|"|')/gi),i=r;a.forEach((function(e,r){if(r%2==0){var n=t.parseText(e,i);o.push.apply(o,n)}i+=e.length}))}},onCloseTag:function(e){r.indexOf(e)>=0&&(n=Math.max(n-1,0))},onComment:function(e){},onDoctype:function(e){}}),o=this.compactMatches(o),o=this.removeUnwantedMatches(o)},e.prototype.compactMatches=function(e){e.sort((function(e,t){return e.getOffset()-t.getOffset()}));for(var t=0;to?t:t+1;e.splice(i,1);continue}e[t+1].getOffset()/g,">"));for(var t=this.parse(e),r=[],n=0,o=0,a=t.length;o/i.test(e)}function se(){var e=[],t=new oe({stripPrefix:!1,url:!0,email:!0,replaceFn:function(t){switch(t.getType()){case"url":e.push({text:t.matchedText,url:t.getUrl()});break;case"email":e.push({text:t.matchedText,url:"mailto:"+t.getEmail().replace(/^mailto:/i,"")})}return!1}});return{links:e,autolinker:t}}function le(e){var t,r,n,o,a,i,s,l,u,c,p,f,h,d,m=e.tokens,g=null;for(r=0,n=m.length;r=0;t--)if("link_close"!==(a=o[t]).type){if("htmltag"===a.type&&(d=a.content,/^\s]/i.test(d)&&p>0&&p--,ie(a.content)&&p++),!(p>0)&&"text"===a.type&&ae.test(a.content)){if(g||(f=(g=se()).links,h=g.autolinker),i=a.content,f.length=0,h.link(i),!f.length)continue;for(s=[],c=a.level,l=0;l({useUnsafeMarkdown:!1})};const me=de;function ge(e){let{useUnsafeMarkdown:t=!1}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const r=t,n=t?[]:["style","class"];return t&&!ge.hasWarnedAboutDeprecation&&(console.warn("useUnsafeMarkdown display configuration parameter is deprecated since >3.26.0 and will be removed in v4.0.0."),ge.hasWarnedAboutDeprecation=!0),pe().sanitize(e,{ADD_ATTR:["target"],FORBID_TAGS:["style","form"],ALLOW_DATA_ATTR:r,FORBID_ATTR:n})}ge.hasWarnedAboutDeprecation=!1},45308:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>f});var n,o=r(86),a=r.n(o),i=r(8712),s=r.n(i),l=r(90242),u=r(27621);const c=r(95102),p={},f=p;a()(n=s()(c).call(c)).call(n,(function(e){if("./index.js"===e)return;let t=c(e);p[(0,l.Zl)(e)]=t.default?t.default:t})),p.SafeRender=u.default},55812:(e,t,r)=>{"use strict";r.r(t),r.d(t,{SHOW_AUTH_POPUP:()=>p,AUTHORIZE:()=>f,LOGOUT:()=>h,PRE_AUTHORIZE_OAUTH2:()=>d,AUTHORIZE_OAUTH2:()=>m,VALIDATE:()=>g,CONFIGURE_AUTH:()=>v,RESTORE_AUTHORIZATION:()=>y,showDefinitions:()=>b,authorize:()=>w,authorizeWithPersistOption:()=>E,logout:()=>x,logoutWithPersistOption:()=>_,preAuthorizeImplicit:()=>S,authorizeOauth2:()=>A,authorizeOauth2WithPersistOption:()=>k,authorizePassword:()=>C,authorizeApplication:()=>O,authorizeAccessCodeWithFormParams:()=>j,authorizeAccessCodeWithBasicAuthentication:()=>I,authorizeRequest:()=>N,configureAuth:()=>T,restoreAuthorization:()=>P,persistAuthorizationIfNeeded:()=>R,authPopup:()=>M});var n=r(35627),o=r.n(n),a=r(76986),i=r.n(a),s=r(84564),l=r.n(s),u=r(27504),c=r(90242);const p="show_popup",f="authorize",h="logout",d="pre_authorize_oauth2",m="authorize_oauth2",g="validate",v="configure_auth",y="restore_authorization";function b(e){return{type:p,payload:e}}function w(e){return{type:f,payload:e}}const E=e=>t=>{let{authActions:r}=t;r.authorize(e),r.persistAuthorizationIfNeeded()};function x(e){return{type:h,payload:e}}const _=e=>t=>{let{authActions:r}=t;r.logout(e),r.persistAuthorizationIfNeeded()},S=e=>t=>{let{authActions:r,errActions:n}=t,{auth:a,token:i,isValid:s}=e,{schema:l,name:c}=a,p=l.get("flow");delete u.Z.swaggerUIRedirectOauth2,"accessCode"===p||s||n.newAuthErr({authId:c,source:"auth",level:"warning",message:"Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"}),i.error?n.newAuthErr({authId:c,source:"auth",level:"error",message:o()(i)}):r.authorizeOauth2WithPersistOption({auth:a,token:i})};function A(e){return{type:m,payload:e}}const k=e=>t=>{let{authActions:r}=t;r.authorizeOauth2(e),r.persistAuthorizationIfNeeded()},C=e=>t=>{let{authActions:r}=t,{schema:n,name:o,username:a,password:s,passwordType:l,clientId:u,clientSecret:p}=e,f={grant_type:"password",scope:e.scopes.join(" "),username:a,password:s},h={};switch(l){case"request-body":!function(e,t,r){t&&i()(e,{client_id:t});r&&i()(e,{client_secret:r})}(f,u,p);break;case"basic":h.Authorization="Basic "+(0,c.r3)(u+":"+p);break;default:console.warn(`Warning: invalid passwordType ${l} was passed, not including client id and secret`)}return r.authorizeRequest({body:(0,c.GZ)(f),url:n.get("tokenUrl"),name:o,headers:h,query:{},auth:e})};const O=e=>t=>{let{authActions:r}=t,{schema:n,scopes:o,name:a,clientId:i,clientSecret:s}=e,l={Authorization:"Basic "+(0,c.r3)(i+":"+s)},u={grant_type:"client_credentials",scope:o.join(" ")};return r.authorizeRequest({body:(0,c.GZ)(u),name:a,url:n.get("tokenUrl"),auth:e,headers:l})},j=e=>{let{auth:t,redirectUrl:r}=e;return e=>{let{authActions:n}=e,{schema:o,name:a,clientId:i,clientSecret:s,codeVerifier:l}=t,u={grant_type:"authorization_code",code:t.code,client_id:i,client_secret:s,redirect_uri:r,code_verifier:l};return n.authorizeRequest({body:(0,c.GZ)(u),name:a,url:o.get("tokenUrl"),auth:t})}},I=e=>{let{auth:t,redirectUrl:r}=e;return e=>{let{authActions:n}=e,{schema:o,name:a,clientId:i,clientSecret:s,codeVerifier:l}=t,u={Authorization:"Basic "+(0,c.r3)(i+":"+s)},p={grant_type:"authorization_code",code:t.code,client_id:i,redirect_uri:r,code_verifier:l};return n.authorizeRequest({body:(0,c.GZ)(p),name:a,url:o.get("tokenUrl"),auth:t,headers:u})}},N=e=>t=>{let r,{fn:n,getConfigs:a,authActions:s,errActions:u,oas3Selectors:c,specSelectors:p,authSelectors:f}=t,{body:h,query:d={},headers:m={},name:g,url:v,auth:y}=e,{additionalQueryStringParams:b}=f.getConfigs()||{};if(p.isOAS3()){let e=c.serverEffectiveValue(c.selectedServer());r=l()(v,e,!0)}else r=l()(v,p.url(),!0);"object"==typeof b&&(r.query=i()({},r.query,b));const w=r.toString();let E=i()({Accept:"application/json, text/plain, */*","Content-Type":"application/x-www-form-urlencoded","X-Requested-With":"XMLHttpRequest"},m);n.fetch({url:w,method:"post",headers:E,query:d,body:h,requestInterceptor:a().requestInterceptor,responseInterceptor:a().responseInterceptor}).then((function(e){let t=JSON.parse(e.data),r=t&&(t.error||""),n=t&&(t.parseError||"");e.ok?r||n?u.newAuthErr({authId:g,level:"error",source:"auth",message:o()(t)}):s.authorizeOauth2WithPersistOption({auth:y,token:t}):u.newAuthErr({authId:g,level:"error",source:"auth",message:e.statusText})})).catch((e=>{let t=new Error(e).message;if(e.response&&e.response.data){const r=e.response.data;try{const e="string"==typeof r?JSON.parse(r):r;e.error&&(t+=`, error: ${e.error}`),e.error_description&&(t+=`, description: ${e.error_description}`)}catch(e){}}u.newAuthErr({authId:g,level:"error",source:"auth",message:t})}))};function T(e){return{type:v,payload:e}}function P(e){return{type:y,payload:e}}const R=()=>e=>{let{authSelectors:t,getConfigs:r}=e;if(r().persistAuthorization){const e=t.authorized();localStorage.setItem("authorized",o()(e.toJS()))}},M=(e,t)=>()=>{u.Z.swaggerUIRedirectOauth2=t,u.Z.open(e)}},93705:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>u,preauthorizeBasic:()=>c,preauthorizeApiKey:()=>p});var n=r(11189),o=r.n(n),a=r(43962),i=r(55812),s=r(60035),l=r(48302);function u(){return{afterLoad(e){this.rootInjects=this.rootInjects||{},this.rootInjects.initOAuth=e.authActions.configureAuth,this.rootInjects.preauthorizeApiKey=o()(p).call(p,null,e),this.rootInjects.preauthorizeBasic=o()(c).call(c,null,e)},statePlugins:{auth:{reducers:a.default,actions:i,selectors:s},spec:{wrapActions:l}}}}function c(e,t,r,n){const{authActions:{authorize:o},specSelectors:{specJson:a,isOAS3:i}}=e,s=i()?["components","securitySchemes"]:["securityDefinitions"],l=a().getIn([...s,t]);return l?o({[t]:{value:{username:r,password:n},schema:l.toJS()}}):null}function p(e,t,r){const{authActions:{authorize:n},specSelectors:{specJson:o,isOAS3:a}}=e,i=a()?["components","securitySchemes"]:["securityDefinitions"],s=o().getIn([...i,t]);return s?n({[t]:{value:r,schema:s.toJS()}}):null}},43962:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>c});var n=r(86),o=r.n(n),a=r(76986),i=r.n(a),s=r(43393),l=r(90242),u=r(55812);const c={[u.SHOW_AUTH_POPUP]:(e,t)=>{let{payload:r}=t;return e.set("showDefinitions",r)},[u.AUTHORIZE]:(e,t)=>{var r;let{payload:n}=t,a=(0,s.fromJS)(n),i=e.get("authorized")||(0,s.Map)();return o()(r=a.entrySeq()).call(r,(t=>{let[r,n]=t;if(!(0,l.Wl)(n.getIn))return e.set("authorized",i);let o=n.getIn(["schema","type"]);if("apiKey"===o||"http"===o)i=i.set(r,n);else if("basic"===o){let e=n.getIn(["value","username"]),t=n.getIn(["value","password"]);i=i.setIn([r,"value"],{username:e,header:"Basic "+(0,l.r3)(e+":"+t)}),i=i.setIn([r,"schema"],n.get("schema"))}})),e.set("authorized",i)},[u.AUTHORIZE_OAUTH2]:(e,t)=>{let r,{payload:n}=t,{auth:o,token:a}=n;o.token=i()({},a),r=(0,s.fromJS)(o);let l=e.get("authorized")||(0,s.Map)();return l=l.set(r.get("name"),r),e.set("authorized",l)},[u.LOGOUT]:(e,t)=>{let{payload:r}=t,n=e.get("authorized").withMutations((e=>{o()(r).call(r,(t=>{e.delete(t)}))}));return e.set("authorized",n)},[u.CONFIGURE_AUTH]:(e,t)=>{let{payload:r}=t;return e.set("configs",r)},[u.RESTORE_AUTHORIZATION]:(e,t)=>{let{payload:r}=t;return e.set("authorized",(0,s.fromJS)(r.authorized))}}},60035:(e,t,r)=>{"use strict";r.r(t),r.d(t,{shownDefinitions:()=>y,definitionsToAuthorize:()=>b,getDefinitionsByNames:()=>w,definitionsForRequirements:()=>E,authorized:()=>x,isAuthorized:()=>_,getConfigs:()=>S});var n=r(86),o=r.n(n),a=r(14418),i=r.n(a),s=r(92039),l=r.n(s),u=r(11882),c=r.n(u),p=r(97606),f=r.n(p),h=r(28222),d=r.n(h),m=r(20573),g=r(43393);const v=e=>e,y=(0,m.P1)(v,(e=>e.get("showDefinitions"))),b=(0,m.P1)(v,(()=>e=>{var t;let{specSelectors:r}=e,n=r.securityDefinitions()||(0,g.Map)({}),a=(0,g.List)();return o()(t=n.entrySeq()).call(t,(e=>{let[t,r]=e,n=(0,g.Map)();n=n.set(t,r),a=a.push(n)})),a})),w=(e,t)=>e=>{var r;let{specSelectors:n}=e;console.warn("WARNING: getDefinitionsByNames is deprecated and will be removed in the next major version.");let a=n.securityDefinitions(),i=(0,g.List)();return o()(r=t.valueSeq()).call(r,(e=>{var t;let r=(0,g.Map)();o()(t=e.entrySeq()).call(t,(e=>{let t,[n,i]=e,s=a.get(n);var l;"oauth2"===s.get("type")&&i.size&&(t=s.get("scopes"),o()(l=t.keySeq()).call(l,(e=>{i.contains(e)||(t=t.delete(e))})),s=s.set("allowedScopes",t));r=r.set(n,s)})),i=i.push(r)})),i},E=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:(0,g.List)();return e=>{let{authSelectors:r}=e;const n=r.definitionsToAuthorize()||(0,g.List)();return i()(n).call(n,(e=>l()(t).call(t,(t=>t.get(e.keySeq().first())))))}},x=(0,m.P1)(v,(e=>e.get("authorized")||(0,g.Map)())),_=(e,t)=>e=>{var r;let{authSelectors:n}=e,o=n.authorized();return g.List.isList(t)?!!i()(r=t.toJS()).call(r,(e=>{var t,r;return-1===c()(t=f()(r=d()(e)).call(r,(e=>!!o.get(e)))).call(t,!1)})).length:null},S=(0,m.P1)(v,(e=>e.get("configs")))},48302:(e,t,r)=>{"use strict";r.r(t),r.d(t,{execute:()=>n});const n=(e,t)=>{let{authSelectors:r,specSelectors:n}=t;return t=>{let{path:o,method:a,operation:i,extras:s}=t,l={authorized:r.authorized()&&r.authorized().toJS(),definitions:n.securityDefinitions()&&n.securityDefinitions().toJS(),specSecurity:n.security()&&n.security().toJS()};return e({path:o,method:a,operation:i,securities:l,...s})}}},70714:(e,t,r)=>{"use strict";r.r(t),r.d(t,{UPDATE_CONFIGS:()=>n,TOGGLE_CONFIGS:()=>o,update:()=>a,toggle:()=>i,loaded:()=>s});const n="configs_update",o="configs_toggle";function a(e,t){return{type:n,payload:{[e]:t}}}function i(e){return{type:o,payload:e}}const s=()=>e=>{let{getConfigs:t,authActions:r}=e;if(t().persistAuthorization){const e=localStorage.getItem("authorized");e&&r.restoreAuthorization({authorized:JSON.parse(e)})}}},92256:(e,t,r)=>{"use strict";r.r(t),r.d(t,{parseYamlConfig:()=>o});var n=r(1272);const o=(e,t)=>{try{return n.ZP.load(e)}catch(e){return t&&t.errActions.newThrownErr(new Error(e)),{}}}},1661:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>c});var n=r(15163),o=r(92256),a=r(70714),i=r(22698),s=r(69018),l=r(37743);const u={getLocalConfig:()=>(0,o.parseYamlConfig)(n)};function c(){return{statePlugins:{spec:{actions:i,selectors:u},configs:{reducers:l.default,actions:a,selectors:s}}}}},37743:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>a});var n=r(43393),o=r(70714);const a={[o.UPDATE_CONFIGS]:(e,t)=>e.merge((0,n.fromJS)(t.payload)),[o.TOGGLE_CONFIGS]:(e,t)=>{const r=t.payload,n=e.get(r);return e.set(r,!n)}}},69018:(e,t,r)=>{"use strict";r.r(t),r.d(t,{get:()=>a});var n=r(58309),o=r.n(n);const a=(e,t)=>e.getIn(o()(t)?t:[t])},22698:(e,t,r)=>{"use strict";r.r(t),r.d(t,{downloadConfig:()=>o,getConfigByUrl:()=>a});var n=r(92256);const o=e=>t=>{const{fn:{fetch:r}}=t;return r(e)},a=(e,t)=>r=>{let{specActions:o}=r;if(e)return o.downloadConfig(e).then(a,a);function a(r){r instanceof Error||r.status>=400?(o.updateLoadingStatus("failedConfig"),o.updateLoadingStatus("failedConfig"),o.updateUrl(""),console.error(r.statusText+" "+e.url),t(null)):t((0,n.parseYamlConfig)(r.text))}}},31970:(e,t,r)=>{"use strict";r.r(t),r.d(t,{setHash:()=>n});const n=e=>e?history.pushState(null,null,`#${e}`):window.location.hash=""},34980:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>i});var n=r(41599),o=r(60877),a=r(34584);function i(){return[n.default,{statePlugins:{configs:{wrapActions:{loaded:(e,t)=>function(){e(...arguments);const r=decodeURIComponent(window.location.hash);t.layoutActions.parseDeepLinkHash(r)}}}},wrapComponents:{operation:o.default,OperationTag:a.default}}]}},41599:(e,t,r)=>{"use strict";r.r(t),r.d(t,{show:()=>b,scrollTo:()=>w,parseDeepLinkHash:()=>E,readyToScroll:()=>x,scrollToElement:()=>_,clearScrollTo:()=>S,default:()=>A});var n=r(58309),o=r.n(n),a=r(24278),i=r.n(a),s=r(97606),l=r.n(s),u=r(11882),c=r.n(u),p=r(31970),f=r(45172),h=r.n(f),d=r(90242),m=r(43393),g=r.n(m);const v="layout_scroll_to",y="layout_clear_scroll",b=(e,t)=>{let{getConfigs:r,layoutSelectors:n}=t;return function(){for(var t=arguments.length,a=new Array(t),i=0;i({type:v,payload:o()(e)?e:[e]}),E=e=>t=>{let{layoutActions:r,layoutSelectors:n,getConfigs:o}=t;if(o().deepLinking&&e){var a;let t=i()(e).call(e,1);"!"===t[0]&&(t=i()(t).call(t,1)),"/"===t[0]&&(t=i()(t).call(t,1));const o=l()(a=t.split("/")).call(a,(e=>e||"")),s=n.isShownKeyFromUrlHashArray(o),[u,p="",f=""]=s;if("operations"===u){const e=n.isShownKeyFromUrlHashArray([p]);c()(p).call(p,"_")>-1&&(console.warn("Warning: escaping deep link whitespace with `_` will be unsupported in v4.0, use `%20` instead."),r.show(l()(e).call(e,(e=>e.replace(/_/g," "))),!0)),r.show(e,!0)}(c()(p).call(p,"_")>-1||c()(f).call(f,"_")>-1)&&(console.warn("Warning: escaping deep link whitespace with `_` will be unsupported in v4.0, use `%20` instead."),r.show(l()(s).call(s,(e=>e.replace(/_/g," "))),!0)),r.show(s,!0),r.scrollTo(s)}},x=(e,t)=>r=>{const n=r.layoutSelectors.getScrollToKey();g().is(n,(0,m.fromJS)(e))&&(r.layoutActions.scrollToElement(t),r.layoutActions.clearScrollTo())},_=(e,t)=>r=>{try{t=t||r.fn.getScrollParent(e),h().createScroller(t).to(e)}catch(e){console.error(e)}},S=()=>({type:y});const A={fn:{getScrollParent:function(e,t){const r=document.documentElement;let n=getComputedStyle(e);const o="absolute"===n.position,a=t?/(auto|scroll|hidden)/:/(auto|scroll)/;if("fixed"===n.position)return r;for(let t=e;t=t.parentElement;)if(n=getComputedStyle(t),(!o||"static"!==n.position)&&a.test(n.overflow+n.overflowY+n.overflowX))return t;return r}},statePlugins:{layout:{actions:{scrollToElement:_,scrollTo:w,clearScrollTo:S,readyToScroll:x,parseDeepLinkHash:E},selectors:{getScrollToKey:e=>e.get("scrollToKey"),isShownKeyFromUrlHashArray(e,t){const[r,n]=t;return n?["operations",r,n]:r?["operations-tag",r]:[]},urlHashArrayFromIsShownKey(e,t){let[r,n,o]=t;return"operations"==r?[n,o]:"operations-tag"==r?[n]:[]}},reducers:{[v]:(e,t)=>e.set("scrollToKey",g().fromJS(t.payload)),[y]:e=>e.delete("scrollToKey")},wrapActions:{show:b}}}}},34584:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>i});var n=r(61125),o=r.n(n),a=r(67294);const i=(e,t)=>class extends a.Component{constructor(){super(...arguments),o()(this,"onLoad",(e=>{const{tag:r}=this.props,n=["operations-tag",r];t.layoutActions.readyToScroll(n,e)}))}render(){return a.createElement("span",{ref:this.onLoad},a.createElement(e,this.props))}}},60877:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>i});var n=r(61125),o=r.n(n),a=r(67294);r(23930);const i=(e,t)=>class extends a.Component{constructor(){super(...arguments),o()(this,"onLoad",(e=>{const{operation:r}=this.props,{tag:n,operationId:o}=r.toObject();let{isShownKey:a}=r.toObject();a=a||["operations",n,o],t.layoutActions.readyToScroll(a,e)}))}render(){return a.createElement("span",{ref:this.onLoad},a.createElement(e,this.props))}}},48011:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>d});var n=r(76986),o=r.n(n),a=r(63460),i=r.n(a),s=r(11882),l=r.n(s),u=r(35627),c=r.n(u),p=r(20573),f=r(43393),h=r(27504);function d(e){let{fn:t}=e;return{statePlugins:{spec:{actions:{download:e=>r=>{let{errActions:n,specSelectors:a,specActions:s,getConfigs:l}=r,{fetch:u}=t;const c=l();function p(t){if(t instanceof Error||t.status>=400)return s.updateLoadingStatus("failed"),n.newThrownErr(o()(new Error((t.message||t.statusText)+" "+e),{source:"fetch"})),void(!t.status&&t instanceof Error&&function(){try{let t;if("URL"in h.Z?t=new(i())(e):(t=document.createElement("a"),t.href=e),"https:"!==t.protocol&&"https:"===h.Z.location.protocol){const e=o()(new Error(`Possible mixed-content issue? The page was loaded over https:// but a ${t.protocol}// URL was specified. Check that you are not attempting to load mixed content.`),{source:"fetch"});return void n.newThrownErr(e)}if(t.origin!==h.Z.location.origin){const e=o()(new Error(`Possible cross-origin (CORS) issue? The URL origin (${t.origin}) does not match the page (${h.Z.location.origin}). Check the server returns the correct 'Access-Control-Allow-*' headers.`),{source:"fetch"});n.newThrownErr(e)}}catch(e){return}}());s.updateLoadingStatus("success"),s.updateSpec(t.text),a.url()!==e&&s.updateUrl(e)}e=e||a.url(),s.updateLoadingStatus("loading"),n.clear({source:"fetch"}),u({url:e,loadSpec:!0,requestInterceptor:c.requestInterceptor||(e=>e),responseInterceptor:c.responseInterceptor||(e=>e),credentials:"same-origin",headers:{Accept:"application/json,*/*"}}).then(p,p)},updateLoadingStatus:e=>{let t=[null,"loading","failed","success","failedConfig"];return-1===l()(t).call(t,e)&&console.error(`Error: ${e} is not one of ${c()(t)}`),{type:"spec_update_loading_status",payload:e}}},reducers:{spec_update_loading_status:(e,t)=>"string"==typeof t.payload?e.set("loadingStatus",t.payload):e},selectors:{loadingStatus:(0,p.P1)((e=>e||(0,f.Map)()),(e=>e.get("loadingStatus")||null))}}}}}},34966:(e,t,r)=>{"use strict";r.r(t),r.d(t,{NEW_THROWN_ERR:()=>o,NEW_THROWN_ERR_BATCH:()=>a,NEW_SPEC_ERR:()=>i,NEW_SPEC_ERR_BATCH:()=>s,NEW_AUTH_ERR:()=>l,CLEAR:()=>u,CLEAR_BY:()=>c,newThrownErr:()=>p,newThrownErrBatch:()=>f,newSpecErr:()=>h,newSpecErrBatch:()=>d,newAuthErr:()=>m,clear:()=>g,clearBy:()=>v});var n=r(7710);const o="err_new_thrown_err",a="err_new_thrown_err_batch",i="err_new_spec_err",s="err_new_spec_err_batch",l="err_new_auth_err",u="err_clear",c="err_clear_by";function p(e){return{type:o,payload:(0,n.serializeError)(e)}}function f(e){return{type:a,payload:e}}function h(e){return{type:i,payload:e}}function d(e){return{type:s,payload:e}}function m(e){return{type:l,payload:e}}function g(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return{type:u,payload:e}}function v(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:()=>!0;return{type:c,payload:e}}},56982:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>c});var n=r(14418),o=r.n(n),a=r(97606),i=r.n(a),s=r(54061),l=r.n(s);const u=[r(2392),r(21835)];function c(e){var t;let r={jsSpec:{}},n=l()(u,((e,t)=>{try{let n=t.transform(e,r);return o()(n).call(n,(e=>!!e))}catch(t){return console.error("Transformer error:",t),e}}),e);return i()(t=o()(n).call(n,(e=>!!e))).call(t,(e=>(!e.get("line")&&e.get("path"),e)))}},2392:(e,t,r)=>{"use strict";r.r(t),r.d(t,{transform:()=>p});var n=r(97606),o=r.n(n),a=r(11882),i=r.n(a),s=r(24278),l=r.n(s),u=r(24282),c=r.n(u);function p(e){return o()(e).call(e,(e=>{var t;let r="is not of a type(s)",n=i()(t=e.get("message")).call(t,r);if(n>-1){var o,a;let t=l()(o=e.get("message")).call(o,n+r.length).split(",");return e.set("message",l()(a=e.get("message")).call(a,0,n)+function(e){return c()(e).call(e,((e,t,r,n)=>r===n.length-1&&n.length>1?e+"or "+t:n[r+1]&&n.length>2?e+t+", ":n[r+1]?e+t+" ":e+t),"should be a")}(t))}return e}))}},21835:(e,t,r)=>{"use strict";r.r(t),r.d(t,{transform:()=>n});r(97606),r(11882),r(27361),r(43393);function n(e,t){let{jsSpec:r}=t;return e}},77793:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>i});var n=r(93527),o=r(34966),a=r(87667);function i(e){return{statePlugins:{err:{reducers:(0,n.default)(e),actions:o,selectors:a}}}}},93527:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>v});var n=r(76986),o=r.n(n),a=r(97606),i=r.n(a),s=r(39022),l=r.n(s),u=r(14418),c=r.n(u),p=r(2250),f=r.n(p),h=r(34966),d=r(43393),m=r(56982);let g={line:0,level:"error",message:"Unknown error"};function v(){return{[h.NEW_THROWN_ERR]:(e,t)=>{let{payload:r}=t,n=o()(g,r,{type:"thrown"});return e.update("errors",(e=>(e||(0,d.List)()).push((0,d.fromJS)(n)))).update("errors",(e=>(0,m.default)(e)))},[h.NEW_THROWN_ERR_BATCH]:(e,t)=>{let{payload:r}=t;return r=i()(r).call(r,(e=>(0,d.fromJS)(o()(g,e,{type:"thrown"})))),e.update("errors",(e=>{var t;return l()(t=e||(0,d.List)()).call(t,(0,d.fromJS)(r))})).update("errors",(e=>(0,m.default)(e)))},[h.NEW_SPEC_ERR]:(e,t)=>{let{payload:r}=t,n=(0,d.fromJS)(r);return n=n.set("type","spec"),e.update("errors",(e=>(e||(0,d.List)()).push((0,d.fromJS)(n)).sortBy((e=>e.get("line"))))).update("errors",(e=>(0,m.default)(e)))},[h.NEW_SPEC_ERR_BATCH]:(e,t)=>{let{payload:r}=t;return r=i()(r).call(r,(e=>(0,d.fromJS)(o()(g,e,{type:"spec"})))),e.update("errors",(e=>{var t;return l()(t=e||(0,d.List)()).call(t,(0,d.fromJS)(r))})).update("errors",(e=>(0,m.default)(e)))},[h.NEW_AUTH_ERR]:(e,t)=>{let{payload:r}=t,n=(0,d.fromJS)(o()({},r));return n=n.set("type","auth"),e.update("errors",(e=>(e||(0,d.List)()).push((0,d.fromJS)(n)))).update("errors",(e=>(0,m.default)(e)))},[h.CLEAR]:(e,t)=>{var r;let{payload:n}=t;if(!n||!e.get("errors"))return e;let o=c()(r=e.get("errors")).call(r,(e=>{var t;return f()(t=e.keySeq()).call(t,(t=>{const r=e.get(t),o=n[t];return!o||r!==o}))}));return e.merge({errors:o})},[h.CLEAR_BY]:(e,t)=>{var r;let{payload:n}=t;if(!n||"function"!=typeof n)return e;let o=c()(r=e.get("errors")).call(r,(e=>n(e)));return e.merge({errors:o})}}}},87667:(e,t,r)=>{"use strict";r.r(t),r.d(t,{allErrors:()=>a,lastError:()=>i});var n=r(43393),o=r(20573);const a=(0,o.P1)((e=>e),(e=>e.get("errors",(0,n.List)()))),i=(0,o.P1)(a,(e=>e.last()))},49978:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>o});var n=r(4309);function o(){return{fn:{opsFilter:n.default}}}},4309:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>s});var n=r(14418),o=r.n(n),a=r(11882),i=r.n(a);function s(e,t){return o()(e).call(e,((e,r)=>-1!==i()(r).call(r,t)))}},25474:(e,t,r)=>{"use strict";r.r(t),r.d(t,{UPDATE_LAYOUT:()=>o,UPDATE_FILTER:()=>a,UPDATE_MODE:()=>i,SHOW:()=>s,updateLayout:()=>l,updateFilter:()=>u,show:()=>c,changeMode:()=>p});var n=r(90242);const o="layout_update_layout",a="layout_update_filter",i="layout_update_mode",s="layout_show";function l(e){return{type:o,payload:e}}function u(e){return{type:a,payload:e}}function c(e){let t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];return e=(0,n.AF)(e),{type:s,payload:{thing:e,shown:t}}}function p(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return e=(0,n.AF)(e),{type:i,payload:{thing:e,mode:t}}}},26821:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>s});var n=r(5672),o=r(25474),a=r(4400),i=r(28989);function s(){return{statePlugins:{layout:{reducers:n.default,actions:o,selectors:a},spec:{wrapSelectors:i}}}}},5672:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>s});var n=r(39022),o=r.n(n),a=r(43393),i=r(25474);const s={[i.UPDATE_LAYOUT]:(e,t)=>e.set("layout",t.payload),[i.UPDATE_FILTER]:(e,t)=>e.set("filter",t.payload),[i.SHOW]:(e,t)=>{const r=t.payload.shown,n=(0,a.fromJS)(t.payload.thing);return e.update("shown",(0,a.fromJS)({}),(e=>e.set(n,r)))},[i.UPDATE_MODE]:(e,t)=>{var r;let n=t.payload.thing,a=t.payload.mode;return e.setIn(o()(r=["modes"]).call(r,n),(a||"")+"")}}},4400:(e,t,r)=>{"use strict";r.r(t),r.d(t,{current:()=>i,currentFilter:()=>s,isShown:()=>l,whatMode:()=>u,showSummary:()=>c});var n=r(20573),o=r(90242),a=r(43393);const i=e=>e.get("layout"),s=e=>e.get("filter"),l=(e,t,r)=>(t=(0,o.AF)(t),e.get("shown",(0,a.fromJS)({})).get((0,a.fromJS)(t),r)),u=function(e,t){let r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";return t=(0,o.AF)(t),e.getIn(["modes",...t],r)},c=(0,n.P1)((e=>e),(e=>!l(e,"editor")))},28989:(e,t,r)=>{"use strict";r.r(t),r.d(t,{taggedOperations:()=>a});var n=r(24278),o=r.n(n);const a=(e,t)=>function(r){for(var n=arguments.length,a=new Array(n>1?n-1:0),i=1;i=0&&(s=o()(s).call(s,0,f)),s}},9150:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>a});var n=r(11189),o=r.n(n);function a(e){let{configs:t}=e;const r={debug:0,info:1,log:2,warn:3,error:4},n=e=>r[e]||-1;let{logLevel:a}=t,i=n(a);function s(e){for(var t=arguments.length,r=new Array(t>1?t-1:0),o=1;o=i&&console[e](...r)}return s.warn=o()(s).call(s,null,"warn"),s.error=o()(s).call(s,null,"error"),s.info=o()(s).call(s,null,"info"),s.debug=o()(s).call(s,null,"debug"),{rootInjects:{log:s}}}},67002:(e,t,r)=>{"use strict";r.r(t),r.d(t,{UPDATE_SELECTED_SERVER:()=>n,UPDATE_REQUEST_BODY_VALUE:()=>o,UPDATE_REQUEST_BODY_VALUE_RETAIN_FLAG:()=>a,UPDATE_REQUEST_BODY_INCLUSION:()=>i,UPDATE_ACTIVE_EXAMPLES_MEMBER:()=>s,UPDATE_REQUEST_CONTENT_TYPE:()=>l,UPDATE_RESPONSE_CONTENT_TYPE:()=>u,UPDATE_SERVER_VARIABLE_VALUE:()=>c,SET_REQUEST_BODY_VALIDATE_ERROR:()=>p,CLEAR_REQUEST_BODY_VALIDATE_ERROR:()=>f,CLEAR_REQUEST_BODY_VALUE:()=>h,setSelectedServer:()=>d,setRequestBodyValue:()=>m,setRetainRequestBodyValueFlag:()=>g,setRequestBodyInclusion:()=>v,setActiveExamplesMember:()=>y,setRequestContentType:()=>b,setResponseContentType:()=>w,setServerVariableValue:()=>E,setRequestBodyValidateError:()=>x,clearRequestBodyValidateError:()=>_,initRequestBodyValidateError:()=>S,clearRequestBodyValue:()=>A});const n="oas3_set_servers",o="oas3_set_request_body_value",a="oas3_set_request_body_retain_flag",i="oas3_set_request_body_inclusion",s="oas3_set_active_examples_member",l="oas3_set_request_content_type",u="oas3_set_response_content_type",c="oas3_set_server_variable_value",p="oas3_set_request_body_validate_error",f="oas3_clear_request_body_validate_error",h="oas3_clear_request_body_value";function d(e,t){return{type:n,payload:{selectedServerUrl:e,namespace:t}}}function m(e){let{value:t,pathMethod:r}=e;return{type:o,payload:{value:t,pathMethod:r}}}const g=e=>{let{value:t,pathMethod:r}=e;return{type:a,payload:{value:t,pathMethod:r}}};function v(e){let{value:t,pathMethod:r,name:n}=e;return{type:i,payload:{value:t,pathMethod:r,name:n}}}function y(e){let{name:t,pathMethod:r,contextType:n,contextName:o}=e;return{type:s,payload:{name:t,pathMethod:r,contextType:n,contextName:o}}}function b(e){let{value:t,pathMethod:r}=e;return{type:l,payload:{value:t,pathMethod:r}}}function w(e){let{value:t,path:r,method:n}=e;return{type:u,payload:{value:t,path:r,method:n}}}function E(e){let{server:t,namespace:r,key:n,val:o}=e;return{type:c,payload:{server:t,namespace:r,key:n,val:o}}}const x=e=>{let{path:t,method:r,validationErrors:n}=e;return{type:p,payload:{path:t,method:r,validationErrors:n}}},_=e=>{let{path:t,method:r}=e;return{type:f,payload:{path:t,method:r}}},S=e=>{let{pathMethod:t}=e;return{type:f,payload:{path:t[0],method:t[1]}}},A=e=>{let{pathMethod:t}=e;return{type:h,payload:{pathMethod:t}}}},73723:(e,t,r)=>{"use strict";r.r(t),r.d(t,{definitionsToAuthorize:()=>f});var n=r(86),o=r.n(n),a=r(14418),i=r.n(a),s=r(24282),l=r.n(s),u=r(20573),c=r(43393),p=r(7779);const f=(h=(0,u.P1)((e=>e),(e=>{let{specSelectors:t}=e;return t.securityDefinitions()}),((e,t)=>{var r;let n=(0,c.List)();return t?(o()(r=t.entrySeq()).call(r,(e=>{let[t,r]=e;const a=r.get("type");var s;if("oauth2"===a&&o()(s=r.get("flows").entrySeq()).call(s,(e=>{let[o,a]=e,s=(0,c.fromJS)({flow:o,authorizationUrl:a.get("authorizationUrl"),tokenUrl:a.get("tokenUrl"),scopes:a.get("scopes"),type:r.get("type"),description:r.get("description")});n=n.push(new c.Map({[t]:i()(s).call(s,(e=>void 0!==e))}))})),"http"!==a&&"apiKey"!==a||(n=n.push(new c.Map({[t]:r}))),"openIdConnect"===a&&r.get("openIdConnectData")){let e=r.get("openIdConnectData"),a=e.get("grant_types_supported")||["authorization_code","implicit"];o()(a).call(a,(o=>{var a;let s=e.get("scopes_supported")&&l()(a=e.get("scopes_supported")).call(a,((e,t)=>e.set(t,"")),new c.Map),u=(0,c.fromJS)({flow:o,authorizationUrl:e.get("authorization_endpoint"),tokenUrl:e.get("token_endpoint"),scopes:s,type:"oauth2",openIdConnectUrl:r.get("openIdConnectUrl")});n=n.push(new c.Map({[t]:i()(u).call(u,(e=>void 0!==e))}))}))}})),n):n})),(e,t)=>function(){const r=t.getSystem().specSelectors.specJson();for(var n=arguments.length,o=new Array(n),a=0;a{"use strict";r.r(t),r.d(t,{default:()=>u});var n=r(23101),o=r.n(n),a=r(97606),i=r.n(a),s=r(67294),l=(r(23930),r(43393));const u=e=>{var t;let{callbacks:r,getComponent:n,specPath:a}=e;const u=n("OperationContainer",!0);if(!r)return s.createElement("span",null,"No callbacks");let c=i()(t=r.entrySeq()).call(t,(t=>{var r;let[n,c]=t;return s.createElement("div",{key:n},s.createElement("h2",null,n),i()(r=c.entrySeq()).call(r,(t=>{var r;let[c,p]=t;return"$$ref"===c?null:s.createElement("div",{key:c},i()(r=p.entrySeq()).call(r,(t=>{let[r,i]=t;if("$$ref"===r)return null;let p=(0,l.fromJS)({operation:i});return s.createElement(u,o()({},e,{op:p,key:r,tag:"",method:r,path:c,specPath:a.push(n,c,r),allowTryItOut:!1}))})))})))}));return s.createElement("div",null,c)}},86775:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>f});var n=r(61125),o=r.n(n),a=r(76986),i=r.n(a),s=r(14418),l=r.n(s),u=r(97606),c=r.n(u),p=r(67294);class f extends p.Component{constructor(e,t){super(e,t),o()(this,"onChange",(e=>{let{onChange:t}=this.props,{value:r,name:n}=e.target,o=i()({},this.state.value);n?o[n]=r:o=r,this.setState({value:o},(()=>t(this.state)))}));let{name:r,schema:n}=this.props,a=this.getValue();this.state={name:r,schema:n,value:a}}getValue(){let{name:e,authorized:t}=this.props;return t&&t.getIn([e,"value"])}render(){var e;let{schema:t,getComponent:r,errSelectors:n,name:o}=this.props;const a=r("Input"),i=r("Row"),s=r("Col"),u=r("authError"),f=r("Markdown",!0),h=r("JumpToPath",!0),d=(t.get("scheme")||"").toLowerCase();let m=this.getValue(),g=l()(e=n.allErrors()).call(e,(e=>e.get("authId")===o));if("basic"===d){var v;let e=m?m.get("username"):null;return p.createElement("div",null,p.createElement("h4",null,p.createElement("code",null,o||t.get("name")),"  (http, Basic)",p.createElement(h,{path:["securityDefinitions",o]})),e&&p.createElement("h6",null,"Authorized"),p.createElement(i,null,p.createElement(f,{source:t.get("description")})),p.createElement(i,null,p.createElement("label",null,"Username:"),e?p.createElement("code",null," ",e," "):p.createElement(s,null,p.createElement(a,{type:"text",required:"required",name:"username","aria-label":"auth-basic-username",onChange:this.onChange,autoFocus:!0}))),p.createElement(i,null,p.createElement("label",null,"Password:"),e?p.createElement("code",null," ****** "):p.createElement(s,null,p.createElement(a,{autoComplete:"new-password",name:"password",type:"password","aria-label":"auth-basic-password",onChange:this.onChange}))),c()(v=g.valueSeq()).call(v,((e,t)=>p.createElement(u,{error:e,key:t}))))}var y;return"bearer"===d?p.createElement("div",null,p.createElement("h4",null,p.createElement("code",null,o||t.get("name")),"  (http, Bearer)",p.createElement(h,{path:["securityDefinitions",o]})),m&&p.createElement("h6",null,"Authorized"),p.createElement(i,null,p.createElement(f,{source:t.get("description")})),p.createElement(i,null,p.createElement("label",null,"Value:"),m?p.createElement("code",null," ****** "):p.createElement(s,null,p.createElement(a,{type:"text","aria-label":"auth-bearer-value",onChange:this.onChange,autoFocus:!0}))),c()(y=g.valueSeq()).call(y,((e,t)=>p.createElement(u,{error:e,key:t})))):p.createElement("div",null,p.createElement("em",null,p.createElement("b",null,o)," HTTP authentication: unsupported scheme ",`'${d}'`))}}},76467:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>p});var n=r(33427),o=r(42458),a=r(15757),i=r(56617),s=r(9928),l=r(45327),u=r(86775),c=r(96796);const p={Callbacks:n.default,HttpAuth:u.default,RequestBody:o.default,Servers:i.default,ServersContainer:s.default,RequestBodyEditor:l.default,OperationServers:c.default,operationLink:a.default}},15757:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>u});var n=r(35627),o=r.n(n),a=r(97606),i=r.n(a),s=r(67294);r(23930);class l extends s.Component{render(){const{link:e,name:t,getComponent:r}=this.props,n=r("Markdown",!0);let a=e.get("operationId")||e.get("operationRef"),l=e.get("parameters")&&e.get("parameters").toJS(),u=e.get("description");return s.createElement("div",{className:"operation-link"},s.createElement("div",{className:"description"},s.createElement("b",null,s.createElement("code",null,t)),u?s.createElement(n,{source:u}):null),s.createElement("pre",null,"Operation `",a,"`",s.createElement("br",null),s.createElement("br",null),"Parameters ",function(e,t){var r;if("string"!=typeof t)return"";return i()(r=t.split("\n")).call(r,((t,r)=>r>0?Array(e+1).join(" ")+t:t)).join("\n")}(0,o()(l,null,2))||"{}",s.createElement("br",null)))}}const u=l},96796:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>i});var n=r(61125),o=r.n(n),a=r(67294);r(23930);class i extends a.Component{constructor(){super(...arguments),o()(this,"setSelectedServer",(e=>{const{path:t,method:r}=this.props;return this.forceUpdate(),this.props.setSelectedServer(e,`${t}:${r}`)})),o()(this,"setServerVariableValue",(e=>{const{path:t,method:r}=this.props;return this.forceUpdate(),this.props.setServerVariableValue({...e,namespace:`${t}:${r}`})})),o()(this,"getSelectedServer",(()=>{const{path:e,method:t}=this.props;return this.props.getSelectedServer(`${e}:${t}`)})),o()(this,"getServerVariable",((e,t)=>{const{path:r,method:n}=this.props;return this.props.getServerVariable({namespace:`${r}:${n}`,server:e},t)})),o()(this,"getEffectiveServerValue",(e=>{const{path:t,method:r}=this.props;return this.props.getEffectiveServerValue({server:e,namespace:`${t}:${r}`})}))}render(){const{operationServers:e,pathServers:t,getComponent:r}=this.props;if(!e&&!t)return null;const n=r("Servers"),o=e||t,i=e?"operation":"path";return a.createElement("div",{className:"opblock-section operation-servers"},a.createElement("div",{className:"opblock-section-header"},a.createElement("div",{className:"tab-header"},a.createElement("h4",{className:"opblock-title"},"Servers"))),a.createElement("div",{className:"opblock-description-wrapper"},a.createElement("h4",{className:"message"},"These ",i,"-level options override the global server options."),a.createElement(n,{servers:o,currentServer:this.getSelectedServer(),setSelectedServer:this.setSelectedServer,setServerVariableValue:this.setServerVariableValue,getServerVariable:this.getServerVariable,getEffectiveServerValue:this.getEffectiveServerValue})))}}},45327:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>c});var n=r(61125),o=r.n(n),a=r(67294),i=r(94184),s=r.n(i),l=r(90242);const u=Function.prototype;class c extends a.PureComponent{constructor(e,t){super(e,t),o()(this,"applyDefaultValue",(e=>{const{onChange:t,defaultValue:r}=e||this.props;return this.setState({value:r}),t(r)})),o()(this,"onChange",(e=>{this.props.onChange((0,l.Pz)(e))})),o()(this,"onDomChange",(e=>{const t=e.target.value;this.setState({value:t},(()=>this.onChange(t)))})),this.state={value:(0,l.Pz)(e.value)||e.defaultValue},e.onChange(e.value)}UNSAFE_componentWillReceiveProps(e){this.props.value!==e.value&&e.value!==this.state.value&&this.setState({value:(0,l.Pz)(e.value)}),!e.value&&e.defaultValue&&this.state.value&&this.applyDefaultValue(e)}render(){let{getComponent:e,errors:t}=this.props,{value:r}=this.state,n=t.size>0;const o=e("TextArea");return a.createElement("div",{className:"body-param"},a.createElement(o,{className:s()("body-param__text",{invalid:n}),title:t.size?t.join(", "):"",value:r,onChange:this.onDomChange}))}}o()(c,"defaultProps",{onChange:u,userHasEditedBody:!1})},42458:(e,t,r)=>{"use strict";r.r(t),r.d(t,{getDefaultRequestBodyValue:()=>m,default:()=>g});var n=r(97606),o=r.n(n),a=r(11882),i=r.n(a),s=r(58118),l=r.n(s),u=r(58309),c=r.n(u),p=r(67294),f=(r(23930),r(43393)),h=r(90242),d=r(2518);const m=(e,t,r)=>{const n=e.getIn(["content",t]),o=n.get("schema").toJS(),a=void 0!==n.get("examples"),i=n.get("example"),s=a?n.getIn(["examples",r,"value"]):i,l=(0,h.xi)(o,t,{includeWriteOnly:!0},s);return(0,h.Pz)(l)},g=e=>{let{userHasEditedBody:t,requestBody:r,requestBodyValue:n,requestBodyInclusionSetting:a,requestBodyErrors:s,getComponent:u,getConfigs:g,specSelectors:v,fn:y,contentType:b,isExecute:w,specPath:E,onChange:x,onChangeIncludeEmpty:_,activeExamplesKey:S,updateActiveExamplesKey:A,setRetainRequestBodyValueFlag:k}=e;const C=e=>{x(e.target.files[0])},O=e=>{let t={key:e,shouldDispatchInit:!1,defaultValue:!0};return"no value"===a.get(e,"no value")&&(t.shouldDispatchInit=!0),t},j=u("Markdown",!0),I=u("modelExample"),N=u("RequestBodyEditor"),T=u("highlightCode"),P=u("ExamplesSelectValueRetainer"),R=u("Example"),M=u("ParameterIncludeEmpty"),{showCommonExtensions:D}=g(),L=r&&r.get("description")||null,B=r&&r.get("content")||new f.OrderedMap;b=b||B.keySeq().first()||"";const F=B.get(b,(0,f.OrderedMap)()),z=F.get("schema",(0,f.OrderedMap)()),U=F.get("examples",null),q=null==U?void 0:o()(U).call(U,((e,t)=>{var n;const o=null===(n=e)||void 0===n?void 0:n.get("value",null);return o&&(e=e.set("value",m(r,b,t),o)),e}));if(s=f.List.isList(s)?s:(0,f.List)(),!F.size)return null;const V="object"===F.getIn(["schema","type"]),$="binary"===F.getIn(["schema","format"]),W="base64"===F.getIn(["schema","format"]);if("application/octet-stream"===b||0===i()(b).call(b,"image/")||0===i()(b).call(b,"audio/")||0===i()(b).call(b,"video/")||$||W){const e=u("Input");return w?p.createElement(e,{type:"file",onChange:C}):p.createElement("i",null,"Example values are not available for ",p.createElement("code",null,b)," media types.")}if(V&&("application/x-www-form-urlencoded"===b||0===i()(b).call(b,"multipart/"))&&z.get("properties",(0,f.OrderedMap)()).size>0){var H;const e=u("JsonSchemaForm"),t=u("ParameterExt"),r=z.get("properties",(0,f.OrderedMap)());return n=f.Map.isMap(n)?n:(0,f.OrderedMap)(),p.createElement("div",{className:"table-container"},L&&p.createElement(j,{source:L}),p.createElement("table",null,p.createElement("tbody",null,f.Map.isMap(r)&&o()(H=r.entrySeq()).call(H,(r=>{var i,d;let[m,g]=r;if(g.get("readOnly"))return;let v=D?(0,h.po)(g):null;const b=l()(i=z.get("required",(0,f.List)())).call(i,m),E=g.get("type"),S=g.get("format"),A=g.get("description"),k=n.getIn([m,"value"]),C=n.getIn([m,"errors"])||s,I=a.get(m)||!1,N=g.has("default")||g.has("example")||g.hasIn(["items","example"])||g.hasIn(["items","default"]),T=g.has("enum")&&(1===g.get("enum").size||b),P=N||T;let R="";"array"!==E||P||(R=[]),("object"===E||P)&&(R=(0,h.xi)(g,!1,{includeWriteOnly:!0})),"string"!=typeof R&&"object"===E&&(R=(0,h.Pz)(R)),"string"==typeof R&&"array"===E&&(R=JSON.parse(R));const L="string"===E&&("binary"===S||"base64"===S);return p.createElement("tr",{key:m,className:"parameters","data-property-name":m},p.createElement("td",{className:"parameters-col_name"},p.createElement("div",{className:b?"parameter__name required":"parameter__name"},m,b?p.createElement("span",null," *"):null),p.createElement("div",{className:"parameter__type"},E,S&&p.createElement("span",{className:"prop-format"},"($",S,")"),D&&v.size?o()(d=v.entrySeq()).call(d,(e=>{let[r,n]=e;return p.createElement(t,{key:`${r}-${n}`,xKey:r,xVal:n})})):null),p.createElement("div",{className:"parameter__deprecated"},g.get("deprecated")?"deprecated":null)),p.createElement("td",{className:"parameters-col_description"},p.createElement(j,{source:A}),w?p.createElement("div",null,p.createElement(e,{fn:y,dispatchInitialValue:!L,schema:g,description:m,getComponent:u,value:void 0===k?R:k,required:b,errors:C,onChange:e=>{x(e,[m])}}),b?null:p.createElement(M,{onChange:e=>_(m,e),isIncluded:I,isIncludedOptions:O(m),isDisabled:c()(k)?0!==k.length:!(0,h.O2)(k)})):null))})))))}const J=m(r,b,S);let K=null;return(0,d.O)(J)&&(K="json"),p.createElement("div",null,L&&p.createElement(j,{source:L}),q?p.createElement(P,{userHasEditedBody:t,examples:q,currentKey:S,currentUserInputValue:n,onSelect:e=>{A(e)},updateValue:x,defaultToFirstExample:!0,getComponent:u,setRetainRequestBodyValueFlag:k}):null,w?p.createElement("div",null,p.createElement(N,{value:n,errors:s,defaultValue:J,onChange:x,getComponent:u})):p.createElement(I,{getComponent:u,getConfigs:g,specSelectors:v,expandDepth:1,isExecute:w,schema:F.get("schema"),specPath:E.push("content",b),example:p.createElement(T,{className:"body-param__example",getConfigs:g,language:K,value:(0,h.Pz)(n)||J}),includeWriteOnly:!0}),q?p.createElement(R,{example:q.get(S),getComponent:u,getConfigs:g}):null)}},9928:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>o});var n=r(67294);class o extends n.Component{render(){const{specSelectors:e,oas3Selectors:t,oas3Actions:r,getComponent:o}=this.props,a=e.servers(),i=o("Servers");return a&&a.size?n.createElement("div",null,n.createElement("span",{className:"servers-title"},"Servers"),n.createElement(i,{servers:a,currentServer:t.selectedServer(),setSelectedServer:r.setSelectedServer,setServerVariableValue:r.setServerVariableValue,getServerVariable:t.serverVariableValue,getEffectiveServerValue:t.serverEffectiveValue})):null}}},56617:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>p});var n=r(61125),o=r.n(n),a=r(51679),i=r.n(a),s=r(97606),l=r.n(s),u=r(67294),c=r(43393);r(23930);class p extends u.Component{constructor(){super(...arguments),o()(this,"onServerChange",(e=>{this.setServer(e.target.value)})),o()(this,"onServerVariableValueChange",(e=>{let{setServerVariableValue:t,currentServer:r}=this.props,n=e.target.getAttribute("data-variable"),o=e.target.value;"function"==typeof t&&t({server:r,key:n,val:o})})),o()(this,"setServer",(e=>{let{setSelectedServer:t}=this.props;t(e)}))}componentDidMount(){var e;let{servers:t,currentServer:r}=this.props;r||this.setServer(null===(e=t.first())||void 0===e?void 0:e.get("url"))}UNSAFE_componentWillReceiveProps(e){let{servers:t,setServerVariableValue:r,getServerVariable:n}=e;if(this.props.currentServer!==e.currentServer||this.props.servers!==e.servers){var o;let a=i()(t).call(t,(t=>t.get("url")===e.currentServer)),s=i()(o=this.props.servers).call(o,(e=>e.get("url")===this.props.currentServer))||(0,c.OrderedMap)();if(!a)return this.setServer(t.first().get("url"));let u=s.get("variables")||(0,c.OrderedMap)(),p=(i()(u).call(u,(e=>e.get("default")))||(0,c.OrderedMap)()).get("default"),f=a.get("variables")||(0,c.OrderedMap)(),h=(i()(f).call(f,(e=>e.get("default")))||(0,c.OrderedMap)()).get("default");l()(f).call(f,((t,o)=>{n(e.currentServer,o)&&p===h||r({server:e.currentServer,key:o,val:t.get("default")||""})}))}}render(){var e,t;let{servers:r,currentServer:n,getServerVariable:o,getEffectiveServerValue:a}=this.props,s=(i()(r).call(r,(e=>e.get("url")===n))||(0,c.OrderedMap)()).get("variables")||(0,c.OrderedMap)(),p=0!==s.size;return u.createElement("div",{className:"servers"},u.createElement("label",{htmlFor:"servers"},u.createElement("select",{onChange:this.onServerChange,value:n},l()(e=r.valueSeq()).call(e,(e=>u.createElement("option",{value:e.get("url"),key:e.get("url")},e.get("url"),e.get("description")&&` - ${e.get("description")}`))).toArray())),p?u.createElement("div",null,u.createElement("div",{className:"computed-url"},"Computed URL:",u.createElement("code",null,a(n))),u.createElement("h4",null,"Server variables"),u.createElement("table",null,u.createElement("tbody",null,l()(t=s.entrySeq()).call(t,(e=>{var t;let[r,a]=e;return u.createElement("tr",{key:r},u.createElement("td",null,r),u.createElement("td",null,a.get("enum")?u.createElement("select",{"data-variable":r,onChange:this.onServerVariableValueChange},l()(t=a.get("enum")).call(t,(e=>u.createElement("option",{selected:e===o(n,r),key:e,value:e},e)))):u.createElement("input",{type:"text",value:o(n,r)||"",onChange:this.onServerVariableValueChange,"data-variable":r})))}))))):null)}}},7779:(e,t,r)=>{"use strict";r.r(t),r.d(t,{isOAS3:()=>l,isSwagger2:()=>u,OAS3ComponentWrapFactory:()=>c});var n=r(23101),o=r.n(n),a=r(27043),i=r.n(a),s=r(67294);function l(e){const t=e.get("openapi");return"string"==typeof t&&(i()(t).call(t,"3.0.")&&t.length>4)}function u(e){const t=e.get("swagger");return"string"==typeof t&&i()(t).call(t,"2.0")}function c(e){return(t,r)=>n=>{if(r&&r.specSelectors&&r.specSelectors.specJson){return l(r.specSelectors.specJson())?s.createElement(e,o()({},n,r,{Ori:t})):s.createElement(t,n)}return console.warn("OAS3 wrapper: couldn't get spec"),null}}},97451:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>p});var n=r(92044),o=r(73723),a=r(91741),i=r(76467),s=r(37761),l=r(67002),u=r(5065),c=r(62109);function p(){return{components:i.default,wrapComponents:s.default,statePlugins:{spec:{wrapSelectors:n,selectors:a},auth:{wrapSelectors:o},oas3:{actions:l,reducers:c.default,selectors:u}}}}},62109:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>p});var n=r(8712),o=r.n(n),a=r(86),i=r.n(a),s=r(24282),l=r.n(s),u=r(43393),c=r(67002);const p={[c.UPDATE_SELECTED_SERVER]:(e,t)=>{let{payload:{selectedServerUrl:r,namespace:n}}=t;const o=n?[n,"selectedServer"]:["selectedServer"];return e.setIn(o,r)},[c.UPDATE_REQUEST_BODY_VALUE]:(e,t)=>{let{payload:{value:r,pathMethod:n}}=t,[a,s]=n;if(!u.Map.isMap(r))return e.setIn(["requestData",a,s,"bodyValue"],r);let l,c=e.getIn(["requestData",a,s,"bodyValue"])||(0,u.Map)();u.Map.isMap(c)||(c=(0,u.Map)());const[...p]=o()(r).call(r);return i()(p).call(p,(e=>{let t=r.getIn([e]);c.has(e)&&u.Map.isMap(t)||(l=c.setIn([e,"value"],t))})),e.setIn(["requestData",a,s,"bodyValue"],l)},[c.UPDATE_REQUEST_BODY_VALUE_RETAIN_FLAG]:(e,t)=>{let{payload:{value:r,pathMethod:n}}=t,[o,a]=n;return e.setIn(["requestData",o,a,"retainBodyValue"],r)},[c.UPDATE_REQUEST_BODY_INCLUSION]:(e,t)=>{let{payload:{value:r,pathMethod:n,name:o}}=t,[a,i]=n;return e.setIn(["requestData",a,i,"bodyInclusion",o],r)},[c.UPDATE_ACTIVE_EXAMPLES_MEMBER]:(e,t)=>{let{payload:{name:r,pathMethod:n,contextType:o,contextName:a}}=t,[i,s]=n;return e.setIn(["examples",i,s,o,a,"activeExample"],r)},[c.UPDATE_REQUEST_CONTENT_TYPE]:(e,t)=>{let{payload:{value:r,pathMethod:n}}=t,[o,a]=n;return e.setIn(["requestData",o,a,"requestContentType"],r)},[c.UPDATE_RESPONSE_CONTENT_TYPE]:(e,t)=>{let{payload:{value:r,path:n,method:o}}=t;return e.setIn(["requestData",n,o,"responseContentType"],r)},[c.UPDATE_SERVER_VARIABLE_VALUE]:(e,t)=>{let{payload:{server:r,namespace:n,key:o,val:a}}=t;const i=n?[n,"serverVariableValues",r,o]:["serverVariableValues",r,o];return e.setIn(i,a)},[c.SET_REQUEST_BODY_VALIDATE_ERROR]:(e,t)=>{let{payload:{path:r,method:n,validationErrors:o}}=t,a=[];if(a.push("Required field is not provided"),o.missingBodyValue)return e.setIn(["requestData",r,n,"errors"],(0,u.fromJS)(a));if(o.missingRequiredKeys&&o.missingRequiredKeys.length>0){const{missingRequiredKeys:t}=o;return e.updateIn(["requestData",r,n,"bodyValue"],(0,u.fromJS)({}),(e=>l()(t).call(t,((e,t)=>e.setIn([t,"errors"],(0,u.fromJS)(a))),e)))}return console.warn("unexpected result: SET_REQUEST_BODY_VALIDATE_ERROR"),e},[c.CLEAR_REQUEST_BODY_VALIDATE_ERROR]:(e,t)=>{let{payload:{path:r,method:n}}=t;const a=e.getIn(["requestData",r,n,"bodyValue"]);if(!u.Map.isMap(a))return e.setIn(["requestData",r,n,"errors"],(0,u.fromJS)([]));const[...i]=o()(a).call(a);return i?e.updateIn(["requestData",r,n,"bodyValue"],(0,u.fromJS)({}),(e=>l()(i).call(i,((e,t)=>e.setIn([t,"errors"],(0,u.fromJS)([]))),e))):e},[c.CLEAR_REQUEST_BODY_VALUE]:(e,t)=>{let{payload:{pathMethod:r}}=t,[n,o]=r;const a=e.getIn(["requestData",n,o,"bodyValue"]);return a?u.Map.isMap(a)?e.setIn(["requestData",n,o,"bodyValue"],(0,u.Map)()):e.setIn(["requestData",n,o,"bodyValue"],""):e}}},5065:(e,t,r)=>{"use strict";r.r(t),r.d(t,{selectedServer:()=>g,requestBodyValue:()=>v,shouldRetainRequestBodyValue:()=>y,hasUserEditedBody:()=>b,requestBodyInclusionSetting:()=>w,requestBodyErrors:()=>E,activeExamplesMember:()=>x,requestContentType:()=>_,responseContentType:()=>S,serverVariableValue:()=>A,serverVariables:()=>k,serverEffectiveValue:()=>C,validateBeforeExecute:()=>O,validateShallowRequired:()=>I});var n=r(97606),o=r.n(n),a=r(86),i=r.n(a),s=r(28222),l=r.n(s),u=r(11882),c=r.n(u),p=r(43393),f=r(7779),h=r(42458),d=r(90242);function m(e){return function(){for(var t=arguments.length,r=new Array(t),n=0;n{const n=t.getSystem().specSelectors.specJson();return(0,f.isOAS3)(n)?e(...r):null}}}const g=m(((e,t)=>{const r=t?[t,"selectedServer"]:["selectedServer"];return e.getIn(r)||""})),v=m(((e,t,r)=>e.getIn(["requestData",t,r,"bodyValue"])||null)),y=m(((e,t,r)=>e.getIn(["requestData",t,r,"retainBodyValue"])||!1)),b=(e,t,r)=>e=>{const{oas3Selectors:n,specSelectors:o}=e.getSystem(),a=o.specJson();if((0,f.isOAS3)(a)){let e=!1;const a=n.requestContentType(t,r);let i=n.requestBodyValue(t,r);if(p.Map.isMap(i)&&(i=(0,d.Pz)(i.mapEntries((e=>p.Map.isMap(e[1])?[e[0],e[1].get("value")]:e)).toJS())),p.List.isList(i)&&(i=(0,d.Pz)(i)),a){const s=(0,h.getDefaultRequestBodyValue)(o.specResolvedSubtree(["paths",t,r,"requestBody"]),a,n.activeExamplesMember(t,r,"requestBody","requestBody"));e=!!i&&i!==s}return e}return null},w=m(((e,t,r)=>e.getIn(["requestData",t,r,"bodyInclusion"])||(0,p.Map)())),E=m(((e,t,r)=>e.getIn(["requestData",t,r,"errors"])||null)),x=m(((e,t,r,n,o)=>e.getIn(["examples",t,r,n,o,"activeExample"])||null)),_=m(((e,t,r)=>e.getIn(["requestData",t,r,"requestContentType"])||null)),S=m(((e,t,r)=>e.getIn(["requestData",t,r,"responseContentType"])||null)),A=m(((e,t,r)=>{let n;if("string"!=typeof t){const{server:e,namespace:o}=t;n=o?[o,"serverVariableValues",e,r]:["serverVariableValues",e,r]}else{n=["serverVariableValues",t,r]}return e.getIn(n)||null})),k=m(((e,t)=>{let r;if("string"!=typeof t){const{server:e,namespace:n}=t;r=n?[n,"serverVariableValues",e]:["serverVariableValues",e]}else{r=["serverVariableValues",t]}return e.getIn(r)||(0,p.OrderedMap)()})),C=m(((e,t)=>{var r,n;if("string"!=typeof t){const{server:o,namespace:a}=t;n=o,r=a?e.getIn([a,"serverVariableValues",n]):e.getIn(["serverVariableValues",n])}else n=t,r=e.getIn(["serverVariableValues",n]);r=r||(0,p.OrderedMap)();let a=n;return o()(r).call(r,((e,t)=>{a=a.replace(new RegExp(`{${t}}`,"g"),e)})),a})),O=(j=(e,t)=>((e,t)=>(t=t||[],!!e.getIn(["requestData",...t,"bodyValue"])))(e,t),function(){for(var e=arguments.length,t=new Array(e),r=0;r{const r=e.getSystem().specSelectors.specJson();let n=[...t][1]||[];return!r.getIn(["paths",...n,"requestBody","required"])||j(...t)}});var j;const I=(e,t)=>{var r;let{oas3RequiredRequestBodyContentType:n,oas3RequestContentType:o,oas3RequestBodyValue:a}=t,s=[];if(!p.Map.isMap(a))return s;let u=[];return i()(r=l()(n.requestContentType)).call(r,(e=>{if(e===o){let t=n.requestContentType[e];i()(t).call(t,(e=>{c()(u).call(u,e)<0&&u.push(e)}))}})),i()(u).call(u,(e=>{a.getIn([e,"value"])||s.push(e)})),s}},91741:(e,t,r)=>{"use strict";r.r(t),r.d(t,{servers:()=>u,isSwagger2:()=>p});var n=r(20573),o=r(43393),a=r(7779);const i=e=>e||(0,o.Map)(),s=(0,n.P1)(i,(e=>e.get("json",(0,o.Map)()))),l=(0,n.P1)(i,(e=>e.get("resolved",(0,o.Map)()))),u=(c=(0,n.P1)((e=>{let t=l(e);return t.count()<1&&(t=s(e)),t}),(e=>e.getIn(["servers"])||(0,o.Map)())),()=>function(e){const t=e.getSystem().specSelectors.specJson();if((0,a.isOAS3)(t)){for(var r=arguments.length,n=new Array(r>1?r-1:0),o=1;o()=>{const e=t.getSystem().specSelectors.specJson();return(0,a.isSwagger2)(e)}},92044:(e,t,r)=>{"use strict";r.r(t),r.d(t,{definitions:()=>h,hasHost:()=>d,securityDefinitions:()=>m,host:()=>g,basePath:()=>v,consumes:()=>y,produces:()=>b,schemes:()=>w,servers:()=>E,isOAS3:()=>x,isSwagger2:()=>_});var n=r(20573),o=r(33881),a=r(43393),i=r(7779);function s(e){return(t,r)=>function(){const n=r.getSystem().specSelectors.specJson();return(0,i.isOAS3)(n)?e(...arguments):t(...arguments)}}const l=e=>e||(0,a.Map)(),u=s((0,n.P1)((()=>null))),c=(0,n.P1)(l,(e=>e.get("json",(0,a.Map)()))),p=(0,n.P1)(l,(e=>e.get("resolved",(0,a.Map)()))),f=e=>{let t=p(e);return t.count()<1&&(t=c(e)),t},h=s((0,n.P1)(f,(e=>{const t=e.getIn(["components","schemas"]);return a.Map.isMap(t)?t:(0,a.Map)()}))),d=s((e=>f(e).hasIn(["servers",0]))),m=s((0,n.P1)(o.specJsonWithResolvedSubtrees,(e=>e.getIn(["components","securitySchemes"])||null))),g=u,v=u,y=u,b=u,w=u,E=s((0,n.P1)(f,(e=>e.getIn(["servers"])||(0,a.Map)()))),x=(e,t)=>()=>{const e=t.getSystem().specSelectors.specJson();return(0,i.isOAS3)(a.Map.isMap(e)?e:(0,a.Map)())},_=(e,t)=>()=>{const e=t.getSystem().specSelectors.specJson();return(0,i.isSwagger2)(a.Map.isMap(e)?e:(0,a.Map)())}},70356:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>o});var n=r(67294);const o=(0,r(7779).OAS3ComponentWrapFactory)((e=>{let{Ori:t,...r}=e;const{schema:o,getComponent:a,errSelectors:i,authorized:s,onAuthChange:l,name:u}=r,c=a("HttpAuth");return"http"===o.get("type")?n.createElement(c,{key:u,schema:o,name:u,errSelectors:i,authorized:s,getComponent:a,onChange:l}):n.createElement(t,r)}))},37761:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>u});var n=r(22460),o=r(70356),a=r(69487),i=r(50058),s=r(53499),l=r(90287);const u={Markdown:n.default,AuthItem:o.default,JsonSchema_string:l.default,VersionStamp:a.default,model:s.default,onlineValidatorBadge:i.default}},90287:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>o});var n=r(67294);const o=(0,r(7779).OAS3ComponentWrapFactory)((e=>{let{Ori:t,...r}=e;const{schema:o,getComponent:a,errors:i,onChange:s}=r,l=o&&o.get?o.get("format"):null,u=o&&o.get?o.get("type"):null,c=a("Input");return u&&"string"===u&&l&&("binary"===l||"base64"===l)?n.createElement(c,{type:"file",className:i.length?"invalid":"",title:i.length?i:"",onChange:e=>{s(e.target.files[0])},disabled:t.isDisabled}):n.createElement(t,r)}))},22460:(e,t,r)=>{"use strict";r.r(t),r.d(t,{Markdown:()=>f,default:()=>h});var n=r(81607),o=r.n(n),a=r(67294),i=r(94184),s=r.n(i),l=r(89927),u=r(7779),c=r(86019);const p=new l._("commonmark");p.block.ruler.enable(["table"]),p.set({linkTarget:"_blank"});const f=e=>{let{source:t,className:r="",getConfigs:n}=e;if("string"!=typeof t)return null;if(t){const{useUnsafeMarkdown:e}=n(),i=p.render(t),l=(0,c.s)(i,{useUnsafeMarkdown:e});let u;return"string"==typeof l&&(u=o()(l).call(l)),a.createElement("div",{dangerouslySetInnerHTML:{__html:u},className:s()(r,"renderedMarkdown")})}return null};f.defaultProps={getConfigs:()=>({useUnsafeMarkdown:!1})};const h=(0,u.OAS3ComponentWrapFactory)(f)},53499:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>u});var n=r(23101),o=r.n(n),a=r(67294),i=r(7779),s=r(53795);class l extends a.Component{render(){let{getConfigs:e,schema:t}=this.props,r=["model-box"],n=null;return!0===t.get("deprecated")&&(r.push("deprecated"),n=a.createElement("span",{className:"model-deprecated-warning"},"Deprecated:")),a.createElement("div",{className:r.join(" ")},n,a.createElement(s.Z,o()({},this.props,{getConfigs:e,depth:1,expandDepth:this.props.expandDepth||0})))}}const u=(0,i.OAS3ComponentWrapFactory)(l)},50058:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>a});var n=r(7779),o=r(5623);const a=(0,n.OAS3ComponentWrapFactory)(o.Z)},69487:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>o});var n=r(67294);const o=(0,r(7779).OAS3ComponentWrapFactory)((e=>{const{Ori:t}=e;return n.createElement("span",null,n.createElement(t,e),n.createElement("small",{className:"version-stamp"},n.createElement("pre",{className:"version"},"OAS3")))}))},28560:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>i});var n=r(87198),o=r.n(n);let a=!1;function i(){return{statePlugins:{spec:{wrapActions:{updateSpec:e=>function(){return a=!0,e(...arguments)},updateJsonSpec:(e,t)=>function(){const r=t.getConfigs().onComplete;return a&&"function"==typeof r&&(o()(r,0),a=!1),e(...arguments)}}}}}}},92135:(e,t,r)=>{"use strict";r.r(t),r.d(t,{requestSnippetGenerator_curl_powershell:()=>A,requestSnippetGenerator_curl_bash:()=>k,requestSnippetGenerator_curl_cmd:()=>C});var n=r(11882),o=r.n(n),a=r(81607),i=r.n(a),s=r(35627),l=r.n(s),u=r(97606),c=r.n(u),p=r(12196),f=r.n(p),h=r(74386),d=r.n(h),m=r(58118),g=r.n(m),v=r(27504),y=r(43393);const b=e=>{var t;const r="_**[]";return o()(e).call(e,r)<0?e:i()(t=e.split(r)[0]).call(t)},w=e=>"-d "===e||/^[_\/-]/g.test(e)?e:"'"+e.replace(/'/g,"'\\''")+"'",E=e=>"-d "===(e=e.replace(/\^/g,"^^").replace(/\\"/g,'\\\\"').replace(/"/g,'""').replace(/\n/g,"^\n"))?e.replace(/-d /g,"-d ^\n"):/^[_\/-]/g.test(e)?e:'"'+e+'"',x=e=>"-d "===e?e:/\n/.test(e)?'@"\n'+e.replace(/"/g,'\\"').replace(/`/g,"``").replace(/\$/,"`$")+'\n"@':/^[_\/-]/g.test(e)?e:"'"+e.replace(/"/g,'""').replace(/'/g,"''")+"'";function _(e){let t=[];for(let[r,n]of e.get("body").entrySeq()){let e=b(r);n instanceof v.Z.File?t.push(` "${e}": {\n "name": "${n.name}"${n.type?`,\n "type": "${n.type}"`:""}\n }`):t.push(` "${e}": ${l()(n,null,2).replace(/(\r\n|\r|\n)/g,"\n ")}`)}return`{\n${t.join(",\n")}\n}`}const S=function(e,t,r){let n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"",o=!1,a="";const i=function(){for(var e=arguments.length,r=new Array(e),n=0;na+=` ${r}`,p=function(){var e;let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1;return a+=f()(e=" ").call(e,t)};let h=e.get("headers");if(a+="curl"+n,e.has("curlOptions")&&i(...e.get("curlOptions")),i("-X",e.get("method")),u(),p(),s(`${e.get("url")}`),h&&h.size)for(let t of d()(m=e.get("headers")).call(m)){var m;u(),p();let[e,r]=t;s("-H",`${e}: ${r}`),o=o||/^content-type$/i.test(e)&&/^multipart\/form-data$/i.test(r)}const w=e.get("body");var E;if(w)if(o&&g()(E=["POST","PUT","PATCH"]).call(E,e.get("method")))for(let[e,t]of w.entrySeq()){let r=b(e);u(),p(),s("-F"),t instanceof v.Z.File?i(`${r}=@${t.name}${t.type?`;type=${t.type}`:""}`):i(`${r}=${t}`)}else if(w instanceof v.Z.File)u(),p(),s(`--data-binary '@${w.name}'`);else{u(),p(),s("-d ");let t=w;y.Map.isMap(t)?s(_(e)):("string"!=typeof t&&(t=l()(t)),s(t))}else w||"POST"!==e.get("method")||(u(),p(),s("-d ''"));return a},A=e=>S(e,x,"`\n",".exe"),k=e=>S(e,w,"\\\n"),C=e=>S(e,E,"^\n")},86575:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>i});var n=r(92135),o=r(4669),a=r(84206);const i=()=>({components:{RequestSnippets:a.default},fn:n,statePlugins:{requestSnippets:{selectors:o}}})},84206:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>w});var n=r(14418),o=r.n(n),a=r(25110),i=r.n(a),s=r(86),l=r.n(s),u=r(97606),c=r.n(u),p=r(67294),f=r(27361),h=r.n(f),d=r(23560),m=r.n(d),g=r(74855),v=r(36581);const y={cursor:"pointer",lineHeight:1,display:"inline-flex",backgroundColor:"rgb(250, 250, 250)",paddingBottom:"0",paddingTop:"0",border:"1px solid rgb(51, 51, 51)",borderRadius:"4px 4px 0 0",boxShadow:"none",borderBottom:"none"},b={cursor:"pointer",lineHeight:1,display:"inline-flex",backgroundColor:"rgb(51, 51, 51)",boxShadow:"none",border:"1px solid rgb(51, 51, 51)",paddingBottom:"0",paddingTop:"0",borderRadius:"4px 4px 0 0",marginTop:"-5px",marginRight:"-5px",marginLeft:"-5px",zIndex:"9999",borderBottom:"none"},w=e=>{var t,r;let{request:n,requestSnippetsSelectors:a,getConfigs:s}=e;const u=m()(s)?s():null,f=!1!==h()(u,"syntaxHighlight")&&h()(u,"syntaxHighlight.activated",!0),d=(0,p.useRef)(null),[w,E]=(0,p.useState)(null===(t=a.getSnippetGenerators())||void 0===t?void 0:t.keySeq().first()),[x,_]=(0,p.useState)(null==a?void 0:a.getDefaultExpanded());(0,p.useEffect)((()=>{}),[]),(0,p.useEffect)((()=>{var e;const t=o()(e=i()(d.current.childNodes)).call(e,(e=>{var t;return!!e.nodeType&&(null===(t=e.classList)||void 0===t?void 0:t.contains("curl-command"))}));return l()(t).call(t,(e=>e.addEventListener("mousewheel",j,{passive:!1}))),()=>{l()(t).call(t,(e=>e.removeEventListener("mousewheel",j)))}}),[n]);const S=a.getSnippetGenerators(),A=S.get(w),k=A.get("fn")(n),C=()=>{_(!x)},O=e=>e===w?b:y,j=e=>{const{target:t,deltaY:r}=e,{scrollHeight:n,offsetHeight:o,scrollTop:a}=t;n>o&&(0===a&&r<0||o+a>=n&&r>0)&&e.preventDefault()},I=f?p.createElement(v.d3,{language:A.get("syntax"),className:"curl microlight",style:(0,v.C2)(h()(u,"syntaxHighlight.theme"))},k):p.createElement("textarea",{readOnly:!0,className:"curl",value:k});return p.createElement("div",{className:"request-snippets",ref:d},p.createElement("div",{style:{width:"100%",display:"flex",justifyContent:"flex-start",alignItems:"center",marginBottom:"15px"}},p.createElement("h4",{onClick:()=>C(),style:{cursor:"pointer"}},"Snippets"),p.createElement("button",{onClick:()=>C(),style:{border:"none",background:"none"},title:x?"Collapse operation":"Expand operation"},p.createElement("svg",{className:"arrow",width:"10",height:"10"},p.createElement("use",{href:x?"#large-arrow-down":"#large-arrow",xlinkHref:x?"#large-arrow-down":"#large-arrow"})))),x&&p.createElement("div",{className:"curl-command"},p.createElement("div",{style:{paddingLeft:"15px",paddingRight:"10px",width:"100%",display:"flex"}},c()(r=S.entrySeq()).call(r,(e=>{let[t,r]=e;return p.createElement("div",{style:O(t),className:"btn",key:t,onClick:()=>(e=>{w!==e&&E(e)})(t)},p.createElement("h4",{style:t===w?{color:"white"}:{}},r.get("title")))}))),p.createElement("div",{className:"copy-to-clipboard"},p.createElement(g.CopyToClipboard,{text:k},p.createElement("button",null))),p.createElement("div",null,I)))}},4669:(e,t,r)=>{"use strict";r.r(t),r.d(t,{getGenerators:()=>f,getSnippetGenerators:()=>h,getActiveLanguage:()=>d,getDefaultExpanded:()=>m});var n=r(14418),o=r.n(n),a=r(58118),i=r.n(a),s=r(97606),l=r.n(s),u=r(20573),c=r(43393);const p=e=>e||(0,c.Map)(),f=(0,u.P1)(p,(e=>{const t=e.get("languages"),r=e.get("generators",(0,c.Map)());return!t||t.isEmpty()?r:o()(r).call(r,((e,r)=>i()(t).call(t,r)))})),h=e=>t=>{var r,n;let{fn:a}=t;return o()(r=l()(n=f(e)).call(n,((e,t)=>{const r=(e=>a[`requestSnippetGenerator_${e}`])(t);return"function"!=typeof r?null:e.set("fn",r)}))).call(r,(e=>e))},d=(0,u.P1)(p,(e=>e.get("activeLanguage"))),m=(0,u.P1)(p,(e=>e.get("defaultExpanded")))},36195:(e,t,r)=>{"use strict";r.r(t),r.d(t,{ErrorBoundary:()=>i,default:()=>s});var n=r(67294),o=r(56189),a=r(29403);class i extends n.Component{static getDerivedStateFromError(e){return{hasError:!0,error:e}}constructor(){super(...arguments),this.state={hasError:!1,error:null}}componentDidCatch(e,t){this.props.fn.componentDidCatch(e,t)}render(){const{getComponent:e,targetName:t,children:r}=this.props;if(this.state.hasError){const r=e("Fallback");return n.createElement(r,{name:t})}return r}}i.defaultProps={targetName:"this component",getComponent:()=>a.default,fn:{componentDidCatch:o.componentDidCatch},children:null};const s=i},29403:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>o});var n=r(67294);const o=e=>{let{name:t}=e;return n.createElement("div",{className:"fallback"},"😱 ",n.createElement("i",null,"Could not render ","t"===t?"this component":t,", see the console."))}},56189:(e,t,r)=>{"use strict";r.r(t),r.d(t,{componentDidCatch:()=>i,withErrorBoundary:()=>s});var n=r(23101),o=r.n(n),a=r(67294);const i=console.error,s=e=>t=>{const{getComponent:r,fn:n}=e(),i=r("ErrorBoundary"),s=n.getDisplayName(t);class l extends a.Component{render(){return a.createElement(i,{targetName:s,getComponent:r,fn:n},a.createElement(t,o()({},this.props,this.context)))}}var u;return l.displayName=`WithErrorBoundary(${s})`,(u=t).prototype&&u.prototype.isReactComponent&&(l.prototype.mapStateToProps=t.prototype.mapStateToProps),l}},27621:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>c});var n=r(47475),o=r.n(n),a=r(7287),i=r.n(a),s=r(36195),l=r(29403),u=r(56189);const c=function(){let{componentList:e=[],fullOverride:t=!1}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return r=>{var n;let{getSystem:a}=r;const c=t?e:["App","BaseLayout","VersionPragmaFilter","InfoContainer","ServersContainer","SchemesContainer","AuthorizeBtnContainer","FilterContainer","Operations","OperationContainer","parameters","responses","OperationServers","Models","ModelWrapper",...e],p=i()(c,o()(n=Array(c.length)).call(n,((e,t)=>{let{fn:r}=t;return r.withErrorBoundary(e)})));return{fn:{componentDidCatch:u.componentDidCatch,withErrorBoundary:(0,u.withErrorBoundary)(a)},components:{ErrorBoundary:s.default,Fallback:l.default},wrapComponents:p}}}},57050:(e,t,r)=>{"use strict";r.r(t),r.d(t,{sampleFromSchemaGeneric:()=>F,inferSchema:()=>z,createXMLExample:()=>U,sampleFromSchema:()=>q,memoizedCreateXMLExample:()=>$,memoizedSampleFromSchema:()=>W});var n=r(11882),o=r.n(n),a=r(86),i=r.n(a),s=r(58309),l=r.n(s),u=r(58118),c=r.n(u),p=r(92039),f=r.n(p),h=r(24278),d=r.n(h),m=r(51679),g=r.n(m),v=r(39022),y=r.n(v),b=r(97606),w=r.n(b),E=r(35627),x=r.n(E),_=r(53479),S=r.n(_),A=r(14419),k=r.n(A),C=r(41609),O=r.n(C),j=r(90242),I=r(60314);const N={string:e=>e.pattern?(e=>{try{return new(k())(e).gen()}catch(e){return"string"}})(e.pattern):"string",string_email:()=>"user@example.com","string_date-time":()=>(new Date).toISOString(),string_date:()=>(new Date).toISOString().substring(0,10),string_uuid:()=>"3fa85f64-5717-4562-b3fc-2c963f66afa6",string_hostname:()=>"example.com",string_ipv4:()=>"198.51.100.42",string_ipv6:()=>"2001:0db8:5b96:0000:0000:426f:8e17:642a",number:()=>0,number_float:()=>0,integer:()=>0,boolean:e=>"boolean"!=typeof e.default||e.default},T=e=>{e=(0,j.mz)(e);let{type:t,format:r}=e,n=N[`${t}_${r}`]||N[t];return(0,j.Wl)(n)?n(e):"Unknown Type: "+e.type},P=e=>(0,j.XV)(e,"$$ref",(e=>"string"==typeof e&&o()(e).call(e,"#")>-1)),R=["maxProperties","minProperties"],M=["minItems","maxItems"],D=["minimum","maximum","exclusiveMinimum","exclusiveMaximum"],L=["minLength","maxLength"],B=function(e,t){var r;let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const a=r=>{void 0===t[r]&&void 0!==e[r]&&(t[r]=e[r])};var s;(i()(r=["example","default","enum","xml","type",...R,...M,...D,...L]).call(r,(e=>a(e))),void 0!==e.required&&l()(e.required))&&(void 0!==t.required&&t.required.length||(t.required=[]),i()(s=e.required).call(s,(e=>{var r;c()(r=t.required).call(r,e)||t.required.push(e)})));if(e.properties){t.properties||(t.properties={});let r=(0,j.mz)(e.properties);for(let a in r){var u;if(Object.prototype.hasOwnProperty.call(r,a))if(!r[a]||!r[a].deprecated)if(!r[a]||!r[a].readOnly||n.includeReadOnly)if(!r[a]||!r[a].writeOnly||n.includeWriteOnly)if(!t.properties[a])t.properties[a]=r[a],!e.required&&l()(e.required)&&-1!==o()(u=e.required).call(u,a)&&(t.required?t.required.push(a):t.required=[a])}}return e.items&&(t.items||(t.items={}),t.items=B(e.items,t.items,n)),t},F=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0,n=arguments.length>3&&void 0!==arguments[3]&&arguments[3];e&&(0,j.Wl)(e.toJS)&&(e=e.toJS());let a=void 0!==r||e&&void 0!==e.example||e&&void 0!==e.default;const s=!a&&e&&e.oneOf&&e.oneOf.length>0,u=!a&&e&&e.anyOf&&e.anyOf.length>0;if(!a&&(s||u)){const r=(0,j.mz)(s?e.oneOf[0]:e.anyOf[0]);if(B(r,e,t),!e.xml&&r.xml&&(e.xml=r.xml),void 0!==e.example&&void 0!==r.example)a=!0;else if(r.properties){e.properties||(e.properties={});let n=(0,j.mz)(r.properties);for(let a in n){var p;if(Object.prototype.hasOwnProperty.call(n,a))if(!n[a]||!n[a].deprecated)if(!n[a]||!n[a].readOnly||t.includeReadOnly)if(!n[a]||!n[a].writeOnly||t.includeWriteOnly)if(!e.properties[a])e.properties[a]=n[a],!r.required&&l()(r.required)&&-1!==o()(p=r.required).call(p,a)&&(e.required?e.required.push(a):e.required=[a])}}}const h={};let{xml:m,type:v,example:b,properties:E,additionalProperties:x,items:_}=e||{},{includeReadOnly:S,includeWriteOnly:A}=t;m=m||{};let k,{name:C,prefix:I,namespace:N}=m,L={};if(n&&(C=C||"notagname",k=(I?I+":":"")+C,N)){h[I?"xmlns:"+I:"xmlns"]=N}n&&(L[k]=[]);const z=t=>f()(t).call(t,(t=>Object.prototype.hasOwnProperty.call(e,t)));e&&!v&&(E||x||z(R)?v="object":_||z(M)?v="array":z(D)?(v="number",e.type="number"):a||e.enum||(v="string",e.type="string"));const U=t=>{var r,n,o,a,i;null!==(null===(r=e)||void 0===r?void 0:r.maxItems)&&void 0!==(null===(n=e)||void 0===n?void 0:n.maxItems)&&(t=d()(t).call(t,0,null===(i=e)||void 0===i?void 0:i.maxItems));if(null!==(null===(o=e)||void 0===o?void 0:o.minItems)&&void 0!==(null===(a=e)||void 0===a?void 0:a.minItems)){let r=0;for(;t.length<(null===(s=e)||void 0===s?void 0:s.minItems);){var s;t.push(t[r++%t.length])}}return t},q=(0,j.mz)(E);let V,$=0;const W=()=>e&&null!==e.maxProperties&&void 0!==e.maxProperties&&$>=e.maxProperties,H=()=>{if(!e||!e.required)return 0;let t=0;var r,o;n?i()(r=e.required).call(r,(e=>t+=void 0===L[e]?0:1)):i()(o=e.required).call(o,(e=>{var r;return t+=void 0===(null===(r=L[k])||void 0===r?void 0:g()(r).call(r,(t=>void 0!==t[e])))?0:1}));return e.required.length-t},J=t=>{var r;return!(e&&e.required&&e.required.length)||!c()(r=e.required).call(r,t)},K=t=>!e||null===e.maxProperties||void 0===e.maxProperties||!W()&&(!J(t)||e.maxProperties-$-H()>0);if(V=n?function(r){let o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:void 0;if(e&&q[r]){if(q[r].xml=q[r].xml||{},q[r].xml.attribute){const e=l()(q[r].enum)?q[r].enum[0]:void 0,t=q[r].example,n=q[r].default;return void(h[q[r].xml.name||r]=void 0!==t?t:void 0!==n?n:void 0!==e?e:T(q[r]))}q[r].xml.name=q[r].xml.name||r}else q[r]||!1===x||(q[r]={xml:{name:r}});let a=F(e&&q[r]||void 0,t,o,n);var i;K(r)&&($++,l()(a)?L[k]=y()(i=L[k]).call(i,a):L[k].push(a))}:(e,r)=>{K(e)&&(L[e]=F(q[e],t,r,n),$++)},a){let o;if(o=P(void 0!==r?r:void 0!==b?b:e.default),!n){if("number"==typeof o&&"string"===v)return`${o}`;if("string"!=typeof o||"string"===v)return o;try{return JSON.parse(o)}catch(e){return o}}if(e||(v=l()(o)?"array":typeof o),"array"===v){if(!l()(o)){if("string"==typeof o)return o;o=[o]}const r=e?e.items:void 0;r&&(r.xml=r.xml||m||{},r.xml.name=r.xml.name||m.name);let a=w()(o).call(o,(e=>F(r,t,e,n)));return a=U(a),m.wrapped?(L[k]=a,O()(h)||L[k].push({_attr:h})):L=a,L}if("object"===v){if("string"==typeof o)return o;for(let t in o)Object.prototype.hasOwnProperty.call(o,t)&&(e&&q[t]&&q[t].readOnly&&!S||e&&q[t]&&q[t].writeOnly&&!A||(e&&q[t]&&q[t].xml&&q[t].xml.attribute?h[q[t].xml.name||t]=o[t]:V(t,o[t])));return O()(h)||L[k].push({_attr:h}),L}return L[k]=O()(h)?o:[{_attr:h},o],L}if("object"===v){for(let e in q)Object.prototype.hasOwnProperty.call(q,e)&&(q[e]&&q[e].deprecated||q[e]&&q[e].readOnly&&!S||q[e]&&q[e].writeOnly&&!A||V(e));if(n&&h&&L[k].push({_attr:h}),W())return L;if(!0===x)n?L[k].push({additionalProp:"Anything can be here"}):L.additionalProp1={},$++;else if(x){const r=(0,j.mz)(x),o=F(r,t,void 0,n);if(n&&r.xml&&r.xml.name&&"notagname"!==r.xml.name)L[k].push(o);else{const t=null!==e.minProperties&&void 0!==e.minProperties&&$F(B(_,e,t),t,void 0,n)));else if(l()(_.oneOf)){var Y;r=w()(Y=_.oneOf).call(Y,(e=>F(B(_,e,t),t,void 0,n)))}else{if(!(!n||n&&m.wrapped))return F(_,t,void 0,n);r=[F(_,t,void 0,n)]}return r=U(r),n&&m.wrapped?(L[k]=r,O()(h)||L[k].push({_attr:h}),L):r}let Q;if(e&&l()(e.enum))Q=(0,j.AF)(e.enum)[0];else{if(!e)return;if(Q=T(e),"number"==typeof Q){let t=e.minimum;null!=t&&(e.exclusiveMinimum&&t++,Q=t);let r=e.maximum;null!=r&&(e.exclusiveMaximum&&r--,Q=r)}if("string"==typeof Q&&(null!==e.maxLength&&void 0!==e.maxLength&&(Q=d()(Q).call(Q,0,e.maxLength)),null!==e.minLength&&void 0!==e.minLength)){let t=0;for(;Q.length(e.schema&&(e=e.schema),e.properties&&(e.type="object"),e),U=(e,t,r)=>{const n=F(e,t,r,!0);if(n)return"string"==typeof n?n:S()(n,{declaration:!0,indent:"\t"})},q=(e,t,r)=>F(e,t,r,!1),V=(e,t,r)=>[e,x()(t),x()(r)],$=(0,I.Z)(U,V),W=(0,I.Z)(q,V)},8883:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>o});var n=r(57050);function o(){return{fn:n}}},51228:(e,t,r)=>{"use strict";r.r(t),r.d(t,{UPDATE_SPEC:()=>U,UPDATE_URL:()=>q,UPDATE_JSON:()=>V,UPDATE_PARAM:()=>$,UPDATE_EMPTY_PARAM_INCLUSION:()=>W,VALIDATE_PARAMS:()=>H,SET_RESPONSE:()=>J,SET_REQUEST:()=>K,SET_MUTATED_REQUEST:()=>G,LOG_REQUEST:()=>Z,CLEAR_RESPONSE:()=>Y,CLEAR_REQUEST:()=>Q,CLEAR_VALIDATE_PARAMS:()=>X,UPDATE_OPERATION_META_VALUE:()=>ee,UPDATE_RESOLVED:()=>te,UPDATE_RESOLVED_SUBTREE:()=>re,SET_SCHEME:()=>ne,updateSpec:()=>oe,updateResolved:()=>ae,updateUrl:()=>ie,updateJsonSpec:()=>se,parseToJson:()=>le,resolveSpec:()=>ce,requestResolvedSubtree:()=>he,changeParam:()=>de,changeParamByIdentity:()=>me,updateResolvedSubtree:()=>ge,invalidateResolvedSubtreeCache:()=>ve,validateParams:()=>ye,updateEmptyParamInclusion:()=>be,clearValidateParams:()=>we,changeConsumesValue:()=>Ee,changeProducesValue:()=>xe,setResponse:()=>_e,setRequest:()=>Se,setMutatedRequest:()=>Ae,logRequest:()=>ke,executeRequest:()=>Ce,execute:()=>Oe,clearResponse:()=>je,clearRequest:()=>Ie,setScheme:()=>Ne});var n=r(58309),o=r.n(n),a=r(97606),i=r.n(a),s=r(96718),l=r.n(s),u=r(24282),c=r.n(u),p=r(2250),f=r.n(p),h=r(6226),d=r.n(h),m=r(14418),g=r.n(m),v=r(3665),y=r.n(v),b=r(11882),w=r.n(b),E=r(86),x=r.n(E),_=r(28222),S=r.n(_),A=r(76986),k=r.n(A),C=r(70586),O=r.n(C),j=r(1272),I=r(43393),N=r(84564),T=r.n(N),P=r(7710),R=r(47037),M=r.n(R),D=r(23279),L=r.n(D),B=r(36968),F=r.n(B),z=r(90242);const U="spec_update_spec",q="spec_update_url",V="spec_update_json",$="spec_update_param",W="spec_update_empty_param_inclusion",H="spec_validate_param",J="spec_set_response",K="spec_set_request",G="spec_set_mutated_request",Z="spec_log_request",Y="spec_clear_response",Q="spec_clear_request",X="spec_clear_validate_param",ee="spec_update_operation_meta_value",te="spec_update_resolved",re="spec_update_resolved_subtree",ne="set_scheme";function oe(e){const t=(r=e,M()(r)?r:"").replace(/\t/g," ");var r;if("string"==typeof e)return{type:U,payload:t}}function ae(e){return{type:te,payload:e}}function ie(e){return{type:q,payload:e}}function se(e){return{type:V,payload:e}}const le=e=>t=>{let{specActions:r,specSelectors:n,errActions:o}=t,{specStr:a}=n,i=null;try{e=e||a(),o.clear({source:"parser"}),i=j.ZP.load(e,{schema:j.A8})}catch(e){return console.error(e),o.newSpecErr({source:"parser",level:"error",message:e.reason,line:e.mark&&e.mark.line?e.mark.line+1:void 0})}return i&&"object"==typeof i?r.updateJsonSpec(i):{}};let ue=!1;const ce=(e,t)=>r=>{let{specActions:n,specSelectors:a,errActions:s,fn:{fetch:u,resolve:c,AST:p={}},getConfigs:f}=r;ue||(console.warn("specActions.resolveSpec is deprecated since v3.10.0 and will be removed in v4.0.0; use requestResolvedSubtree instead!"),ue=!0);const{modelPropertyMacro:h,parameterMacro:d,requestInterceptor:m,responseInterceptor:g}=f();void 0===e&&(e=a.specJson()),void 0===t&&(t=a.url());let v=p.getLineNumberForPath?p.getLineNumberForPath:()=>{},y=a.specStr();return c({fetch:u,spec:e,baseDoc:t,modelPropertyMacro:h,parameterMacro:d,requestInterceptor:m,responseInterceptor:g}).then((e=>{let{spec:t,errors:r}=e;if(s.clear({type:"thrown"}),o()(r)&&r.length>0){let e=i()(r).call(r,(e=>(console.error(e),e.line=e.fullPath?v(y,e.fullPath):null,e.path=e.fullPath?e.fullPath.join("."):null,e.level="error",e.type="thrown",e.source="resolver",l()(e,"message",{enumerable:!0,value:e.message}),e)));s.newThrownErrBatch(e)}return n.updateResolved(t)}))};let pe=[];const fe=L()((async()=>{const e=pe.system;if(!e)return void console.error("debResolveSubtrees: don't have a system to operate on, aborting.");const{errActions:t,errSelectors:r,fn:{resolveSubtree:n,fetch:a,AST:s={}},specSelectors:u,specActions:p}=e;if(!n)return void console.error("Error: Swagger-Client did not provide a `resolveSubtree` method, doing nothing.");let h=s.getLineNumberForPath?s.getLineNumberForPath:()=>{};const m=u.specStr(),{modelPropertyMacro:v,parameterMacro:b,requestInterceptor:w,responseInterceptor:E}=e.getConfigs();try{var x=await c()(pe).call(pe,(async(e,s)=>{const{resultMap:c,specWithCurrentSubtrees:p}=await e,{errors:x,spec:_}=await n(p,s,{baseDoc:u.url(),modelPropertyMacro:v,parameterMacro:b,requestInterceptor:w,responseInterceptor:E});if(r.allErrors().size&&t.clearBy((e=>{var t;return"thrown"!==e.get("type")||"resolver"!==e.get("source")||!f()(t=e.get("fullPath")).call(t,((e,t)=>e===s[t]||void 0===s[t]))})),o()(x)&&x.length>0){let e=i()(x).call(x,(e=>(e.line=e.fullPath?h(m,e.fullPath):null,e.path=e.fullPath?e.fullPath.join("."):null,e.level="error",e.type="thrown",e.source="resolver",l()(e,"message",{enumerable:!0,value:e.message}),e)));t.newThrownErrBatch(e)}var S,A;_&&u.isOAS3()&&"components"===s[0]&&"securitySchemes"===s[1]&&await d().all(i()(S=g()(A=y()(_)).call(A,(e=>"openIdConnect"===e.type))).call(S,(async e=>{const t={url:e.openIdConnectUrl,requestInterceptor:w,responseInterceptor:E};try{const r=await a(t);r instanceof Error||r.status>=400?console.error(r.statusText+" "+t.url):e.openIdConnectData=JSON.parse(r.text)}catch(e){console.error(e)}})));return F()(c,s,_),F()(p,s,_),{resultMap:c,specWithCurrentSubtrees:p}}),d().resolve({resultMap:(u.specResolvedSubtree([])||(0,I.Map)()).toJS(),specWithCurrentSubtrees:u.specJson().toJS()}));delete pe.system,pe=[]}catch(e){console.error(e)}p.updateResolvedSubtree([],x.resultMap)}),35),he=e=>t=>{var r;w()(r=i()(pe).call(pe,(e=>e.join("@@")))).call(r,e.join("@@"))>-1||(pe.push(e),pe.system=t,fe())};function de(e,t,r,n,o){return{type:$,payload:{path:e,value:n,paramName:t,paramIn:r,isXml:o}}}function me(e,t,r,n){return{type:$,payload:{path:e,param:t,value:r,isXml:n}}}const ge=(e,t)=>({type:re,payload:{path:e,value:t}}),ve=()=>({type:re,payload:{path:[],value:(0,I.Map)()}}),ye=(e,t)=>({type:H,payload:{pathMethod:e,isOAS3:t}}),be=(e,t,r,n)=>({type:W,payload:{pathMethod:e,paramName:t,paramIn:r,includeEmptyValue:n}});function we(e){return{type:X,payload:{pathMethod:e}}}function Ee(e,t){return{type:ee,payload:{path:e,value:t,key:"consumes_value"}}}function xe(e,t){return{type:ee,payload:{path:e,value:t,key:"produces_value"}}}const _e=(e,t,r)=>({payload:{path:e,method:t,res:r},type:J}),Se=(e,t,r)=>({payload:{path:e,method:t,req:r},type:K}),Ae=(e,t,r)=>({payload:{path:e,method:t,req:r},type:G}),ke=e=>({payload:e,type:Z}),Ce=e=>t=>{let{fn:r,specActions:n,specSelectors:a,getConfigs:s,oas3Selectors:l}=t,{pathName:u,method:c,operation:p}=e,{requestInterceptor:f,responseInterceptor:h}=s(),d=p.toJS();var m,v;p&&p.get("parameters")&&x()(m=g()(v=p.get("parameters")).call(v,(e=>e&&!0===e.get("allowEmptyValue")))).call(m,(t=>{if(a.parameterInclusionSettingFor([u,c],t.get("name"),t.get("in"))){e.parameters=e.parameters||{};const r=(0,z.cz)(t,e.parameters);(!r||r&&0===r.size)&&(e.parameters[t.get("name")]="")}}));if(e.contextUrl=T()(a.url()).toString(),d&&d.operationId?e.operationId=d.operationId:d&&u&&c&&(e.operationId=r.opId(d,u,c)),a.isOAS3()){const t=`${u}:${c}`;e.server=l.selectedServer(t)||l.selectedServer();const r=l.serverVariables({server:e.server,namespace:t}).toJS(),n=l.serverVariables({server:e.server}).toJS();e.serverVariables=S()(r).length?r:n,e.requestContentType=l.requestContentType(u,c),e.responseContentType=l.responseContentType(u,c)||"*/*";const a=l.requestBodyValue(u,c),s=l.requestBodyInclusionSetting(u,c);var y;if(a&&a.toJS)e.requestBody=g()(y=i()(a).call(a,(e=>I.Map.isMap(e)?e.get("value"):e))).call(y,((e,t)=>(o()(e)?0!==e.length:!(0,z.O2)(e))||s.get(t))).toJS();else e.requestBody=a}let b=k()({},e);b=r.buildRequest(b),n.setRequest(e.pathName,e.method,b);e.requestInterceptor=async t=>{let r=await f.apply(void 0,[t]),o=k()({},r);return n.setMutatedRequest(e.pathName,e.method,o),r},e.responseInterceptor=h;const w=O()();return r.execute(e).then((t=>{t.duration=O()()-w,n.setResponse(e.pathName,e.method,t)})).catch((t=>{"Failed to fetch"===t.message&&(t.name="",t.message='**Failed to fetch.** \n**Possible Reasons:** \n - CORS \n - Network Failure \n - URL scheme must be "http" or "https" for CORS request.'),n.setResponse(e.pathName,e.method,{error:!0,err:(0,P.serializeError)(t)})}))},Oe=function(){let{path:e,method:t,...r}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return n=>{let{fn:{fetch:o},specSelectors:a,specActions:i}=n,s=a.specJsonWithResolvedSubtrees().toJS(),l=a.operationScheme(e,t),{requestContentType:u,responseContentType:c}=a.contentTypeValues([e,t]).toJS(),p=/xml/i.test(u),f=a.parameterValues([e,t],p).toJS();return i.executeRequest({...r,fetch:o,spec:s,pathName:e,method:t,parameters:f,requestContentType:u,scheme:l,responseContentType:c})}};function je(e,t){return{type:Y,payload:{path:e,method:t}}}function Ie(e,t){return{type:Q,payload:{path:e,method:t}}}function Ne(e,t,r){return{type:ne,payload:{scheme:e,path:t,method:r}}}},37038:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>s});var n=r(20032),o=r(51228),a=r(33881),i=r(77508);function s(){return{statePlugins:{spec:{wrapActions:i,reducers:n.default,actions:o,selectors:a}}}}},20032:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>d});var n=r(24282),o=r.n(n),a=r(97606),i=r.n(a),s=r(76986),l=r.n(s),u=r(43393),c=r(90242),p=r(27504),f=r(33881),h=r(51228);const d={[h.UPDATE_SPEC]:(e,t)=>"string"==typeof t.payload?e.set("spec",t.payload):e,[h.UPDATE_URL]:(e,t)=>e.set("url",t.payload+""),[h.UPDATE_JSON]:(e,t)=>e.set("json",(0,c.oG)(t.payload)),[h.UPDATE_RESOLVED]:(e,t)=>e.setIn(["resolved"],(0,c.oG)(t.payload)),[h.UPDATE_RESOLVED_SUBTREE]:(e,t)=>{const{value:r,path:n}=t.payload;return e.setIn(["resolvedSubtrees",...n],(0,c.oG)(r))},[h.UPDATE_PARAM]:(e,t)=>{let{payload:r}=t,{path:n,paramName:o,paramIn:a,param:i,value:s,isXml:l}=r,u=i?(0,c.V9)(i):`${a}.${o}`;const p=l?"value_xml":"value";return e.setIn(["meta","paths",...n,"parameters",u,p],s)},[h.UPDATE_EMPTY_PARAM_INCLUSION]:(e,t)=>{let{payload:r}=t,{pathMethod:n,paramName:o,paramIn:a,includeEmptyValue:i}=r;if(!o||!a)return console.warn("Warning: UPDATE_EMPTY_PARAM_INCLUSION could not generate a paramKey."),e;const s=`${a}.${o}`;return e.setIn(["meta","paths",...n,"parameter_inclusions",s],i)},[h.VALIDATE_PARAMS]:(e,t)=>{let{payload:{pathMethod:r,isOAS3:n}}=t;const a=(0,f.specJsonWithResolvedSubtrees)(e).getIn(["paths",...r]),i=(0,f.parameterValues)(e,r).toJS();return e.updateIn(["meta","paths",...r,"parameters"],(0,u.fromJS)({}),(t=>{var s;return o()(s=a.get("parameters",(0,u.List)())).call(s,((t,o)=>{const a=(0,c.cz)(o,i),s=(0,f.parameterInclusionSettingFor)(e,r,o.get("name"),o.get("in")),l=(0,c.Ik)(o,a,{bypassRequiredCheck:s,isOAS3:n});return t.setIn([(0,c.V9)(o),"errors"],(0,u.fromJS)(l))}),t)}))},[h.CLEAR_VALIDATE_PARAMS]:(e,t)=>{let{payload:{pathMethod:r}}=t;return e.updateIn(["meta","paths",...r,"parameters"],(0,u.fromJS)([]),(e=>i()(e).call(e,(e=>e.set("errors",(0,u.fromJS)([]))))))},[h.SET_RESPONSE]:(e,t)=>{let r,{payload:{res:n,path:o,method:a}}=t;r=n.error?l()({error:!0,name:n.err.name,message:n.err.message,statusCode:n.err.statusCode},n.err.response):n,r.headers=r.headers||{};let i=e.setIn(["responses",o,a],(0,c.oG)(r));return p.Z.Blob&&n.data instanceof p.Z.Blob&&(i=i.setIn(["responses",o,a,"text"],n.data)),i},[h.SET_REQUEST]:(e,t)=>{let{payload:{req:r,path:n,method:o}}=t;return e.setIn(["requests",n,o],(0,c.oG)(r))},[h.SET_MUTATED_REQUEST]:(e,t)=>{let{payload:{req:r,path:n,method:o}}=t;return e.setIn(["mutatedRequests",n,o],(0,c.oG)(r))},[h.UPDATE_OPERATION_META_VALUE]:(e,t)=>{let{payload:{path:r,value:n,key:o}}=t,a=["paths",...r],i=["meta","paths",...r];return e.getIn(["json",...a])||e.getIn(["resolved",...a])||e.getIn(["resolvedSubtrees",...a])?e.setIn([...i,o],(0,u.fromJS)(n)):e},[h.CLEAR_RESPONSE]:(e,t)=>{let{payload:{path:r,method:n}}=t;return e.deleteIn(["responses",r,n])},[h.CLEAR_REQUEST]:(e,t)=>{let{payload:{path:r,method:n}}=t;return e.deleteIn(["requests",r,n])},[h.SET_SCHEME]:(e,t)=>{let{payload:{scheme:r,path:n,method:o}}=t;return n&&o?e.setIn(["scheme",n,o],r):n||o?void 0:e.setIn(["scheme","_defaultScheme"],r)}}},33881:(e,t,r)=>{"use strict";r.r(t),r.d(t,{lastError:()=>O,url:()=>j,specStr:()=>I,specSource:()=>N,specJson:()=>T,specResolved:()=>P,specResolvedSubtree:()=>R,specJsonWithResolvedSubtrees:()=>D,spec:()=>L,isOAS3:()=>B,info:()=>F,externalDocs:()=>z,version:()=>U,semver:()=>q,paths:()=>V,operations:()=>$,consumes:()=>W,produces:()=>H,security:()=>J,securityDefinitions:()=>K,findDefinition:()=>G,definitions:()=>Z,basePath:()=>Y,host:()=>Q,schemes:()=>X,operationsWithRootInherited:()=>ee,tags:()=>te,tagDetails:()=>re,operationsWithTags:()=>ne,taggedOperations:()=>oe,responses:()=>ae,requests:()=>ie,mutatedRequests:()=>se,responseFor:()=>le,requestFor:()=>ue,mutatedRequestFor:()=>ce,allowTryItOutFor:()=>pe,parameterWithMetaByIdentity:()=>fe,parameterInclusionSettingFor:()=>he,parameterWithMeta:()=>de,operationWithMeta:()=>me,getParameter:()=>ge,hasHost:()=>ve,parameterValues:()=>ye,parametersIncludeIn:()=>be,parametersIncludeType:()=>we,contentTypeValues:()=>Ee,currentProducesFor:()=>xe,producesOptionsFor:()=>_e,consumesOptionsFor:()=>Se,operationScheme:()=>Ae,canExecuteScheme:()=>ke,validateBeforeExecute:()=>Ce,getOAS3RequiredRequestBodyContentType:()=>Oe,isMediaTypeSchemaPropertiesEqual:()=>je});var n=r(24278),o=r.n(n),a=r(86),i=r.n(a),s=r(11882),l=r.n(s),u=r(97606),c=r.n(u),p=r(14418),f=r.n(p),h=r(51679),d=r.n(h),m=r(24282),g=r.n(m),v=r(2578),y=r.n(v),b=r(92039),w=r.n(b),E=r(58309),x=r.n(E),_=r(20573),S=r(90242),A=r(43393);const k=["get","put","post","delete","options","head","patch","trace"],C=e=>e||(0,A.Map)(),O=(0,_.P1)(C,(e=>e.get("lastError"))),j=(0,_.P1)(C,(e=>e.get("url"))),I=(0,_.P1)(C,(e=>e.get("spec")||"")),N=(0,_.P1)(C,(e=>e.get("specSource")||"not-editor")),T=(0,_.P1)(C,(e=>e.get("json",(0,A.Map)()))),P=(0,_.P1)(C,(e=>e.get("resolved",(0,A.Map)()))),R=(e,t)=>e.getIn(["resolvedSubtrees",...t],void 0),M=(e,t)=>A.Map.isMap(e)&&A.Map.isMap(t)?t.get("$$ref")?t:(0,A.OrderedMap)().mergeWith(M,e,t):t,D=(0,_.P1)(C,(e=>(0,A.OrderedMap)().mergeWith(M,e.get("json"),e.get("resolvedSubtrees")))),L=e=>T(e),B=(0,_.P1)(L,(()=>!1)),F=(0,_.P1)(L,(e=>Ie(e&&e.get("info")))),z=(0,_.P1)(L,(e=>Ie(e&&e.get("externalDocs")))),U=(0,_.P1)(F,(e=>e&&e.get("version"))),q=(0,_.P1)(U,(e=>{var t;return o()(t=/v?([0-9]*)\.([0-9]*)\.([0-9]*)/i.exec(e)).call(t,1)})),V=(0,_.P1)(D,(e=>e.get("paths"))),$=(0,_.P1)(V,(e=>{if(!e||e.size<1)return(0,A.List)();let t=(0,A.List)();return e&&i()(e)?(i()(e).call(e,((e,r)=>{if(!e||!i()(e))return{};i()(e).call(e,((e,n)=>{l()(k).call(k,n)<0||(t=t.push((0,A.fromJS)({path:r,method:n,operation:e,id:`${n}-${r}`})))}))})),t):(0,A.List)()})),W=(0,_.P1)(L,(e=>(0,A.Set)(e.get("consumes")))),H=(0,_.P1)(L,(e=>(0,A.Set)(e.get("produces")))),J=(0,_.P1)(L,(e=>e.get("security",(0,A.List)()))),K=(0,_.P1)(L,(e=>e.get("securityDefinitions"))),G=(e,t)=>{const r=e.getIn(["resolvedSubtrees","definitions",t],null),n=e.getIn(["json","definitions",t],null);return r||n||null},Z=(0,_.P1)(L,(e=>{const t=e.get("definitions");return A.Map.isMap(t)?t:(0,A.Map)()})),Y=(0,_.P1)(L,(e=>e.get("basePath"))),Q=(0,_.P1)(L,(e=>e.get("host"))),X=(0,_.P1)(L,(e=>e.get("schemes",(0,A.Map)()))),ee=(0,_.P1)($,W,H,((e,t,r)=>c()(e).call(e,(e=>e.update("operation",(e=>{if(e){if(!A.Map.isMap(e))return;return e.withMutations((e=>(e.get("consumes")||e.update("consumes",(e=>(0,A.Set)(e).merge(t))),e.get("produces")||e.update("produces",(e=>(0,A.Set)(e).merge(r))),e)))}return(0,A.Map)()})))))),te=(0,_.P1)(L,(e=>{const t=e.get("tags",(0,A.List)());return A.List.isList(t)?f()(t).call(t,(e=>A.Map.isMap(e))):(0,A.List)()})),re=(e,t)=>{var r;let n=te(e)||(0,A.List)();return d()(r=f()(n).call(n,A.Map.isMap)).call(r,(e=>e.get("name")===t),(0,A.Map)())},ne=(0,_.P1)(ee,te,((e,t)=>g()(e).call(e,((e,t)=>{let r=(0,A.Set)(t.getIn(["operation","tags"]));return r.count()<1?e.update("default",(0,A.List)(),(e=>e.push(t))):g()(r).call(r,((e,r)=>e.update(r,(0,A.List)(),(e=>e.push(t)))),e)}),g()(t).call(t,((e,t)=>e.set(t.get("name"),(0,A.List)())),(0,A.OrderedMap)())))),oe=e=>t=>{var r;let{getConfigs:n}=t,{tagsSorter:o,operationsSorter:a}=n();return c()(r=ne(e).sortBy(((e,t)=>t),((e,t)=>{let r="function"==typeof o?o:S.wh.tagsSorter[o];return r?r(e,t):null}))).call(r,((t,r)=>{let n="function"==typeof a?a:S.wh.operationsSorter[a],o=n?y()(t).call(t,n):t;return(0,A.Map)({tagDetails:re(e,r),operations:o})}))},ae=(0,_.P1)(C,(e=>e.get("responses",(0,A.Map)()))),ie=(0,_.P1)(C,(e=>e.get("requests",(0,A.Map)()))),se=(0,_.P1)(C,(e=>e.get("mutatedRequests",(0,A.Map)()))),le=(e,t,r)=>ae(e).getIn([t,r],null),ue=(e,t,r)=>ie(e).getIn([t,r],null),ce=(e,t,r)=>se(e).getIn([t,r],null),pe=()=>!0,fe=(e,t,r)=>{const n=D(e).getIn(["paths",...t,"parameters"],(0,A.OrderedMap)()),o=e.getIn(["meta","paths",...t,"parameters"],(0,A.OrderedMap)()),a=c()(n).call(n,(e=>{const t=o.get(`${r.get("in")}.${r.get("name")}`),n=o.get(`${r.get("in")}.${r.get("name")}.hash-${r.hashCode()}`);return(0,A.OrderedMap)().merge(e,t,n)}));return d()(a).call(a,(e=>e.get("in")===r.get("in")&&e.get("name")===r.get("name")),(0,A.OrderedMap)())},he=(e,t,r,n)=>{const o=`${n}.${r}`;return e.getIn(["meta","paths",...t,"parameter_inclusions",o],!1)},de=(e,t,r,n)=>{const o=D(e).getIn(["paths",...t,"parameters"],(0,A.OrderedMap)()),a=d()(o).call(o,(e=>e.get("in")===n&&e.get("name")===r),(0,A.OrderedMap)());return fe(e,t,a)},me=(e,t,r)=>{var n;const o=D(e).getIn(["paths",t,r],(0,A.OrderedMap)()),a=e.getIn(["meta","paths",t,r],(0,A.OrderedMap)()),i=c()(n=o.get("parameters",(0,A.List)())).call(n,(n=>fe(e,[t,r],n)));return(0,A.OrderedMap)().merge(o,a).set("parameters",i)};function ge(e,t,r,n){t=t||[];let o=e.getIn(["meta","paths",...t,"parameters"],(0,A.fromJS)([]));return d()(o).call(o,(e=>A.Map.isMap(e)&&e.get("name")===r&&e.get("in")===n))||(0,A.Map)()}const ve=(0,_.P1)(L,(e=>{const t=e.get("host");return"string"==typeof t&&t.length>0&&"/"!==t[0]}));function ye(e,t,r){t=t||[];let n=me(e,...t).get("parameters",(0,A.List)());return g()(n).call(n,((e,t)=>{let n=r&&"body"===t.get("in")?t.get("value_xml"):t.get("value");return e.set((0,S.V9)(t,{allowHashes:!1}),n)}),(0,A.fromJS)({}))}function be(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";if(A.List.isList(e))return w()(e).call(e,(e=>A.Map.isMap(e)&&e.get("in")===t))}function we(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";if(A.List.isList(e))return w()(e).call(e,(e=>A.Map.isMap(e)&&e.get("type")===t))}function Ee(e,t){t=t||[];let r=D(e).getIn(["paths",...t],(0,A.fromJS)({})),n=e.getIn(["meta","paths",...t],(0,A.fromJS)({})),o=xe(e,t);const a=r.get("parameters")||new A.List,i=n.get("consumes_value")?n.get("consumes_value"):we(a,"file")?"multipart/form-data":we(a,"formData")?"application/x-www-form-urlencoded":void 0;return(0,A.fromJS)({requestContentType:i,responseContentType:o})}function xe(e,t){t=t||[];const r=D(e).getIn(["paths",...t],null);if(null===r)return;const n=e.getIn(["meta","paths",...t,"produces_value"],null),o=r.getIn(["produces",0],null);return n||o||"application/json"}function _e(e,t){t=t||[];const r=D(e),n=r.getIn(["paths",...t],null);if(null===n)return;const[o]=t,a=n.get("produces",null),i=r.getIn(["paths",o,"produces"],null),s=r.getIn(["produces"],null);return a||i||s}function Se(e,t){t=t||[];const r=D(e),n=r.getIn(["paths",...t],null);if(null===n)return;const[o]=t,a=n.get("consumes",null),i=r.getIn(["paths",o,"consumes"],null),s=r.getIn(["consumes"],null);return a||i||s}const Ae=(e,t,r)=>{let n=e.get("url").match(/^([a-z][a-z0-9+\-.]*):/),o=x()(n)?n[1]:null;return e.getIn(["scheme",t,r])||e.getIn(["scheme","_defaultScheme"])||o||""},ke=(e,t,r)=>{var n;return l()(n=["http","https"]).call(n,Ae(e,t,r))>-1},Ce=(e,t)=>{t=t||[];let r=e.getIn(["meta","paths",...t,"parameters"],(0,A.fromJS)([])),n=!0;return i()(r).call(r,(e=>{let t=e.get("errors");t&&t.count()&&(n=!1)})),n},Oe=(e,t)=>{var r;let n={requestBody:!1,requestContentType:{}},o=e.getIn(["resolvedSubtrees","paths",...t,"requestBody"],(0,A.fromJS)([]));return o.size<1||(o.getIn(["required"])&&(n.requestBody=o.getIn(["required"])),i()(r=o.getIn(["content"]).entrySeq()).call(r,(e=>{const t=e[0];if(e[1].getIn(["schema","required"])){const r=e[1].getIn(["schema","required"]).toJS();n.requestContentType[t]=r}}))),n},je=(e,t,r,n)=>{if((r||n)&&r===n)return!0;let o=e.getIn(["resolvedSubtrees","paths",...t,"requestBody","content"],(0,A.fromJS)([]));if(o.size<2||!r||!n)return!1;let a=o.getIn([r,"schema","properties"],(0,A.fromJS)([])),i=o.getIn([n,"schema","properties"],(0,A.fromJS)([]));return!!a.equals(i)};function Ie(e){return A.Map.isMap(e)?e:new A.Map}},77508:(e,t,r)=>{"use strict";r.r(t),r.d(t,{updateSpec:()=>u,updateJsonSpec:()=>c,executeRequest:()=>p,validateParams:()=>f});var n=r(28222),o=r.n(n),a=r(86),i=r.n(a),s=r(27361),l=r.n(s);const u=(e,t)=>{let{specActions:r}=t;return function(){e(...arguments),r.parseToJson(...arguments)}},c=(e,t)=>{let{specActions:r}=t;return function(){for(var t=arguments.length,n=new Array(t),a=0;a{l()(u,[e]).$ref&&r.requestResolvedSubtree(["paths",e])})),r.requestResolvedSubtree(["components","securitySchemes"])}},p=(e,t)=>{let{specActions:r}=t;return t=>(r.logRequest(t),e(t))},f=(e,t)=>{let{specSelectors:r}=t;return t=>e(t,r.isOAS3())}},34852:(e,t,r)=>{"use strict";r.r(t),r.d(t,{loaded:()=>n});const n=(e,t)=>function(){e(...arguments);const r=t.getConfigs().withCredentials;void 0!==r&&(t.fn.fetch.withCredentials="string"==typeof r?"true"===r:!!r)}},48792:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>qr});var n={};r.r(n),r.d(n,{JsonPatchError:()=>Fe,_areEquals:()=>Ge,applyOperation:()=>$e,applyPatch:()=>We,applyReducer:()=>He,deepClone:()=>ze,getValueByPointer:()=>Ve,validate:()=>Ke,validator:()=>Je});var o={};r.r(o),r.d(o,{compare:()=>nt,generate:()=>tt,observe:()=>et,unobserve:()=>Xe});var a={};r.r(a),r.d(a,{cookie:()=>kr,header:()=>Ar,path:()=>xr,query:()=>_r});var i=r(80093),s=r.n(i),l=r(30222),u=r.n(l),c=r(36594),p=r.n(c),f=r(20474),h=r.n(f),d=r(67375),m=r.n(d),g=r(58118),v=r.n(g),y=r(74386),b=r.n(y),w=r(25110),E=r.n(w),x=r(35627),_=r.n(x),S=r(97606),A=r.n(S),k=r(28222),C=r.n(k),O=r(39022),j=r.n(O),I=r(2018),N=r.n(I),T=r(14418),P=r.n(T),R=(r(31905),r(92495)),M=r.n(R),D=r(1272);const L="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:window,{FormData:B,Blob:F,File:z}=L;var U=r(15687),q=r.n(U),V=r(24278),$=r.n(V),W=function(e){return":/?#[]@!$&'()*+,;=".indexOf(e)>-1},H=function(e){return/^[a-z0-9\-._~]+$/i.test(e)};function J(e){var t,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=r.escape,o=arguments.length>2?arguments[2]:void 0;return"number"==typeof e&&(e=e.toString()),"string"==typeof e&&e.length&&n?o?JSON.parse(e):A()(t=q()(e)).call(t,(function(e){var t,r;if(H(e))return e;if(W(e)&&"unsafe"===n)return e;var o=new TextEncoder;return A()(t=A()(r=E()(o.encode(e))).call(r,(function(e){var t;return $()(t="0".concat(e.toString(16).toUpperCase())).call(t,-2)}))).call(t,(function(e){return"%".concat(e)})).join("")})).join(""):e}function K(e){var t=e.value;return Array.isArray(t)?function(e){var t=e.key,r=e.value,n=e.style,o=e.explode,a=e.escape,i=function(e){return J(e,{escape:a})};if("simple"===n)return A()(r).call(r,(function(e){return i(e)})).join(",");if("label"===n)return".".concat(A()(r).call(r,(function(e){return i(e)})).join("."));if("matrix"===n)return A()(r).call(r,(function(e){return i(e)})).reduce((function(e,r){var n,a,i;return!e||o?j()(a=j()(i="".concat(e||"",";")).call(i,t,"=")).call(a,r):j()(n="".concat(e,",")).call(n,r)}),"");if("form"===n){var s=o?"&".concat(t,"="):",";return A()(r).call(r,(function(e){return i(e)})).join(s)}if("spaceDelimited"===n){var l=o?"".concat(t,"="):"";return A()(r).call(r,(function(e){return i(e)})).join(" ".concat(l))}if("pipeDelimited"===n){var u=o?"".concat(t,"="):"";return A()(r).call(r,(function(e){return i(e)})).join("|".concat(u))}return}(e):"object"===h()(t)?function(e){var t=e.key,r=e.value,n=e.style,o=e.explode,a=e.escape,i=function(e){return J(e,{escape:a})},s=C()(r);if("simple"===n)return s.reduce((function(e,t){var n,a,s,l=i(r[t]),u=o?"=":",",c=e?"".concat(e,","):"";return j()(n=j()(a=j()(s="".concat(c)).call(s,t)).call(a,u)).call(n,l)}),"");if("label"===n)return s.reduce((function(e,t){var n,a,s,l=i(r[t]),u=o?"=":".",c=e?"".concat(e,"."):".";return j()(n=j()(a=j()(s="".concat(c)).call(s,t)).call(a,u)).call(n,l)}),"");if("matrix"===n&&o)return s.reduce((function(e,t){var n,o,a=i(r[t]),s=e?"".concat(e,";"):";";return j()(n=j()(o="".concat(s)).call(o,t,"=")).call(n,a)}),"");if("matrix"===n)return s.reduce((function(e,n){var o,a,s=i(r[n]),l=e?"".concat(e,","):";".concat(t,"=");return j()(o=j()(a="".concat(l)).call(a,n,",")).call(o,s)}),"");if("form"===n)return s.reduce((function(e,t){var n,a,s,l,u=i(r[t]),c=e?j()(n="".concat(e)).call(n,o?"&":","):"",p=o?"=":",";return j()(a=j()(s=j()(l="".concat(c)).call(l,t)).call(s,p)).call(a,u)}),"");return}(e):function(e){var t,r=e.key,n=e.value,o=e.style,a=e.escape,i=function(e){return J(e,{escape:a})};if("simple"===o)return i(n);if("label"===o)return".".concat(i(n));if("matrix"===o)return j()(t=";".concat(r,"=")).call(t,i(n));if("form"===o)return i(n);if("deepObject"===o)return i(n,{},!0);return}(e)}const G=function(e,t){t.body=e};var Z={serializeRes:te,mergeInQueryOrForm:fe};function Y(e){return Q.apply(this,arguments)}function Q(){return Q=s()(u().mark((function e(t){var r,n,o,a,i,s=arguments;return u().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(r=s.length>1&&void 0!==s[1]?s[1]:{},"object"===h()(t)&&(t=(r=t).url),r.headers=r.headers||{},Z.mergeInQueryOrForm(r),r.headers&&C()(r.headers).forEach((function(e){var t=r.headers[e];"string"==typeof t&&(r.headers[e]=t.replace(/\n+/g," "))})),!r.requestInterceptor){e.next=12;break}return e.next=8,r.requestInterceptor(r);case 8:if(e.t0=e.sent,e.t0){e.next=11;break}e.t0=r;case 11:r=e.t0;case 12:return n=r.headers["content-type"]||r.headers["Content-Type"],/multipart\/form-data/i.test(n)&&r.body instanceof B&&(delete r.headers["content-type"],delete r.headers["Content-Type"]),e.prev=14,e.next=17,(r.userFetch||fetch)(r.url,r);case 17:return o=e.sent,e.next=20,Z.serializeRes(o,t,r);case 20:if(o=e.sent,!r.responseInterceptor){e.next=28;break}return e.next=24,r.responseInterceptor(o);case 24:if(e.t1=e.sent,e.t1){e.next=27;break}e.t1=o;case 27:o=e.t1;case 28:e.next=39;break;case 30:if(e.prev=30,e.t2=e.catch(14),o){e.next=34;break}throw e.t2;case 34:throw(a=new Error(o.statusText||"response status is ".concat(o.status))).status=o.status,a.statusCode=o.status,a.responseError=e.t2,a;case 39:if(o.ok){e.next=45;break}throw(i=new Error(o.statusText||"response status is ".concat(o.status))).status=o.status,i.statusCode=o.status,i.response=o,i;case 45:return e.abrupt("return",o);case 46:case"end":return e.stop()}}),e,null,[[14,30]])}))),Q.apply(this,arguments)}var X=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";return/(json|xml|yaml|text)\b/.test(e)};function ee(e,t){return t&&(0===t.indexOf("application/json")||t.indexOf("+json")>0)?JSON.parse(e):D.ZP.load(e)}function te(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},n=r.loadSpec,o=void 0!==n&&n,a={ok:e.ok,url:e.url||t,status:e.status,statusText:e.statusText,headers:ne(e.headers)},i=a.headers["content-type"],s=o||X(i),l=s?e.text:e.blob||e.buffer;return l.call(e).then((function(e){if(a.text=e,a.data=e,s)try{var t=ee(e,i);a.body=t,a.obj=t}catch(e){a.parseError=e}return a}))}function re(e){return v()(e).call(e,", ")?e.split(", "):e}function ne(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return"function"!=typeof b()(e)?{}:E()(b()(e).call(e)).reduce((function(e,t){var r=m()(t,2),n=r[0],o=r[1];return e[n]=re(o),e}),{})}function oe(e,t){return t||"undefined"==typeof navigator||(t=navigator),t&&"ReactNative"===t.product?!(!e||"object"!==h()(e)||"string"!=typeof e.uri):void 0!==z&&e instanceof z||(void 0!==F&&e instanceof F||(!!ArrayBuffer.isView(e)||null!==e&&"object"===h()(e)&&"function"==typeof e.pipe))}function ae(e,t){return Array.isArray(e)&&e.some((function(e){return oe(e,t)}))}var ie={form:",",spaceDelimited:"%20",pipeDelimited:"|"},se={csv:",",ssv:"%20",tsv:"%09",pipes:"|"};function le(e,t){var r=arguments.length>2&&void 0!==arguments[2]&&arguments[2],n=t.collectionFormat,o=t.allowEmptyValue,a=t.serializationOption,i=t.encoding,s="object"!==h()(t)||Array.isArray(t)?t:t.value,l=r?function(e){return e.toString()}:function(e){return encodeURIComponent(e)},u=l(e);if(void 0===s&&o)return[[u,""]];if(oe(s)||ae(s))return[[u,s]];if(a)return ue(e,s,r,a);if(i){if([h()(i.style),h()(i.explode),h()(i.allowReserved)].some((function(e){return"undefined"!==e}))){var c=i.style,p=i.explode,f=i.allowReserved;return ue(e,s,r,{style:c,explode:p,allowReserved:f})}if(i.contentType){if("application/json"===i.contentType){var d="string"==typeof s?s:_()(s);return[[u,l(d)]]}return[[u,l(s.toString())]]}return"object"!==h()(s)?[[u,l(s)]]:Array.isArray(s)&&s.every((function(e){return"object"!==h()(e)}))?[[u,A()(s).call(s,l).join(",")]]:[[u,l(_()(s))]]}return"object"!==h()(s)?[[u,l(s)]]:Array.isArray(s)?"multi"===n?[[u,A()(s).call(s,l)]]:[[u,A()(s).call(s,l).join(se[n||"csv"])]]:[[u,""]]}function ue(e,t,r,n){var o,a,i,s=n.style||"form",l=void 0===n.explode?"form"===s:n.explode,u=!r&&(n&&n.allowReserved?"unsafe":"reserved"),c=function(e){return J(e,{escape:u})},p=r?function(e){return e}:function(e){return J(e,{escape:u})};return"object"!==h()(t)?[[p(e),c(t)]]:Array.isArray(t)?l?[[p(e),A()(t).call(t,c)]]:[[p(e),A()(t).call(t,c).join(ie[s])]]:"deepObject"===s?A()(a=C()(t)).call(a,(function(r){var n;return[p(j()(n="".concat(e,"[")).call(n,r,"]")),c(t[r])]})):l?A()(i=C()(t)).call(i,(function(e){return[p(e),c(t[e])]})):[[p(e),A()(o=C()(t)).call(o,(function(e){var r;return[j()(r="".concat(p(e),",")).call(r,c(t[e]))]})).join(",")]]}function ce(e){return N()(e).reduce((function(e,t){var r,n=m()(t,2),o=n[0],a=n[1],i=p()(le(o,a,!0));try{for(i.s();!(r=i.n()).done;){var s=m()(r.value,2),l=s[0],u=s[1];if(Array.isArray(u)){var c,f=p()(u);try{for(f.s();!(c=f.n()).done;){var h=c.value;if(ArrayBuffer.isView(h)){var d=new F([h]);e.append(l,d)}else e.append(l,h)}}catch(e){f.e(e)}finally{f.f()}}else if(ArrayBuffer.isView(u)){var g=new F([u]);e.append(l,g)}else e.append(l,u)}}catch(e){i.e(e)}finally{i.f()}return e}),new B)}function pe(e){var t=C()(e).reduce((function(t,r){var n,o=p()(le(r,e[r]));try{for(o.s();!(n=o.n()).done;){var a=m()(n.value,2),i=a[0],s=a[1];t[i]=s}}catch(e){o.e(e)}finally{o.f()}return t}),{});return M().stringify(t,{encode:!1,indices:!1})||""}function fe(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.url,r=void 0===t?"":t,n=e.query,o=e.form,a=function(){for(var e=arguments.length,t=new Array(e),r=0;r=48&&t<=57))return!1;r++}return!0}function Re(e){return-1===e.indexOf("/")&&-1===e.indexOf("~")?e:e.replace(/~/g,"~0").replace(/\//g,"~1")}function Me(e){return e.replace(/~1/g,"/").replace(/~0/g,"~")}function De(e){if(void 0===e)return!0;if(e)if(Array.isArray(e)){for(var t=0,r=e.length;t0&&"constructor"==s[u-1]))throw new TypeError("JSON-Patch: modifying `__proto__` or `constructor/prototype` prop is banned for security reasons, if this was on purpose, please set `banPrototypeModifications` flag false and pass it to this function. More info in fast-json-patch README");if(r&&void 0===p&&(void 0===l[f]?p=s.slice(0,u).join("/"):u==c-1&&(p=t.path),void 0!==p&&h(t,0,e,p)),u++,Array.isArray(l)){if("-"===f)f=l.length;else{if(r&&!Pe(f))throw new Fe("Expected an unsigned base-10 integer value, making the new referenced value the array element with the zero-based index","OPERATION_PATH_ILLEGAL_ARRAY_INDEX",a,t,e);Pe(f)&&(f=~~f)}if(u>=c){if(r&&"add"===t.op&&f>l.length)throw new Fe("The specified index MUST NOT be greater than the number of elements in the array","OPERATION_VALUE_OUT_OF_BOUNDS",a,t,e);if(!1===(i=qe[t.op].call(t,l,f,e)).test)throw new Fe("Test operation failed","TEST_OPERATION_FAILED",a,t,e);return i}}else if(u>=c){if(!1===(i=Ue[t.op].call(t,l,f,e)).test)throw new Fe("Test operation failed","TEST_OPERATION_FAILED",a,t,e);return i}if(l=l[f],r&&u0)throw new Fe('Operation `path` property must start with "/"',"OPERATION_PATH_INVALID",t,e,r);if(("move"===e.op||"copy"===e.op)&&"string"!=typeof e.from)throw new Fe("Operation `from` property is not present (applicable in `move` and `copy` operations)","OPERATION_FROM_REQUIRED",t,e,r);if(("add"===e.op||"replace"===e.op||"test"===e.op)&&void 0===e.value)throw new Fe("Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)","OPERATION_VALUE_REQUIRED",t,e,r);if(("add"===e.op||"replace"===e.op||"test"===e.op)&&De(e.value))throw new Fe("Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)","OPERATION_VALUE_CANNOT_CONTAIN_UNDEFINED",t,e,r);if(r)if("add"==e.op){var o=e.path.split("/").length,a=n.split("/").length;if(o!==a+1&&o!==a)throw new Fe("Cannot perform an `add` operation at the desired path","OPERATION_PATH_CANNOT_ADD",t,e,r)}else if("replace"===e.op||"remove"===e.op||"_get"===e.op){if(e.path!==n)throw new Fe("Cannot perform the operation at a path that does not exist","OPERATION_PATH_UNRESOLVABLE",t,e,r)}else if("move"===e.op||"copy"===e.op){var i=Ke([{op:"_get",path:e.from,value:void 0}],r);if(i&&"OPERATION_PATH_UNRESOLVABLE"===i.name)throw new Fe("Cannot perform the operation from a path that does not exist","OPERATION_FROM_UNRESOLVABLE",t,e,r)}}function Ke(e,t,r){try{if(!Array.isArray(e))throw new Fe("Patch sequence must be an array","SEQUENCE_NOT_AN_ARRAY");if(t)We(Te(t),Te(e),r||!0);else{r=r||Je;for(var n=0;n0&&(e.patches=[],e.callback&&e.callback(n)),n}function rt(e,t,r,n,o){if(t!==e){"function"==typeof t.toJSON&&(t=t.toJSON());for(var a=Ne(t),i=Ne(e),s=!1,l=i.length-1;l>=0;l--){var u=e[p=i[l]];if(!Ie(t,p)||void 0===t[p]&&void 0!==u&&!1===Array.isArray(t))Array.isArray(e)===Array.isArray(t)?(o&&r.push({op:"test",path:n+"/"+Re(p),value:Te(u)}),r.push({op:"remove",path:n+"/"+Re(p)}),s=!0):(o&&r.push({op:"test",path:n,value:e}),r.push({op:"replace",path:n,value:t}),!0);else{var c=t[p];"object"==typeof u&&null!=u&&"object"==typeof c&&null!=c&&Array.isArray(u)===Array.isArray(c)?rt(u,c,r,n+"/"+Re(p),o):u!==c&&(!0,o&&r.push({op:"test",path:n+"/"+Re(p),value:Te(u)}),r.push({op:"replace",path:n+"/"+Re(p),value:Te(c)}))}}if(s||a.length!=i.length)for(l=0;l0){var o=t(e,r[r.length-1],r);o&&(n=j()(n).call(n,o))}if(Array.isArray(e)){var a=A()(e).call(e,(function(e,n){return pt(e,t,j()(r).call(r,n))}));a&&(n=j()(n).call(n,a))}else if(mt(e)){var i,s=A()(i=C()(e)).call(i,(function(n){return pt(e[n],t,j()(r).call(r,n))}));s&&(n=j()(n).call(n,s))}return n=ht(n)}function ft(e){return Array.isArray(e)?e:[e]}function ht(e){var t;return j()(t=[]).apply(t,q()(A()(e).call(e,(function(e){return Array.isArray(e)?ht(e):e}))))}function dt(e){return P()(e).call(e,(function(e){return void 0!==e}))}function mt(e){return e&&"object"===h()(e)}function gt(e){return e&&"function"==typeof e}function vt(e){if(wt(e)){var t=e.op;return"add"===t||"remove"===t||"replace"===t}return!1}function yt(e){return vt(e)||wt(e)&&"mutation"===e.type}function bt(e){return yt(e)&&("add"===e.op||"replace"===e.op||"merge"===e.op||"mergeDeep"===e.op)}function wt(e){return e&&"object"===h()(e)}function Et(e,t){try{return Ve(e,t)}catch(e){return console.error(e),{}}}var xt=r(28886),_t=r.n(xt),St=r(37659),At=r.n(St),kt=r(8575);function Ct(e,t){function r(){Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack;for(var e=arguments.length,r=new Array(e),n=0;n-1&&-1===Nt.indexOf(r)||Tt.indexOf(n)>-1||Pt.some((function(e){return n.indexOf(e)>-1}))}function Mt(e,t){var r,n=e.split("#"),o=m()(n,2),a=o[0],i=o[1],s=kt.resolve(a||"",t||"");return i?j()(r="".concat(s,"#")).call(r,i):s}var Dt="application/json, application/yaml",Lt=/^([a-z]+:\/\/|\/\/)/i,Bt=Ct("JSONRefError",(function(e,t,r){this.originalError=r,Ee()(this,t||{})})),Ft={},zt=new(_t()),Ut=[function(e){return"paths"===e[0]&&"responses"===e[3]&&"examples"===e[5]},function(e){return"paths"===e[0]&&"responses"===e[3]&&"content"===e[5]&&"example"===e[7]},function(e){return"paths"===e[0]&&"responses"===e[3]&&"content"===e[5]&&"examples"===e[7]&&"value"===e[9]},function(e){return"paths"===e[0]&&"requestBody"===e[3]&&"content"===e[4]&&"example"===e[6]},function(e){return"paths"===e[0]&&"requestBody"===e[3]&&"content"===e[4]&&"examples"===e[6]&&"value"===e[8]},function(e){return"paths"===e[0]&&"parameters"===e[2]&&"example"===e[4]},function(e){return"paths"===e[0]&&"parameters"===e[3]&&"example"===e[5]},function(e){return"paths"===e[0]&&"parameters"===e[2]&&"examples"===e[4]&&"value"===e[6]},function(e){return"paths"===e[0]&&"parameters"===e[3]&&"examples"===e[5]&&"value"===e[7]},function(e){return"paths"===e[0]&&"parameters"===e[2]&&"content"===e[4]&&"example"===e[6]},function(e){return"paths"===e[0]&&"parameters"===e[2]&&"content"===e[4]&&"examples"===e[6]&&"value"===e[8]},function(e){return"paths"===e[0]&&"parameters"===e[3]&&"content"===e[4]&&"example"===e[7]},function(e){return"paths"===e[0]&&"parameters"===e[3]&&"content"===e[5]&&"examples"===e[7]&&"value"===e[9]}],qt={key:"$ref",plugin:function(e,t,r,n){var o=n.getInstance(),a=$()(r).call(r,0,-1);if(!Rt(a)&&!function(e){return Ut.some((function(t){return t(e)}))}(a)){var i=n.getContext(r).baseDoc;if("string"!=typeof e)return new Bt("$ref: must be a string (JSON-Ref)",{$ref:e,baseDoc:i,fullPath:r});var s,l,u,c=Jt(e),p=c[0],f=c[1]||"";try{s=i||p?Wt(p,i):null}catch(t){return Ht(t,{pointer:f,$ref:e,basePath:s,fullPath:r})}if(function(e,t,r,n){var o,a,i=zt.get(n);i||(i={},zt.set(n,i));var s=function(e){if(0===e.length)return"";return"/".concat(A()(e).call(e,Xt).join("/"))}(r),l=j()(o="".concat(t||"","#")).call(o,e),u=s.replace(/allOf\/\d+\/?/g,""),c=n.contextTree.get([]).baseDoc;if(t===c&&er(u,e))return!0;var p="",f=r.some((function(e){var t;return p=j()(t="".concat(p,"/")).call(t,Xt(e)),i[p]&&i[p].some((function(e){return er(e,l)||er(l,e)}))}));if(f)return!0;return void(i[u]=j()(a=i[u]||[]).call(a,l))}(f,s,a,n)&&!o.useCircularStructures){var h=Mt(e,s);return e===h?null:it.replace(r,h)}if(null==s?(u=Yt(f),void 0===(l=n.get(u))&&(l=new Bt("Could not resolve reference: ".concat(e),{pointer:f,$ref:e,baseDoc:i,fullPath:r}))):l=null!=(l=Kt(s,f)).__value?l.__value:l.catch((function(t){throw Ht(t,{pointer:f,$ref:e,baseDoc:i,fullPath:r})})),l instanceof Error)return[it.remove(r),l];var d=Mt(e,s),m=it.replace(a,l,{$$ref:d});if(s&&s!==i)return[m,it.context(a,{baseDoc:s})];try{if(!function(e,t){var r=[e];return t.path.reduce((function(e,t){return r.push(e[t]),e[t]}),e),n(t.value);function n(e){return it.isObject(e)&&(r.indexOf(e)>=0||C()(e).some((function(t){return n(e[t])})))}}(n.state,m)||o.useCircularStructures)return m}catch(e){return null}}}},Vt=Ee()(qt,{docCache:Ft,absoluteify:Wt,clearCache:function(e){void 0!==e?delete Ft[e]:C()(Ft).forEach((function(e){delete Ft[e]}))},JSONRefError:Bt,wrapError:Ht,getDoc:Gt,split:Jt,extractFromDoc:Kt,fetchJSON:function(e){return fetch(e,{headers:{Accept:Dt},loadSpec:!0}).then((function(e){return e.text()})).then((function(e){return D.ZP.load(e)}))},extract:Zt,jsonPointerToArray:Yt,unescapeJsonPointerToken:Qt});const $t=Vt;function Wt(e,t){if(!Lt.test(e)){var r;if(!t)throw new Bt(j()(r="Tried to resolve a relative URL, without having a basePath. path: '".concat(e,"' basePath: '")).call(r,t,"'"));return kt.resolve(t,e)}return e}function Ht(e,t){var r,n;e&&e.response&&e.response.body?r=j()(n="".concat(e.response.body.code," ")).call(n,e.response.body.message):r=e.message;return new Bt("Could not resolve reference: ".concat(r),t,e)}function Jt(e){return(e+"").split("#")}function Kt(e,t){var r=Ft[e];if(r&&!it.isPromise(r))try{var n=Zt(t,r);return Ee()(Ae().resolve(n),{__value:n})}catch(e){return Ae().reject(e)}return Gt(e).then((function(e){return Zt(t,e)}))}function Gt(e){var t=Ft[e];return t?it.isPromise(t)?t:Ae().resolve(t):(Ft[e]=Vt.fetchJSON(e).then((function(t){return Ft[e]=t,t})),Ft[e])}function Zt(e,t){var r=Yt(e);if(r.length<1)return t;var n=it.getIn(t,r);if(void 0===n)throw new Bt("Could not resolve pointer: ".concat(e," does not exist in document"),{pointer:e});return n}function Yt(e){var t;if("string"!=typeof e)throw new TypeError("Expected a string, got a ".concat(h()(e)));return"/"===e[0]&&(e=e.substr(1)),""===e?[]:A()(t=e.split("/")).call(t,Qt)}function Qt(e){return"string"!=typeof e?e:new(At())("=".concat(e.replace(/~1/g,"/").replace(/~0/g,"~"))).get("")}function Xt(e){var t,r=new(At())([["",e.replace(/~/g,"~0").replace(/\//g,"~1")]]);return $()(t=r.toString()).call(t,1)}function er(e,t){if(!(r=t)||"/"===r||"#"===r)return!0;var r,n=e.charAt(t.length),o=$()(t).call(t,-1);return 0===e.indexOf(t)&&(!n||"/"===n||"#"===n)&&"#"!==o}const tr={key:"allOf",plugin:function(e,t,r,n,o){if(!o.meta||!o.meta.$$ref){var a=$()(r).call(r,0,-1);if(!Rt(a)){if(!Array.isArray(e)){var i=new TypeError("allOf must be an array");return i.fullPath=r,i}var s=!1,l=o.value;if(a.forEach((function(e){l&&(l=l[e])})),l=me()({},l),0!==C()(l).length){delete l.allOf;var u,c,p=[];if(p.push(n.replace(a,{})),e.forEach((function(e,t){if(!n.isObject(e)){if(s)return null;s=!0;var o=new TypeError("Elements in allOf must be objects");return o.fullPath=r,p.push(o)}p.push(n.mergeDeep(a,e));var i=function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},n=r.specmap,o=r.getBaseUrlForNodePath,a=void 0===o?function(e){var r;return n.getContext(j()(r=[]).call(r,q()(t),q()(e))).baseDoc}:o,i=r.targetKeys,s=void 0===i?["$ref","$$ref"]:i,l=[];return jt()(e).forEach((function(){if(v()(s).call(s,this.key)&&"string"==typeof this.node){var e=this.path,r=j()(t).call(t,this.path),o=Mt(this.node,a(e));l.push(n.replace(r,o))}})),l}(e,$()(r).call(r,0,-1),{getBaseUrlForNodePath:function(e){var o;return n.getContext(j()(o=[]).call(o,q()(r),[t],q()(e))).baseDoc},specmap:n});p.push.apply(p,q()(i))})),l.example)p.push(n.remove(j()(u=[]).call(u,a,"example")));if(p.push(n.mergeDeep(a,l)),!l.$$ref)p.push(n.remove(j()(c=[]).call(c,a,"$$ref")));return p}}}}},rr={key:"parameters",plugin:function(e,t,r,n){if(Array.isArray(e)&&e.length){var o=Ee()([],e),a=$()(r).call(r,0,-1),i=me()({},it.getIn(n.spec,a));return e.forEach((function(e,t){try{o[t].default=n.parameterMacro(i,e)}catch(e){var a=new Error(e);return a.fullPath=r,a}})),it.replace(r,o)}return it.replace(r,e)}},nr={key:"properties",plugin:function(e,t,r,n){var o=me()({},e);for(var a in e)try{o[a].default=n.modelPropertyMacro(o[a])}catch(e){var i=new Error(e);return i.fullPath=r,i}return it.replace(r,o)}};var or=function(){function e(t){ve()(this,e),this.root=ar(t||{})}return be()(e,[{key:"set",value:function(e,t){var r=this.getParent(e,!0);if(r){var n=e[e.length-1],o=r.children;o[n]?ir(o[n],t,r):o[n]=ar(t,r)}else ir(this.root,t,null)}},{key:"get",value:function(e){if((e=e||[]).length<1)return this.root.value;for(var t,r,n=this.root,o=0;o1?r-1:0),o=1;o1?n-1:0),a=1;a0}))}},{key:"nextPromisedPatch",value:function(){var e;if(this.promisedPatches.length>0)return Ae().race(A()(e=this.promisedPatches).call(e,(function(e){return e.value})))}},{key:"getPluginHistory",value:function(e){var t=this.constructor.getPluginName(e);return this.pluginHistory[t]||[]}},{key:"getPluginRunCount",value:function(e){return this.getPluginHistory(e).length}},{key:"getPluginHistoryTip",value:function(e){var t=this.getPluginHistory(e);return t&&t[t.length-1]||{}}},{key:"getPluginMutationIndex",value:function(e){var t=this.getPluginHistoryTip(e).mutationIndex;return"number"!=typeof t?-1:t}},{key:"updatePluginHistory",value:function(e,t){var r=this.constructor.getPluginName(e);this.pluginHistory[r]=this.pluginHistory[r]||[],this.pluginHistory[r].push(t)}},{key:"updatePatches",value:function(e){var t=this;it.normalizeArray(e).forEach((function(e){if(e instanceof Error)t.errors.push(e);else try{if(!it.isObject(e))return void t.debug("updatePatches","Got a non-object patch",e);if(t.showDebug&&t.allPatches.push(e),it.isPromise(e.value))return t.promisedPatches.push(e),void t.promisedPatchThen(e);if(it.isContextPatch(e))return void t.setContext(e.path,e.value);if(it.isMutation(e))return void t.updateMutations(e)}catch(e){console.error(e),t.errors.push(e)}}))}},{key:"updateMutations",value:function(e){"object"===h()(e.value)&&!Array.isArray(e.value)&&this.allowMetaPatches&&(e.value=me()({},e.value));var t=it.applyPatch(this.state,e,{allowMetaPatches:this.allowMetaPatches});t&&(this.mutations.push(e),this.state=t)}},{key:"removePromisedPatch",value:function(e){var t,r=this.promisedPatches.indexOf(e);r<0?this.debug("Tried to remove a promisedPatch that isn't there!"):Ce()(t=this.promisedPatches).call(t,r,1)}},{key:"promisedPatchThen",value:function(e){var t=this;return e.value=e.value.then((function(r){var n=me()(me()({},e),{},{value:r});t.removePromisedPatch(e),t.updatePatches(n)})).catch((function(r){t.removePromisedPatch(e),t.updatePatches(r)})),e.value}},{key:"getMutations",value:function(e,t){var r;return e=e||0,"number"!=typeof t&&(t=this.mutations.length),$()(r=this.mutations).call(r,e,t)}},{key:"getCurrentMutations",value:function(){return this.getMutationsForPlugin(this.getCurrentPlugin())}},{key:"getMutationsForPlugin",value:function(e){var t=this.getPluginMutationIndex(e);return this.getMutations(t+1)}},{key:"getCurrentPlugin",value:function(){return this.currentPlugin}},{key:"getLib",value:function(){return this.libMethods}},{key:"_get",value:function(e){return it.getIn(this.state,e)}},{key:"_getContext",value:function(e){return this.contextTree.get(e)}},{key:"setContext",value:function(e,t){return this.contextTree.set(e,t)}},{key:"_hasRun",value:function(e){return this.getPluginRunCount(this.getCurrentPlugin())>(e||0)}},{key:"dispatch",value:function(){var e,t=this,r=this,n=this.nextPlugin();if(!n){var o=this.nextPromisedPatch();if(o)return o.then((function(){return t.dispatch()})).catch((function(){return t.dispatch()}));var a={spec:this.state,errors:this.errors};return this.showDebug&&(a.patches=this.allPatches),Ae().resolve(a)}if(r.pluginCount=r.pluginCount||{},r.pluginCount[n]=(r.pluginCount[n]||0)+1,r.pluginCount[n]>100)return Ae().resolve({spec:r.state,errors:j()(e=r.errors).call(e,new Error("We've reached a hard limit of ".concat(100," plugin runs")))});if(n!==this.currentPlugin&&this.promisedPatches.length){var i,s=A()(i=this.promisedPatches).call(i,(function(e){return e.value}));return Ae().all(A()(s).call(s,(function(e){return e.then(sr,sr)}))).then((function(){return t.dispatch()}))}return function(){r.currentPlugin=n;var e=r.getCurrentMutations(),t=r.mutations.length-1;try{if(n.isGenerator){var o,a=p()(n(e,r.getLib()));try{for(a.s();!(o=a.n()).done;){l(o.value)}}catch(e){a.e(e)}finally{a.f()}}else{l(n(e,r.getLib()))}}catch(e){console.error(e),l([Ee()(Object.create(e),{plugin:n})])}finally{r.updatePluginHistory(n,{mutationIndex:t})}return r.dispatch()}();function l(e){e&&(e=it.fullyNormalizeArray(e),r.updatePatches(e,n))}}}],[{key:"getPluginName",value:function(e){return e.pluginName}},{key:"getPatchesOfType",value:function(e,t){return P()(e).call(e,t)}}]),e}();var ur={refs:$t,allOf:tr,parameters:rr,properties:nr},cr=r(23159);function pr(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=t.requestInterceptor,n=t.responseInterceptor,o=e.withCredentials?"include":"same-origin";return function(t){return e({url:t,loadSpec:!0,requestInterceptor:r,responseInterceptor:n,headers:{Accept:Dt},credentials:o}).then((function(e){return e.body}))}}function fr(e){var t=e.fetch,r=e.spec,n=e.url,o=e.mode,a=e.allowMetaPatches,i=void 0===a||a,l=e.pathDiscriminator,c=e.modelPropertyMacro,p=e.parameterMacro,f=e.requestInterceptor,h=e.responseInterceptor,d=e.skipNormalization,m=e.useCircularStructures,g=e.http,v=e.baseDoc;return v=v||n,g=t||g||Y,r?y(r):pr(g,{requestInterceptor:f,responseInterceptor:h})(v).then(y);function y(e){v&&(ur.refs.docCache[v]=e),ur.refs.fetchJSON=pr(g,{requestInterceptor:f,responseInterceptor:h});var t,r=[ur.refs];return"function"==typeof p&&r.push(ur.parameters),"function"==typeof c&&r.push(ur.properties),"strict"!==o&&r.push(ur.allOf),(t={spec:e,context:{baseDoc:v},plugins:r,allowMetaPatches:i,pathDiscriminator:l,parameterMacro:p,modelPropertyMacro:c,useCircularStructures:m},new lr(t).dispatch()).then(d?function(){var e=s()(u().mark((function e(t){return u().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",t);case 1:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}():cr.K1)}}var hr=r(88436),dr=r.n(hr),mr=r(27361),gr=r.n(mr),vr=r(30006);function yr(e){return"[object Object]"===Object.prototype.toString.call(e)}function br(e){var t,r;return!1!==yr(e)&&(void 0===(t=e.constructor)||!1!==yr(r=t.prototype)&&!1!==r.hasOwnProperty("isPrototypeOf"))}const wr={body:function(e){var t=e.req,r=e.value;t.body=r},header:function(e){var t=e.req,r=e.parameter,n=e.value;t.headers=t.headers||{},void 0!==n&&(t.headers[r.name]=n)},query:function(e){var t=e.req,r=e.value,n=e.parameter;t.query=t.query||{},!1===r&&"boolean"===n.type&&(r="false");0===r&&["number","integer"].indexOf(n.type)>-1&&(r="0");if(r)t.query[n.name]={collectionFormat:n.collectionFormat,value:r};else if(n.allowEmptyValue&&void 0!==r){var o=n.name;t.query[o]=t.query[o]||{},t.query[o].allowEmptyValue=!0}},path:function(e){var t=e.req,r=e.value,n=e.parameter;t.url=t.url.split("{".concat(n.name,"}")).join(encodeURIComponent(r))},formData:function(e){var t=e.req,r=e.value,n=e.parameter;(r||n.allowEmptyValue)&&(t.form=t.form||{},t.form[n.name]={value:r,allowEmptyValue:n.allowEmptyValue,collectionFormat:n.collectionFormat})}};function Er(e,t){return v()(t).call(t,"application/json")?"string"==typeof e?e:_()(e):e.toString()}function xr(e){var t=e.req,r=e.value,n=e.parameter,o=n.name,a=n.style,i=n.explode,s=n.content;if(s){var l=C()(s)[0];t.url=t.url.split("{".concat(o,"}")).join(J(Er(r,l),{escape:!0}))}else{var u=K({key:n.name,value:r,style:a||"simple",explode:i||!1,escape:!0});t.url=t.url.split("{".concat(o,"}")).join(u)}}function _r(e){var t=e.req,r=e.value,n=e.parameter;if(t.query=t.query||{},n.content){var o=C()(n.content)[0];t.query[n.name]=Er(r,o)}else if(!1===r&&(r="false"),0===r&&(r="0"),r){var a=n.style,i=n.explode,s=n.allowReserved;t.query[n.name]={value:r,serializationOption:{style:a,explode:i,allowReserved:s}}}else if(n.allowEmptyValue&&void 0!==r){var l=n.name;t.query[l]=t.query[l]||{},t.query[l].allowEmptyValue=!0}}var Sr=["accept","authorization","content-type"];function Ar(e){var t=e.req,r=e.parameter,n=e.value;if(t.headers=t.headers||{},!(Sr.indexOf(r.name.toLowerCase())>-1))if(r.content){var o=C()(r.content)[0];t.headers[r.name]=Er(n,o)}else void 0!==n&&(t.headers[r.name]=K({key:r.name,value:n,style:r.style||"simple",explode:void 0!==r.explode&&r.explode,escape:!1}))}function kr(e){var t=e.req,r=e.parameter,n=e.value;t.headers=t.headers||{};var o=h()(n);if(r.content){var a,i=C()(r.content)[0];t.headers.Cookie=j()(a="".concat(r.name,"=")).call(a,Er(n,i))}else if("undefined"!==o){var s="object"===o&&!Array.isArray(n)&&r.explode?"":"".concat(r.name,"=");t.headers.Cookie=s+K({key:r.name,value:n,escape:!1,style:r.style||"form",explode:void 0!==r.explode&&r.explode})}}var Cr=r(92381),Or=r.n(Cr);const jr=(void 0!==Or()?Or():"undefined"!=typeof self?self:window).btoa;function Ir(e,t){var r=e.operation,n=e.requestBody,o=e.securities,a=e.spec,i=e.attachContentTypeForEmptyPayload,s=e.requestContentType;t=function(e){var t=e.request,r=e.securities,n=void 0===r?{}:r,o=e.operation,a=void 0===o?{}:o,i=e.spec,s=me()({},t),l=n.authorized,u=void 0===l?{}:l,c=a.security||i.security||[],p=u&&!!C()(u).length,f=gr()(i,["components","securitySchemes"])||{};if(s.headers=s.headers||{},s.query=s.query||{},!C()(n).length||!p||!c||Array.isArray(a.security)&&!a.security.length)return t;return c.forEach((function(e){C()(e).forEach((function(e){var t=u[e],r=f[e];if(t){var n=t.value||t,o=r.type;if(t)if("apiKey"===o)"query"===r.in&&(s.query[r.name]=n),"header"===r.in&&(s.headers[r.name]=n),"cookie"===r.in&&(s.cookies[r.name]=n);else if("http"===o){if(/^basic$/i.test(r.scheme)){var a,i=n.username||"",l=n.password||"",c=jr(j()(a="".concat(i,":")).call(a,l));s.headers.Authorization="Basic ".concat(c)}/^bearer$/i.test(r.scheme)&&(s.headers.Authorization="Bearer ".concat(n))}else if("oauth2"===o||"openIdConnect"===o){var p,h=t.token||{},d=h[r["x-tokenName"]||"access_token"],m=h.token_type;m&&"bearer"!==m.toLowerCase()||(m="Bearer"),s.headers.Authorization=j()(p="".concat(m," ")).call(p,d)}}}))})),s}({request:t,securities:o,operation:r,spec:a});var l=r.requestBody||{},u=C()(l.content||{}),c=s&&u.indexOf(s)>-1;if(n||i){if(s&&c)t.headers["Content-Type"]=s;else if(!s){var p=u[0];p&&(t.headers["Content-Type"]=p,s=p)}}else s&&c&&(t.headers["Content-Type"]=s);if(!e.responseContentType&&r.responses){var f,d=P()(f=N()(r.responses)).call(f,(function(e){var t=m()(e,2),r=t[0],n=t[1],o=parseInt(r,10);return o>=200&&o<300&&br(n.content)})).reduce((function(e,t){var r=m()(t,2)[1];return j()(e).call(e,C()(r.content))}),[]);d.length>0&&(t.headers.accept=d.join(", "))}if(n)if(s){if(u.indexOf(s)>-1)if("application/x-www-form-urlencoded"===s||"multipart/form-data"===s)if("object"===h()(n)){var g=(l.content[s]||{}).encoding||{};t.form={},C()(n).forEach((function(e){t.form[e]={value:n[e],encoding:g[e]||{}}}))}else t.form=n;else t.body=n}else t.body=n;return t}function Nr(e,t){var r,n,o=e.spec,a=e.operation,i=e.securities,s=e.requestContentType,l=e.responseContentType,u=e.attachContentTypeForEmptyPayload;if(t=function(e){var t=e.request,r=e.securities,n=void 0===r?{}:r,o=e.operation,a=void 0===o?{}:o,i=e.spec,s=me()({},t),l=n.authorized,u=void 0===l?{}:l,c=n.specSecurity,p=void 0===c?[]:c,f=a.security||p,h=u&&!!C()(u).length,d=i.securityDefinitions;if(s.headers=s.headers||{},s.query=s.query||{},!C()(n).length||!h||!f||Array.isArray(a.security)&&!a.security.length)return t;return f.forEach((function(e){C()(e).forEach((function(e){var t=u[e];if(t){var r=t.token,n=t.value||t,o=d[e],a=o.type,i=o["x-tokenName"]||"access_token",l=r&&r[i],c=r&&r.token_type;if(t)if("apiKey"===a){var p="query"===o.in?"query":"headers";s[p]=s[p]||{},s[p][o.name]=n}else if("basic"===a)if(n.header)s.headers.authorization=n.header;else{var f,h=n.username||"",m=n.password||"";n.base64=jr(j()(f="".concat(h,":")).call(f,m)),s.headers.authorization="Basic ".concat(n.base64)}else if("oauth2"===a&&l){var g;c=c&&"bearer"!==c.toLowerCase()?c:"Bearer",s.headers.authorization=j()(g="".concat(c," ")).call(g,l)}}}))})),s}({request:t,securities:i,operation:a,spec:o}),t.body||t.form||u)if(s)t.headers["Content-Type"]=s;else if(Array.isArray(a.consumes)){var c=m()(a.consumes,1);t.headers["Content-Type"]=c[0]}else if(Array.isArray(o.consumes)){var p=m()(o.consumes,1);t.headers["Content-Type"]=p[0]}else a.parameters&&P()(r=a.parameters).call(r,(function(e){return"file"===e.type})).length?t.headers["Content-Type"]="multipart/form-data":a.parameters&&P()(n=a.parameters).call(n,(function(e){return"formData"===e.in})).length&&(t.headers["Content-Type"]="application/x-www-form-urlencoded");else if(s){var f,h,d=a.parameters&&P()(f=a.parameters).call(f,(function(e){return"body"===e.in})).length>0,g=a.parameters&&P()(h=a.parameters).call(h,(function(e){return"formData"===e.in})).length>0;(d||g)&&(t.headers["Content-Type"]=s)}return!l&&Array.isArray(a.produces)&&a.produces.length>0&&(t.headers.accept=a.produces.join(", ")),t}var Tr=["http","fetch","spec","operationId","pathName","method","parameters","securities"],Pr=function(e){return Array.isArray(e)?e:[]},Rr=Ct("OperationNotFoundError",(function(e,t,r){this.originalError=r,Ee()(this,t||{})})),Mr={buildRequest:Lr};function Dr(e){var t=e.http,r=e.fetch,n=e.spec,o=e.operationId,a=e.pathName,i=e.method,s=e.parameters,l=e.securities,u=dr()(e,Tr),c=t||r||Y;a&&i&&!o&&(o=(0,cr.nc)(a,i));var p=Mr.buildRequest(me()({spec:n,operationId:o,parameters:s,securities:l,http:c},u));return p.body&&(br(p.body)||Array.isArray(p.body))&&(p.body=_()(p.body)),c(p)}function Lr(e){var t,r,n=e.spec,o=e.operationId,i=e.responseContentType,s=e.scheme,l=e.requestInterceptor,u=e.responseInterceptor,c=e.contextUrl,p=e.userFetch,f=e.server,h=e.serverVariables,d=e.http,g=e.signal,v=e.parameters,y=e.parameterBuilders,b=(0,cr.z6)(n);y||(y=b?a:wr);var w={url:"",credentials:d&&d.withCredentials?"include":"same-origin",headers:{},cookies:{}};g&&(w.signal=g),l&&(w.requestInterceptor=l),u&&(w.responseInterceptor=u),p&&(w.userFetch=p);var E=(0,cr.$r)(n,o);if(!E)throw new Rr("Operation ".concat(o," not found"));var x,_=E.operation,S=void 0===_?{}:_,k=E.method,O=E.pathName;if(w.url+=(x={spec:n,scheme:s,contextUrl:c,server:f,serverVariables:h,pathName:O,method:k},(0,cr.z6)(x.spec)?function(e){var t=e.spec,r=e.pathName,n=e.method,o=e.server,a=e.contextUrl,i=e.serverVariables,s=void 0===i?{}:i,l=gr()(t,["paths",r,(n||"").toLowerCase(),"servers"])||gr()(t,["paths",r,"servers"])||gr()(t,["servers"]),u="",c=null;if(o&&l&&l.length){var p=A()(l).call(l,(function(e){return e.url}));p.indexOf(o)>-1&&(u=o,c=l[p.indexOf(o)])}if(!u&&l&&l.length){u=l[0].url;var f=m()(l,1);c=f[0]}return u.indexOf("{")>-1&&function(e){for(var t,r=[],n=/{([^}]+)}/g;t=n.exec(e);)r.push(t[1]);return r}(u).forEach((function(e){if(c.variables&&c.variables[e]){var t=c.variables[e],r=s[e]||t.default,n=new RegExp("{".concat(e,"}"),"g");u=u.replace(n,r)}})),function(){var e,t,r=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",o=r&&n?kt.parse(kt.resolve(n,r)):kt.parse(r),a=kt.parse(n),i=Br(o.protocol)||Br(a.protocol)||"",s=o.host||a.host,l=o.pathname||"";return"/"===(e=i&&s?j()(t="".concat(i,"://")).call(t,s+l):l)[e.length-1]?$()(e).call(e,0,-1):e}(u,a)}(x):function(e){var t,r,n=e.spec,o=e.scheme,a=e.contextUrl,i=void 0===a?"":a,s=kt.parse(i),l=Array.isArray(n.schemes)?n.schemes[0]:null,u=o||l||Br(s.protocol)||"http",c=n.host||s.host||"",p=n.basePath||"";return"/"===(t=u&&c?j()(r="".concat(u,"://")).call(r,c+p):p)[t.length-1]?$()(t).call(t,0,-1):t}(x)),!o)return delete w.cookies,w;w.url+=O,w.method="".concat(k).toUpperCase(),v=v||{};var I=n.paths[O]||{};i&&(w.headers.accept=i);var N=function(e){var t={};e.forEach((function(e){t[e.in]||(t[e.in]={}),t[e.in][e.name]=e}));var r=[];return C()(t).forEach((function(e){C()(t[e]).forEach((function(n){r.push(t[e][n])}))})),r}(j()(t=j()(r=[]).call(r,Pr(S.parameters))).call(t,Pr(I.parameters)));N.forEach((function(e){var t,r,o=y[e.in];if("body"===e.in&&e.schema&&e.schema.properties&&(t=v),void 0===(t=e&&e.name&&v[e.name]))t=e&&e.name&&v[j()(r="".concat(e.in,".")).call(r,e.name)];else if(function(e,t){return P()(t).call(t,(function(t){return t.name===e}))}(e.name,N).length>1){var a;console.warn(j()(a="Parameter '".concat(e.name,"' is ambiguous because the defined spec has more than one parameter with the name: '")).call(a,e.name,"' and the passed-in parameter values did not define an 'in' value."))}if(null!==t){if(void 0!==e.default&&void 0===t&&(t=e.default),void 0===t&&e.required&&!e.allowEmptyValue)throw new Error("Required parameter ".concat(e.name," is not provided"));if(b&&e.schema&&"object"===e.schema.type&&"string"==typeof t)try{t=JSON.parse(t)}catch(e){throw new Error("Could not parse object parameter value string as JSON")}o&&o({req:w,parameter:e,value:t,operation:S,spec:n})}}));var T=me()(me()({},e),{},{operation:S});if((w=b?Ir(T,w):Nr(T,w)).cookies&&C()(w.cookies).length){var R=C()(w.cookies).reduce((function(e,t){var r=w.cookies[t];return e+(e?"&":"")+vr.serialize(t,r)}),"");w.headers.Cookie=R}return w.cookies&&delete w.cookies,fe(w),w}var Br=function(e){return e?e.replace(/\W/g,""):null};function Fr(e,t){return zr.apply(this,arguments)}function zr(){return zr=s()(u().mark((function e(t,r){var n,o,a,i,s,l,c,p,f,h,d,m,g=arguments;return u().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n=g.length>2&&void 0!==g[2]?g[2]:{},o=n.returnEntireTree,a=n.baseDoc,i=n.requestInterceptor,s=n.responseInterceptor,l=n.parameterMacro,c=n.modelPropertyMacro,p=n.useCircularStructures,f={pathDiscriminator:r,baseDoc:a,requestInterceptor:i,responseInterceptor:s,parameterMacro:l,modelPropertyMacro:c,useCircularStructures:p},h=(0,cr.K1)({spec:t}),d=h.spec,e.next=6,fr(me()(me()({},f),{},{spec:d,allowMetaPatches:!0,skipNormalization:!0}));case 6:return m=e.sent,!o&&Array.isArray(r)&&r.length&&(m.spec=gr()(m.spec,r)||null),e.abrupt("return",m);case 9:case"end":return e.stop()}}),e)}))),zr.apply(this,arguments)}var Ur=r(34852);function qr(e){let{configs:t,getConfigs:r}=e;return{fn:{fetch:(n=Y,o=t.preFetch,a=t.postFetch,a=a||function(e){return e},o=o||function(e){return e},function(e){return"string"==typeof e&&(e={url:e}),Z.mergeInQueryOrForm(e),e=o(e),a(n(e))}),buildRequest:Lr,execute:Dr,resolve:fr,resolveSubtree:function(e,t,n){if(void 0===n){const e=r();n={modelPropertyMacro:e.modelPropertyMacro,parameterMacro:e.parameterMacro,requestInterceptor:e.requestInterceptor,responseInterceptor:e.responseInterceptor}}for(var o=arguments.length,a=new Array(o>3?o-3:0),i=3;i{"use strict";r.r(t),r.d(t,{default:()=>o});var n=r(90242);function o(){return{fn:{shallowEqualKeys:n.be}}}},48347:(e,t,r)=>{"use strict";r.r(t),r.d(t,{getDisplayName:()=>n});const n=e=>e.displayName||e.name||"Component"},73420:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>u});var n=r(35627),o=r.n(n),a=r(90242),i=r(55776),s=r(48347),l=r(60314);const u=e=>{let{getComponents:t,getStore:r,getSystem:n}=e;const u=(c=(0,i.getComponent)(n,r,t),(0,a.HP)(c,(function(){for(var e=arguments.length,t=new Array(e),r=0;r(0,l.Z)(e,(function(){for(var e=arguments.length,t=new Array(e),r=0;r{"use strict";r.r(t),r.d(t,{getComponent:()=>ne,render:()=>re,withMappedContainer:()=>te});var n=r(23101),o=r.n(n),a=r(28222),i=r.n(a),s=r(67294),l=r(73935),u=r(97779),c=s.createContext(null);var p=function(e){e()},f=function(){return p},h={notify:function(){}};var d=function(){function e(e,t){this.store=e,this.parentSub=t,this.unsubscribe=null,this.listeners=h,this.handleChangeWrapper=this.handleChangeWrapper.bind(this)}var t=e.prototype;return t.addNestedSub=function(e){return this.trySubscribe(),this.listeners.subscribe(e)},t.notifyNestedSubs=function(){this.listeners.notify()},t.handleChangeWrapper=function(){this.onStateChange&&this.onStateChange()},t.isSubscribed=function(){return Boolean(this.unsubscribe)},t.trySubscribe=function(){this.unsubscribe||(this.unsubscribe=this.parentSub?this.parentSub.addNestedSub(this.handleChangeWrapper):this.store.subscribe(this.handleChangeWrapper),this.listeners=function(){var e=f(),t=null,r=null;return{clear:function(){t=null,r=null},notify:function(){e((function(){for(var e=t;e;)e.callback(),e=e.next}))},get:function(){for(var e=[],r=t;r;)e.push(r),r=r.next;return e},subscribe:function(e){var n=!0,o=r={callback:e,next:null,prev:r};return o.prev?o.prev.next=o:t=o,function(){n&&null!==t&&(n=!1,o.next?o.next.prev=o.prev:r=o.prev,o.prev?o.prev.next=o.next:t=o.next)}}}}())},t.tryUnsubscribe=function(){this.unsubscribe&&(this.unsubscribe(),this.unsubscribe=null,this.listeners.clear(),this.listeners=h)},e}(),m="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement?s.useLayoutEffect:s.useEffect;const g=function(e){var t=e.store,r=e.context,n=e.children,o=(0,s.useMemo)((function(){var e=new d(t);return e.onStateChange=e.notifyNestedSubs,{store:t,subscription:e}}),[t]),a=(0,s.useMemo)((function(){return t.getState()}),[t]);m((function(){var e=o.subscription;return e.trySubscribe(),a!==t.getState()&&e.notifyNestedSubs(),function(){e.tryUnsubscribe(),e.onStateChange=null}}),[o,a]);var i=r||c;return s.createElement(i.Provider,{value:o},n)};var v=r(87462),y=r(63366),b=r(8679),w=r.n(b),E=r(72973),x=[],_=[null,null];function S(e,t){var r=e[1];return[t.payload,r+1]}function A(e,t,r){m((function(){return e.apply(void 0,t)}),r)}function k(e,t,r,n,o,a,i){e.current=n,t.current=o,r.current=!1,a.current&&(a.current=null,i())}function C(e,t,r,n,o,a,i,s,l,u){if(e){var c=!1,p=null,f=function(){if(!c){var e,r,f=t.getState();try{e=n(f,o.current)}catch(e){r=e,p=e}r||(p=null),e===a.current?i.current||l():(a.current=e,s.current=e,i.current=!0,u({type:"STORE_UPDATED",payload:{error:r}}))}};r.onStateChange=f,r.trySubscribe(),f();return function(){if(c=!0,r.tryUnsubscribe(),r.onStateChange=null,p)throw p}}}var O=function(){return[null,0]};function j(e,t){void 0===t&&(t={});var r=t,n=r.getDisplayName,o=void 0===n?function(e){return"ConnectAdvanced("+e+")"}:n,a=r.methodName,i=void 0===a?"connectAdvanced":a,l=r.renderCountProp,u=void 0===l?void 0:l,p=r.shouldHandleStateChanges,f=void 0===p||p,h=r.storeKey,m=void 0===h?"store":h,g=(r.withRef,r.forwardRef),b=void 0!==g&&g,j=r.context,I=void 0===j?c:j,N=(0,y.Z)(r,["getDisplayName","methodName","renderCountProp","shouldHandleStateChanges","storeKey","withRef","forwardRef","context"]),T=I;return function(t){var r=t.displayName||t.name||"Component",n=o(r),a=(0,v.Z)({},N,{getDisplayName:o,methodName:i,renderCountProp:u,shouldHandleStateChanges:f,storeKey:m,displayName:n,wrappedComponentName:r,WrappedComponent:t}),l=N.pure;var c=l?s.useMemo:function(e){return e()};function p(r){var n=(0,s.useMemo)((function(){var e=r.reactReduxForwardedRef,t=(0,y.Z)(r,["reactReduxForwardedRef"]);return[r.context,e,t]}),[r]),o=n[0],i=n[1],l=n[2],u=(0,s.useMemo)((function(){return o&&o.Consumer&&(0,E.isContextConsumer)(s.createElement(o.Consumer,null))?o:T}),[o,T]),p=(0,s.useContext)(u),h=Boolean(r.store)&&Boolean(r.store.getState)&&Boolean(r.store.dispatch);Boolean(p)&&Boolean(p.store);var m=h?r.store:p.store,g=(0,s.useMemo)((function(){return function(t){return e(t.dispatch,a)}(m)}),[m]),b=(0,s.useMemo)((function(){if(!f)return _;var e=new d(m,h?null:p.subscription),t=e.notifyNestedSubs.bind(e);return[e,t]}),[m,h,p]),w=b[0],j=b[1],I=(0,s.useMemo)((function(){return h?p:(0,v.Z)({},p,{subscription:w})}),[h,p,w]),N=(0,s.useReducer)(S,x,O),P=N[0][0],R=N[1];if(P&&P.error)throw P.error;var M=(0,s.useRef)(),D=(0,s.useRef)(l),L=(0,s.useRef)(),B=(0,s.useRef)(!1),F=c((function(){return L.current&&l===D.current?L.current:g(m.getState(),l)}),[m,P,l]);A(k,[D,M,B,l,F,L,j]),A(C,[f,m,w,g,D,M,B,L,j,R],[m,w,g]);var z=(0,s.useMemo)((function(){return s.createElement(t,(0,v.Z)({},F,{ref:i}))}),[i,t,F]);return(0,s.useMemo)((function(){return f?s.createElement(u.Provider,{value:I},z):z}),[u,z,I])}var h=l?s.memo(p):p;if(h.WrappedComponent=t,h.displayName=p.displayName=n,b){var g=s.forwardRef((function(e,t){return s.createElement(h,(0,v.Z)({},e,{reactReduxForwardedRef:t}))}));return g.displayName=n,g.WrappedComponent=t,w()(g,t)}return w()(h,t)}}function I(e,t){return e===t?0!==e||0!==t||1/e==1/t:e!=e&&t!=t}function N(e,t){if(I(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;var r=Object.keys(e),n=Object.keys(t);if(r.length!==n.length)return!1;for(var o=0;o=0;n--){var o=t[n](e);if(o)return o}return function(t,n){throw new Error("Invalid value of type "+typeof e+" for "+r+" argument when connecting component "+n.wrappedComponentName+".")}}function V(e,t){return e===t}function $(e){var t=void 0===e?{}:e,r=t.connectHOC,n=void 0===r?j:r,o=t.mapStateToPropsFactories,a=void 0===o?D:o,i=t.mapDispatchToPropsFactories,s=void 0===i?M:i,l=t.mergePropsFactories,u=void 0===l?B:l,c=t.selectorFactory,p=void 0===c?U:c;return function(e,t,r,o){void 0===o&&(o={});var i=o,l=i.pure,c=void 0===l||l,f=i.areStatesEqual,h=void 0===f?V:f,d=i.areOwnPropsEqual,m=void 0===d?N:d,g=i.areStatePropsEqual,b=void 0===g?N:g,w=i.areMergedPropsEqual,E=void 0===w?N:w,x=(0,y.Z)(i,["pure","areStatesEqual","areOwnPropsEqual","areStatePropsEqual","areMergedPropsEqual"]),_=q(e,a,"mapStateToProps"),S=q(t,s,"mapDispatchToProps"),A=q(r,u,"mergeProps");return n(p,(0,v.Z)({methodName:"connect",getDisplayName:function(e){return"Connect("+e+")"},shouldHandleStateChanges:Boolean(e),initMapStateToProps:_,initMapDispatchToProps:S,initMergeProps:A,pure:c,areStatesEqual:h,areOwnPropsEqual:m,areStatePropsEqual:b,areMergedPropsEqual:E},x))}}const W=$();var H;H=l.unstable_batchedUpdates,p=H;var J=r(57557),K=r.n(J),G=r(6557),Z=r.n(G);const Y=e=>t=>{const{fn:r}=e();class n extends s.Component{render(){return s.createElement(t,o()({},e(),this.props,this.context))}}return n.displayName=`WithSystem(${r.getDisplayName(t)})`,n},Q=(e,t)=>r=>{const{fn:n}=e();class a extends s.Component{render(){return s.createElement(g,{store:t},s.createElement(r,o()({},this.props,this.context)))}}return a.displayName=`WithRoot(${n.getDisplayName(r)})`,a},X=(e,t,r)=>(0,u.qC)(r?Q(e,r):Z(),W(((r,n)=>{var o;const a={...n,...e()},i=(null===(o=t.prototype)||void 0===o?void 0:o.mapStateToProps)||(e=>({state:e}));return i(r,a)})),Y(e))(t),ee=(e,t,r,n)=>{for(const o in t){const a=t[o];"function"==typeof a&&a(r[o],n[o],e())}},te=(e,t,r)=>(t,n)=>{const{fn:o}=e(),a=r(t,"root");class l extends s.Component{constructor(t,r){super(t,r),ee(e,n,t,{})}UNSAFE_componentWillReceiveProps(t){ee(e,n,t,this.props)}render(){const e=K()(this.props,n?i()(n):[]);return s.createElement(a,e)}}return l.displayName=`WithMappedContainer(${o.getDisplayName(a)})`,l},re=(e,t,r,n)=>o=>{const a=r(e,t,n)("App","root");l.render(s.createElement(a,null),o)},ne=(e,t,r)=>function(n,o){let a=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if("string"!=typeof n)throw new TypeError("Need a string, to fetch a component. Was given a "+typeof n);const i=r(n);return i?o?"root"===o?X(e,i,t()):X(e,i):i:(a.failSilently||e().log.warn("Could not find component:",n),null)}},36581:(e,t,r)=>{"use strict";r.d(t,{d3:()=>T,C2:()=>Z});var n=r(28222),o=r.n(n),a=r(58118),i=r.n(a),s=r(63366);function l(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r=4?[t[0],t[1],t[2],t[3],"".concat(t[0],".").concat(t[1]),"".concat(t[0],".").concat(t[2]),"".concat(t[0],".").concat(t[3]),"".concat(t[1],".").concat(t[0]),"".concat(t[1],".").concat(t[2]),"".concat(t[1],".").concat(t[3]),"".concat(t[2],".").concat(t[0]),"".concat(t[2],".").concat(t[1]),"".concat(t[2],".").concat(t[3]),"".concat(t[3],".").concat(t[0]),"".concat(t[3],".").concat(t[1]),"".concat(t[3],".").concat(t[2]),"".concat(t[0],".").concat(t[1],".").concat(t[2]),"".concat(t[0],".").concat(t[1],".").concat(t[3]),"".concat(t[0],".").concat(t[2],".").concat(t[1]),"".concat(t[0],".").concat(t[2],".").concat(t[3]),"".concat(t[0],".").concat(t[3],".").concat(t[1]),"".concat(t[0],".").concat(t[3],".").concat(t[2]),"".concat(t[1],".").concat(t[0],".").concat(t[2]),"".concat(t[1],".").concat(t[0],".").concat(t[3]),"".concat(t[1],".").concat(t[2],".").concat(t[0]),"".concat(t[1],".").concat(t[2],".").concat(t[3]),"".concat(t[1],".").concat(t[3],".").concat(t[0]),"".concat(t[1],".").concat(t[3],".").concat(t[2]),"".concat(t[2],".").concat(t[0],".").concat(t[1]),"".concat(t[2],".").concat(t[0],".").concat(t[3]),"".concat(t[2],".").concat(t[1],".").concat(t[0]),"".concat(t[2],".").concat(t[1],".").concat(t[3]),"".concat(t[2],".").concat(t[3],".").concat(t[0]),"".concat(t[2],".").concat(t[3],".").concat(t[1]),"".concat(t[3],".").concat(t[0],".").concat(t[1]),"".concat(t[3],".").concat(t[0],".").concat(t[2]),"".concat(t[3],".").concat(t[1],".").concat(t[0]),"".concat(t[3],".").concat(t[1],".").concat(t[2]),"".concat(t[3],".").concat(t[2],".").concat(t[0]),"".concat(t[3],".").concat(t[2],".").concat(t[1]),"".concat(t[0],".").concat(t[1],".").concat(t[2],".").concat(t[3]),"".concat(t[0],".").concat(t[1],".").concat(t[3],".").concat(t[2]),"".concat(t[0],".").concat(t[2],".").concat(t[1],".").concat(t[3]),"".concat(t[0],".").concat(t[2],".").concat(t[3],".").concat(t[1]),"".concat(t[0],".").concat(t[3],".").concat(t[1],".").concat(t[2]),"".concat(t[0],".").concat(t[3],".").concat(t[2],".").concat(t[1]),"".concat(t[1],".").concat(t[0],".").concat(t[2],".").concat(t[3]),"".concat(t[1],".").concat(t[0],".").concat(t[3],".").concat(t[2]),"".concat(t[1],".").concat(t[2],".").concat(t[0],".").concat(t[3]),"".concat(t[1],".").concat(t[2],".").concat(t[3],".").concat(t[0]),"".concat(t[1],".").concat(t[3],".").concat(t[0],".").concat(t[2]),"".concat(t[1],".").concat(t[3],".").concat(t[2],".").concat(t[0]),"".concat(t[2],".").concat(t[0],".").concat(t[1],".").concat(t[3]),"".concat(t[2],".").concat(t[0],".").concat(t[3],".").concat(t[1]),"".concat(t[2],".").concat(t[1],".").concat(t[0],".").concat(t[3]),"".concat(t[2],".").concat(t[1],".").concat(t[3],".").concat(t[0]),"".concat(t[2],".").concat(t[3],".").concat(t[0],".").concat(t[1]),"".concat(t[2],".").concat(t[3],".").concat(t[1],".").concat(t[0]),"".concat(t[3],".").concat(t[0],".").concat(t[1],".").concat(t[2]),"".concat(t[3],".").concat(t[0],".").concat(t[2],".").concat(t[1]),"".concat(t[3],".").concat(t[1],".").concat(t[0],".").concat(t[2]),"".concat(t[3],".").concat(t[1],".").concat(t[2],".").concat(t[0]),"".concat(t[3],".").concat(t[2],".").concat(t[0],".").concat(t[1]),"".concat(t[3],".").concat(t[2],".").concat(t[1],".").concat(t[0])]:void 0),d[n]}function g(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=arguments.length>2?arguments[2]:void 0,n=e.filter((function(e){return"token"!==e})),o=m(n);return o.reduce((function(e,t){return p({},e,r[t])}),t)}function v(e){return e.join(" ")}function y(e){var t=e.node,r=e.stylesheet,n=e.style,o=void 0===n?{}:n,a=e.useInlineStyles,i=e.key,s=t.properties,l=t.type,u=t.tagName,c=t.value;if("text"===l)return c;if(u){var d,m=function(e,t){var r=0;return function(n){return r+=1,n.map((function(n,o){return y({node:n,stylesheet:e,useInlineStyles:t,key:"code-segment-".concat(r,"-").concat(o)})}))}}(r,a);if(a){var b=Object.keys(r).reduce((function(e,t){return t.split(".").forEach((function(t){e.includes(t)||e.push(t)})),e}),[]),w=s.className&&s.className.includes("token")?["token"]:[],E=s.className&&w.concat(s.className.filter((function(e){return!b.includes(e)})));d=p({},s,{className:v(E)||void 0,style:g(s.className,Object.assign({},s.style,o),r)})}else d=p({},s,{className:v(s.className)});var x=m(t.children);return f.createElement(u,(0,h.Z)({key:i},d),x)}}var b=/\n/g;function w(e){var t=e.codeString,r=e.codeStyle,n=e.containerStyle,o=void 0===n?{float:"left",paddingRight:"10px"}:n,a=e.numberStyle,i=void 0===a?{}:a,s=e.startingLineNumber;return f.createElement("code",{style:Object.assign({},r,o)},function(e){var t=e.lines,r=e.startingLineNumber,n=e.style;return t.map((function(e,t){var o=t+r;return f.createElement("span",{key:"line-".concat(t),className:"react-syntax-highlighter-line-number",style:"function"==typeof n?n(o):n},"".concat(o,"\n"))}))}({lines:t.replace(/\n$/,"").split("\n"),style:i,startingLineNumber:s}))}function E(e,t){return{type:"element",tagName:"span",properties:{key:"line-number--".concat(e),className:["comment","linenumber","react-syntax-highlighter-line-number"],style:t},children:[{type:"text",value:e}]}}function x(e,t,r){var n;return p({},{display:"inline-block",minWidth:(n=r,"".concat(n.toString().length,".25em")),paddingRight:"1em",textAlign:"right",userSelect:"none"},"function"==typeof e?e(t):e)}function _(e){var t=e.children,r=e.lineNumber,n=e.lineNumberStyle,o=e.largestLineNumber,a=e.showInlineLineNumbers,i=e.lineProps,s=void 0===i?{}:i,l=e.className,u=void 0===l?[]:l,c=e.showLineNumbers,f=e.wrapLongLines,h="function"==typeof s?s(r):s;if(h.className=u,r&&a){var d=x(n,r,o);t.unshift(E(r,d))}return f&c&&(h.style=p({},h.style,{display:"flex"})),{type:"element",tagName:"span",properties:h,children:t}}function S(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],n=0;n2&&void 0!==arguments[2]?arguments[2]:[];return _({children:e,lineNumber:t,lineNumberStyle:s,largestLineNumber:i,showInlineLineNumbers:o,lineProps:r,className:a,showLineNumbers:n,wrapLongLines:l})}function m(e,t){if(n&&t&&o){var r=x(s,t,i);e.unshift(E(t,r))}return e}function g(e,r){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[];return t||n.length>0?d(e,r,n):m(e,r)}for(var v=function(){var e=c[h],t=e.children[0].value;if(t.match(b)){var r=t.split("\n");r.forEach((function(t,o){var i=n&&p.length+a,s={type:"text",value:"".concat(t,"\n")};if(0===o){var l=g(c.slice(f+1,h).concat(_({children:[s],className:e.properties.className})),i);p.push(l)}else if(o===r.length-1){if(c[h+1]&&c[h+1].children&&c[h+1].children[0]){var u=_({children:[{type:"text",value:"".concat(t)}],className:e.properties.className});c.splice(h+1,0,u)}else{var d=g([s],i,e.properties.className);p.push(d)}}else{var m=g([s],i,e.properties.className);p.push(m)}})),f=h}h++};h=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}(e,["language","children","style","customStyle","codeTagProps","useInlineStyles","showLineNumbers","showInlineLineNumbers","startingLineNumber","lineNumberContainerStyle","lineNumberStyle","wrapLines","wrapLongLines","lineProps","renderer","PreTag","CodeTag","code","astGenerator"]);U=U||O;var V=m?f.createElement(w,{containerStyle:E,codeStyle:u.style||{},numberStyle:_,startingLineNumber:b,codeString:z}):null,$=o.hljs||o['pre[class*="language-"]']||{backgroundColor:"#fff"},W=C(U)?"hljs":"prismjs",H=h?Object.assign({},q,{style:Object.assign({},$,i)}):Object.assign({},q,{className:q.className?"".concat(W," ").concat(q.className):W,style:Object.assign({},i)});if(!U)return f.createElement(D,H,V,f.createElement(B,u,z));(void 0===S&&R||N)&&(S=!0),R=R||k;var J=[{type:"text",value:z}],K=function(e){var t=e.astGenerator,r=e.language,n=e.code,o=e.defaultCodeValue;if(C(t)){var a=function(e,t){return-1!==e.listLanguages().indexOf(t)}(t,r);return"text"===r?{value:o,language:"text"}:a?t.highlight(r,n):t.highlightAuto(n)}try{return r&&"text"!==r?{value:t.highlight(n,r)}:{value:o}}catch(e){return{value:o}}}({astGenerator:U,language:t,code:z,defaultCodeValue:J});null===K.language&&(K.value=J);var G=A(K,S,P,m,v,b,K.value.length+b,_,N);return u.style=p({},u.style,N?{whiteSpace:"pre-wrap"}:{whiteSpace:"pre"}),f.createElement(D,H,f.createElement(B,u,!v&&V,R({rows:G,stylesheet:o,useInlineStyles:h})))});N.registerLanguage=I.registerLanguage;const T=N;var P=r(96344);const R=r.n(P)();var M=r(82026);const D=r.n(M)();var L=r(42157);const B=r.n(L)();var F=r(61519);const z=r.n(F)();var U=r(54587);const q=r.n(U)();var V=r(30786);const $=r.n(V)();var W=r(66336);const H=r.n(W)(),J={hljs:{display:"block",overflowX:"auto",padding:"0.5em",background:"#333",color:"white"},"hljs-name":{fontWeight:"bold"},"hljs-strong":{fontWeight:"bold"},"hljs-code":{fontStyle:"italic",color:"#888"},"hljs-emphasis":{fontStyle:"italic"},"hljs-tag":{color:"#62c8f3"},"hljs-variable":{color:"#ade5fc"},"hljs-template-variable":{color:"#ade5fc"},"hljs-selector-id":{color:"#ade5fc"},"hljs-selector-class":{color:"#ade5fc"},"hljs-string":{color:"#a2fca2"},"hljs-bullet":{color:"#d36363"},"hljs-type":{color:"#ffa"},"hljs-title":{color:"#ffa"},"hljs-section":{color:"#ffa"},"hljs-attribute":{color:"#ffa"},"hljs-quote":{color:"#ffa"},"hljs-built_in":{color:"#ffa"},"hljs-builtin-name":{color:"#ffa"},"hljs-number":{color:"#d36363"},"hljs-symbol":{color:"#d36363"},"hljs-keyword":{color:"#fcc28c"},"hljs-selector-tag":{color:"#fcc28c"},"hljs-literal":{color:"#fcc28c"},"hljs-comment":{color:"#888"},"hljs-deletion":{color:"#333",backgroundColor:"#fc9b9b"},"hljs-regexp":{color:"#c6b4f0"},"hljs-link":{color:"#c6b4f0"},"hljs-meta":{color:"#fc9b9b"},"hljs-addition":{backgroundColor:"#a2fca2",color:"#333"}};T.registerLanguage("json",D),T.registerLanguage("js",R),T.registerLanguage("xml",B),T.registerLanguage("yaml",q),T.registerLanguage("http",$),T.registerLanguage("bash",z),T.registerLanguage("powershell",H),T.registerLanguage("javascript",R);const K={agate:J,arta:{hljs:{display:"block",overflowX:"auto",padding:"0.5em",background:"#222",color:"#aaa"},"hljs-subst":{color:"#aaa"},"hljs-section":{color:"#fff",fontWeight:"bold"},"hljs-comment":{color:"#444"},"hljs-quote":{color:"#444"},"hljs-meta":{color:"#444"},"hljs-string":{color:"#ffcc33"},"hljs-symbol":{color:"#ffcc33"},"hljs-bullet":{color:"#ffcc33"},"hljs-regexp":{color:"#ffcc33"},"hljs-number":{color:"#00cc66"},"hljs-addition":{color:"#00cc66"},"hljs-built_in":{color:"#32aaee"},"hljs-builtin-name":{color:"#32aaee"},"hljs-literal":{color:"#32aaee"},"hljs-type":{color:"#32aaee"},"hljs-template-variable":{color:"#32aaee"},"hljs-attribute":{color:"#32aaee"},"hljs-link":{color:"#32aaee"},"hljs-keyword":{color:"#6644aa"},"hljs-selector-tag":{color:"#6644aa"},"hljs-name":{color:"#6644aa"},"hljs-selector-id":{color:"#6644aa"},"hljs-selector-class":{color:"#6644aa"},"hljs-title":{color:"#bb1166"},"hljs-variable":{color:"#bb1166"},"hljs-deletion":{color:"#bb1166"},"hljs-template-tag":{color:"#bb1166"},"hljs-doctag":{fontWeight:"bold"},"hljs-strong":{fontWeight:"bold"},"hljs-emphasis":{fontStyle:"italic"}},monokai:{hljs:{display:"block",overflowX:"auto",padding:"0.5em",background:"#272822",color:"#ddd"},"hljs-tag":{color:"#f92672"},"hljs-keyword":{color:"#f92672",fontWeight:"bold"},"hljs-selector-tag":{color:"#f92672",fontWeight:"bold"},"hljs-literal":{color:"#f92672",fontWeight:"bold"},"hljs-strong":{color:"#f92672"},"hljs-name":{color:"#f92672"},"hljs-code":{color:"#66d9ef"},"hljs-class .hljs-title":{color:"white"},"hljs-attribute":{color:"#bf79db"},"hljs-symbol":{color:"#bf79db"},"hljs-regexp":{color:"#bf79db"},"hljs-link":{color:"#bf79db"},"hljs-string":{color:"#a6e22e"},"hljs-bullet":{color:"#a6e22e"},"hljs-subst":{color:"#a6e22e"},"hljs-title":{color:"#a6e22e",fontWeight:"bold"},"hljs-section":{color:"#a6e22e",fontWeight:"bold"},"hljs-emphasis":{color:"#a6e22e"},"hljs-type":{color:"#a6e22e",fontWeight:"bold"},"hljs-built_in":{color:"#a6e22e"},"hljs-builtin-name":{color:"#a6e22e"},"hljs-selector-attr":{color:"#a6e22e"},"hljs-selector-pseudo":{color:"#a6e22e"},"hljs-addition":{color:"#a6e22e"},"hljs-variable":{color:"#a6e22e"},"hljs-template-tag":{color:"#a6e22e"},"hljs-template-variable":{color:"#a6e22e"},"hljs-comment":{color:"#75715e"},"hljs-quote":{color:"#75715e"},"hljs-deletion":{color:"#75715e"},"hljs-meta":{color:"#75715e"},"hljs-doctag":{fontWeight:"bold"},"hljs-selector-id":{fontWeight:"bold"}},nord:{hljs:{display:"block",overflowX:"auto",padding:"0.5em",background:"#2E3440",color:"#D8DEE9"},"hljs-subst":{color:"#D8DEE9"},"hljs-selector-tag":{color:"#81A1C1"},"hljs-selector-id":{color:"#8FBCBB",fontWeight:"bold"},"hljs-selector-class":{color:"#8FBCBB"},"hljs-selector-attr":{color:"#8FBCBB"},"hljs-selector-pseudo":{color:"#88C0D0"},"hljs-addition":{backgroundColor:"rgba(163, 190, 140, 0.5)"},"hljs-deletion":{backgroundColor:"rgba(191, 97, 106, 0.5)"},"hljs-built_in":{color:"#8FBCBB"},"hljs-type":{color:"#8FBCBB"},"hljs-class":{color:"#8FBCBB"},"hljs-function":{color:"#88C0D0"},"hljs-function > .hljs-title":{color:"#88C0D0"},"hljs-keyword":{color:"#81A1C1"},"hljs-literal":{color:"#81A1C1"},"hljs-symbol":{color:"#81A1C1"},"hljs-number":{color:"#B48EAD"},"hljs-regexp":{color:"#EBCB8B"},"hljs-string":{color:"#A3BE8C"},"hljs-title":{color:"#8FBCBB"},"hljs-params":{color:"#D8DEE9"},"hljs-bullet":{color:"#81A1C1"},"hljs-code":{color:"#8FBCBB"},"hljs-emphasis":{fontStyle:"italic"},"hljs-formula":{color:"#8FBCBB"},"hljs-strong":{fontWeight:"bold"},"hljs-link:hover":{textDecoration:"underline"},"hljs-quote":{color:"#4C566A"},"hljs-comment":{color:"#4C566A"},"hljs-doctag":{color:"#8FBCBB"},"hljs-meta":{color:"#5E81AC"},"hljs-meta-keyword":{color:"#5E81AC"},"hljs-meta-string":{color:"#A3BE8C"},"hljs-attr":{color:"#8FBCBB"},"hljs-attribute":{color:"#D8DEE9"},"hljs-builtin-name":{color:"#81A1C1"},"hljs-name":{color:"#81A1C1"},"hljs-section":{color:"#88C0D0"},"hljs-tag":{color:"#81A1C1"},"hljs-variable":{color:"#D8DEE9"},"hljs-template-variable":{color:"#D8DEE9"},"hljs-template-tag":{color:"#5E81AC"},"abnf .hljs-attribute":{color:"#88C0D0"},"abnf .hljs-symbol":{color:"#EBCB8B"},"apache .hljs-attribute":{color:"#88C0D0"},"apache .hljs-section":{color:"#81A1C1"},"arduino .hljs-built_in":{color:"#88C0D0"},"aspectj .hljs-meta":{color:"#D08770"},"aspectj > .hljs-title":{color:"#88C0D0"},"bnf .hljs-attribute":{color:"#8FBCBB"},"clojure .hljs-name":{color:"#88C0D0"},"clojure .hljs-symbol":{color:"#EBCB8B"},"coq .hljs-built_in":{color:"#88C0D0"},"cpp .hljs-meta-string":{color:"#8FBCBB"},"css .hljs-built_in":{color:"#88C0D0"},"css .hljs-keyword":{color:"#D08770"},"diff .hljs-meta":{color:"#8FBCBB"},"ebnf .hljs-attribute":{color:"#8FBCBB"},"glsl .hljs-built_in":{color:"#88C0D0"},"groovy .hljs-meta:not(:first-child)":{color:"#D08770"},"haxe .hljs-meta":{color:"#D08770"},"java .hljs-meta":{color:"#D08770"},"ldif .hljs-attribute":{color:"#8FBCBB"},"lisp .hljs-name":{color:"#88C0D0"},"lua .hljs-built_in":{color:"#88C0D0"},"moonscript .hljs-built_in":{color:"#88C0D0"},"nginx .hljs-attribute":{color:"#88C0D0"},"nginx .hljs-section":{color:"#5E81AC"},"pf .hljs-built_in":{color:"#88C0D0"},"processing .hljs-built_in":{color:"#88C0D0"},"scss .hljs-keyword":{color:"#81A1C1"},"stylus .hljs-keyword":{color:"#81A1C1"},"swift .hljs-meta":{color:"#D08770"},"vim .hljs-built_in":{color:"#88C0D0",fontStyle:"italic"},"yaml .hljs-meta":{color:"#D08770"}},obsidian:{hljs:{display:"block",overflowX:"auto",padding:"0.5em",background:"#282b2e",color:"#e0e2e4"},"hljs-keyword":{color:"#93c763",fontWeight:"bold"},"hljs-selector-tag":{color:"#93c763",fontWeight:"bold"},"hljs-literal":{color:"#93c763",fontWeight:"bold"},"hljs-selector-id":{color:"#93c763"},"hljs-number":{color:"#ffcd22"},"hljs-attribute":{color:"#668bb0"},"hljs-code":{color:"white"},"hljs-class .hljs-title":{color:"white"},"hljs-section":{color:"white",fontWeight:"bold"},"hljs-regexp":{color:"#d39745"},"hljs-link":{color:"#d39745"},"hljs-meta":{color:"#557182"},"hljs-tag":{color:"#8cbbad"},"hljs-name":{color:"#8cbbad",fontWeight:"bold"},"hljs-bullet":{color:"#8cbbad"},"hljs-subst":{color:"#8cbbad"},"hljs-emphasis":{color:"#8cbbad"},"hljs-type":{color:"#8cbbad",fontWeight:"bold"},"hljs-built_in":{color:"#8cbbad"},"hljs-selector-attr":{color:"#8cbbad"},"hljs-selector-pseudo":{color:"#8cbbad"},"hljs-addition":{color:"#8cbbad"},"hljs-variable":{color:"#8cbbad"},"hljs-template-tag":{color:"#8cbbad"},"hljs-template-variable":{color:"#8cbbad"},"hljs-string":{color:"#ec7600"},"hljs-symbol":{color:"#ec7600"},"hljs-comment":{color:"#818e96"},"hljs-quote":{color:"#818e96"},"hljs-deletion":{color:"#818e96"},"hljs-selector-class":{color:"#A082BD"},"hljs-doctag":{fontWeight:"bold"},"hljs-title":{fontWeight:"bold"},"hljs-strong":{fontWeight:"bold"}},"tomorrow-night":{"hljs-comment":{color:"#969896"},"hljs-quote":{color:"#969896"},"hljs-variable":{color:"#cc6666"},"hljs-template-variable":{color:"#cc6666"},"hljs-tag":{color:"#cc6666"},"hljs-name":{color:"#cc6666"},"hljs-selector-id":{color:"#cc6666"},"hljs-selector-class":{color:"#cc6666"},"hljs-regexp":{color:"#cc6666"},"hljs-deletion":{color:"#cc6666"},"hljs-number":{color:"#de935f"},"hljs-built_in":{color:"#de935f"},"hljs-builtin-name":{color:"#de935f"},"hljs-literal":{color:"#de935f"},"hljs-type":{color:"#de935f"},"hljs-params":{color:"#de935f"},"hljs-meta":{color:"#de935f"},"hljs-link":{color:"#de935f"},"hljs-attribute":{color:"#f0c674"},"hljs-string":{color:"#b5bd68"},"hljs-symbol":{color:"#b5bd68"},"hljs-bullet":{color:"#b5bd68"},"hljs-addition":{color:"#b5bd68"},"hljs-title":{color:"#81a2be"},"hljs-section":{color:"#81a2be"},"hljs-keyword":{color:"#b294bb"},"hljs-selector-tag":{color:"#b294bb"},hljs:{display:"block",overflowX:"auto",background:"#1d1f21",color:"#c5c8c6",padding:"0.5em"},"hljs-emphasis":{fontStyle:"italic"},"hljs-strong":{fontWeight:"bold"}}},G=o()(K),Z=e=>i()(G).call(G,e)?K[e]:(console.warn(`Request style '${e}' is not available, returning default instead`),J)},90242:(e,t,r)=>{"use strict";r.d(t,{mz:()=>pe,oG:()=>fe,AF:()=>he,LQ:()=>de,Kn:()=>me,Wl:()=>ge,kJ:()=>ve,HP:()=>ye,Ay:()=>be,Q2:()=>we,_5:()=>Ee,iQ:()=>xe,gp:()=>_e,DR:()=>Se,Zl:()=>Ae,Ik:()=>Ce,xi:()=>Pe,UG:()=>Re,r3:()=>Me,wh:()=>De,GZ:()=>Le,be:()=>Be,Nm:()=>Fe,hW:()=>ze,QG:()=>Ue,oJ:()=>qe,J6:()=>Ve,nX:()=>$e,po:()=>We,XV:()=>He,Pz:()=>Je,D$:()=>Ke,V9:()=>Ge,cz:()=>Ze,Uj:()=>Ye,Xb:()=>Qe,O2:()=>et});var n=r(58309),o=r.n(n),a=r(97606),i=r.n(a),s=r(74386),l=r.n(s),u=r(86),c=r.n(u),p=r(14418),f=r.n(p),h=r(28222),d=r.n(h),m=(r(11189),r(24282)),g=r.n(m),v=r(76986),y=r.n(v),b=r(2578),w=r.n(b),E=r(24278),x=r.n(E),_=(r(39022),r(92039)),S=r.n(_),A=(r(58118),r(35627)),k=r.n(A),C=r(11882),O=r.n(C),j=r(51679),I=r.n(j),N=r(27043),T=r.n(N),P=r(81607),R=r.n(P),M=r(43393),D=r.n(M),L=r(17967),B=r(68929),F=r.n(B),z=r(11700),U=r.n(z),q=r(88306),V=r.n(q),$=r(13311),W=r.n($),H=r(59704),J=r.n(H),K=r(77813),G=r.n(K),Z=r(23560),Y=r.n(Z),Q=r(57050),X=r(27504),ee=r(8269),te=r.n(ee),re=r(19069),ne=r(92282),oe=r.n(ne),ae=r(89072),ie=r.n(ae),se=r(1272),le=r(48764).Buffer;const ue="default",ce=e=>D().Iterable.isIterable(e);function pe(e){return me(e)?ce(e)?e.toJS():e:{}}function fe(e){var t,r;if(ce(e))return e;if(e instanceof X.Z.File)return e;if(!me(e))return e;if(o()(e))return i()(r=D().Seq(e)).call(r,fe).toList();if(Y()(l()(e))){var n;const t=function(e){if(!Y()(l()(e)))return e;const t={},r="_**[]",n={};for(let o of l()(e).call(e))if(t[o[0]]||n[o[0]]&&n[o[0]].containsMultiple){if(!n[o[0]]){n[o[0]]={containsMultiple:!0,length:1},t[`${o[0]}${r}${n[o[0]].length}`]=t[o[0]],delete t[o[0]]}n[o[0]].length+=1,t[`${o[0]}${r}${n[o[0]].length}`]=o[1]}else t[o[0]]=o[1];return t}(e);return i()(n=D().OrderedMap(t)).call(n,fe)}return i()(t=D().OrderedMap(e)).call(t,fe)}function he(e){return o()(e)?e:[e]}function de(e){return"function"==typeof e}function me(e){return!!e&&"object"==typeof e}function ge(e){return"function"==typeof e}function ve(e){return o()(e)}const ye=V();function be(e,t){var r;return g()(r=d()(e)).call(r,((r,n)=>(r[n]=t(e[n],n),r)),{})}function we(e,t){var r;return g()(r=d()(e)).call(r,((r,n)=>{let o=t(e[n],n);return o&&"object"==typeof o&&y()(r,o),r}),{})}function Ee(e){return t=>{let{dispatch:r,getState:n}=t;return t=>r=>"function"==typeof r?r(e()):t(r)}}function xe(e){var t;let r=e.keySeq();return r.contains(ue)?ue:w()(t=f()(r).call(r,(e=>"2"===(e+"")[0]))).call(t).first()}function _e(e,t){if(!D().Iterable.isIterable(e))return D().List();let r=e.getIn(o()(t)?t:[t]);return D().List.isList(r)?r:D().List()}function Se(e){let t,r=[/filename\*=[^']+'\w*'"([^"]+)";?/i,/filename\*=[^']+'\w*'([^;]+);?/i,/filename="([^;]*);?"/i,/filename=([^;]*);?/i];if(S()(r).call(r,(r=>(t=r.exec(e),null!==t))),null!==t&&t.length>1)try{return decodeURIComponent(t[1])}catch(e){console.error(e)}return null}function Ae(e){return t=e.replace(/\.[^./]*$/,""),U()(F()(t));var t}function ke(e,t,r,n,a){if(!t)return[];let s=[],l=t.get("nullable"),u=t.get("required"),p=t.get("maximum"),h=t.get("minimum"),d=t.get("type"),m=t.get("format"),g=t.get("maxLength"),v=t.get("minLength"),y=t.get("uniqueItems"),b=t.get("maxItems"),w=t.get("minItems"),E=t.get("pattern");const x=r||!0===u,_=null!=e;if(l&&null===e||!d||!(x||_&&"array"===d||!(!x&&!_)))return[];let A="string"===d&&e,k="array"===d&&o()(e)&&e.length,C="array"===d&&D().List.isList(e)&&e.count();const O=[A,k,C,"array"===d&&"string"==typeof e&&e,"file"===d&&e instanceof X.Z.File,"boolean"===d&&(e||!1===e),"number"===d&&(e||0===e),"integer"===d&&(e||0===e),"object"===d&&"object"==typeof e&&null!==e,"object"===d&&"string"==typeof e&&e],j=S()(O).call(O,(e=>!!e));if(x&&!j&&!n)return s.push("Required field is not provided"),s;if("object"===d&&(null===a||"application/json"===a)){let r=e;if("string"==typeof e)try{r=JSON.parse(e)}catch(e){return s.push("Parameter string value must be valid JSON"),s}var I;if(t&&t.has("required")&&ge(u.isList)&&u.isList()&&c()(u).call(u,(e=>{void 0===r[e]&&s.push({propKey:e,error:"Required property not found"})})),t&&t.has("properties"))c()(I=t.get("properties")).call(I,((e,t)=>{const o=ke(r[t],e,!1,n,a);s.push(...i()(o).call(o,(e=>({propKey:t,error:e}))))}))}if(E){let t=((e,t)=>{if(!new RegExp(t).test(e))return"Value must follow pattern "+t})(e,E);t&&s.push(t)}if(w&&"array"===d){let t=((e,t)=>{if(!e&&t>=1||e&&e.length{if(e&&e.length>t)return`Array must not contain more then ${t} item${1===t?"":"s"}`})(e,b);t&&s.push({needRemove:!0,error:t})}if(y&&"array"===d){let t=((e,t)=>{if(e&&("true"===t||!0===t)){const t=(0,M.fromJS)(e),r=t.toSet();if(e.length>r.size){let e=(0,M.Set)();if(c()(t).call(t,((r,n)=>{f()(t).call(t,(e=>ge(e.equals)?e.equals(r):e===r)).size>1&&(e=e.add(n))})),0!==e.size)return i()(e).call(e,(e=>({index:e,error:"No duplicates allowed."}))).toArray()}}})(e,y);t&&s.push(...t)}if(g||0===g){let t=((e,t)=>{if(e.length>t)return`Value must be no longer than ${t} character${1!==t?"s":""}`})(e,g);t&&s.push(t)}if(v){let t=((e,t)=>{if(e.length{if(e>t)return`Value must be less than ${t}`})(e,p);t&&s.push(t)}if(h||0===h){let t=((e,t)=>{if(e{if(isNaN(Date.parse(e)))return"Value must be a DateTime"})(e):"uuid"===m?(e=>{if(e=e.toString().toLowerCase(),!/^[{(]?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}[)}]?$/.test(e))return"Value must be a Guid"})(e):(e=>{if(e&&"string"!=typeof e)return"Value must be a string"})(e),!t)return s;s.push(t)}else if("boolean"===d){let t=(e=>{if("true"!==e&&"false"!==e&&!0!==e&&!1!==e)return"Value must be a boolean"})(e);if(!t)return s;s.push(t)}else if("number"===d){let t=(e=>{if(!/^-?\d+(\.?\d+)?$/.test(e))return"Value must be a number"})(e);if(!t)return s;s.push(t)}else if("integer"===d){let t=(e=>{if(!/^-?\d+$/.test(e))return"Value must be an integer"})(e);if(!t)return s;s.push(t)}else if("array"===d){if(!k&&!C)return s;e&&c()(e).call(e,((e,r)=>{const o=ke(e,t.get("items"),!1,n,a);s.push(...i()(o).call(o,(e=>({index:r,error:e}))))}))}else if("file"===d){let t=(e=>{if(e&&!(e instanceof X.Z.File))return"Value must be a file"})(e);if(!t)return s;s.push(t)}return s}const Ce=function(e,t){let{isOAS3:r=!1,bypassRequiredCheck:n=!1}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},o=e.get("required"),{schema:a,parameterContentMediaType:i}=(0,re.Z)(e,{isOAS3:r});return ke(t,a,o,n,i)},Oe=(e,t,r)=>{if(e&&(!e.xml||!e.xml.name)){if(e.xml=e.xml||{},!e.$$ref)return e.type||e.items||e.properties||e.additionalProperties?'\n\x3c!-- XML example cannot be generated; root element name is undefined --\x3e':null;{let t=e.$$ref.match(/\S*\/(\S+)$/);e.xml.name=t[1]}}return(0,Q.memoizedCreateXMLExample)(e,t,r)},je=[{when:/json/,shouldStringifyTypes:["string"]}],Ie=["object"],Ne=(e,t,r,n)=>{const o=(0,Q.memoizedSampleFromSchema)(e,t,n),a=typeof o,i=g()(je).call(je,((e,t)=>t.when.test(r)?[...e,...t.shouldStringifyTypes]:e),Ie);return J()(i,(e=>e===a))?k()(o,null,2):o},Te=(e,t,r,n)=>{const o=Ne(e,t,r,n);let a;try{a=se.ZP.dump(se.ZP.load(o),{lineWidth:-1},{schema:se.A8}),"\n"===a[a.length-1]&&(a=x()(a).call(a,0,a.length-1))}catch(e){return console.error(e),"error: could not generate yaml example"}return a.replace(/\t/g," ")},Pe=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:void 0;return e&&ge(e.toJS)&&(e=e.toJS()),n&&ge(n.toJS)&&(n=n.toJS()),/xml/.test(t)?Oe(e,r,n):/(yaml|yml)/.test(t)?Te(e,r,t,n):Ne(e,r,t,n)},Re=()=>{let e={},t=X.Z.location.search;if(!t)return{};if(""!=t){let r=t.substr(1).split("&");for(let t in r)Object.prototype.hasOwnProperty.call(r,t)&&(t=r[t].split("="),e[decodeURIComponent(t[0])]=t[1]&&decodeURIComponent(t[1])||"")}return e},Me=e=>{let t;return t=e instanceof le?e:le.from(e.toString(),"utf-8"),t.toString("base64")},De={operationsSorter:{alpha:(e,t)=>e.get("path").localeCompare(t.get("path")),method:(e,t)=>e.get("method").localeCompare(t.get("method"))},tagsSorter:{alpha:(e,t)=>e.localeCompare(t)}},Le=e=>{let t=[];for(let r in e){let n=e[r];void 0!==n&&""!==n&&t.push([r,"=",encodeURIComponent(n).replace(/%20/g,"+")].join(""))}return t.join("&")},Be=(e,t,r)=>!!W()(r,(r=>G()(e[r],t[r])));function Fe(e){return"string"!=typeof e||""===e?"":(0,L.N)(e)}function ze(e){return!(!e||O()(e).call(e,"localhost")>=0||O()(e).call(e,"127.0.0.1")>=0||"none"===e)}function Ue(e){if(!D().OrderedMap.isOrderedMap(e))return null;if(!e.size)return null;const t=I()(e).call(e,((e,t)=>T()(t).call(t,"2")&&d()(e.get("content")||{}).length>0)),r=e.get("default")||D().OrderedMap(),n=(r.get("content")||D().OrderedMap()).keySeq().toJS().length?r:null;return t||n}const qe=e=>"string"==typeof e||e instanceof String?R()(e).call(e).replace(/\s/g,"%20"):"",Ve=e=>te()(qe(e).replace(/%20/g,"_")),$e=e=>f()(e).call(e,((e,t)=>/^x-/.test(t))),We=e=>f()(e).call(e,((e,t)=>/^pattern|maxLength|minLength|maximum|minimum/.test(t)));function He(e,t){var r;let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:()=>!0;if("object"!=typeof e||o()(e)||null===e||!t)return e;const a=y()({},e);return c()(r=d()(a)).call(r,(e=>{e===t&&n(a[e],e)?delete a[e]:a[e]=He(a[e],t,n)})),a}function Je(e){if("string"==typeof e)return e;if(e&&e.toJS&&(e=e.toJS()),"object"==typeof e&&null!==e)try{return k()(e,null,2)}catch(t){return String(e)}return null==e?"":e.toString()}function Ke(e){return"number"==typeof e?e.toString():e}function Ge(e){let{returnAll:t=!1,allowHashes:r=!0}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!D().Map.isMap(e))throw new Error("paramToIdentifier: received a non-Im.Map parameter as input");const n=e.get("name"),o=e.get("in");let a=[];return e&&e.hashCode&&o&&n&&r&&a.push(`${o}.${n}.hash-${e.hashCode()}`),o&&n&&a.push(`${o}.${n}`),a.push(n),t?a:a[0]||""}function Ze(e,t){var r;const n=Ge(e,{returnAll:!0});return f()(r=i()(n).call(n,(e=>t[e]))).call(r,(e=>void 0!==e))[0]}function Ye(){return Xe(oe()(32).toString("base64"))}function Qe(e){return Xe(ie()("sha256").update(e).digest("base64"))}function Xe(e){return e.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}const et=e=>!e||!(!ce(e)||!e.isEmpty())},2518:(e,t,r)=>{"use strict";function n(e){return function(e){try{return!!JSON.parse(e)}catch(e){return null}}(e)?"json":null}r.d(t,{O:()=>n})},27504:(e,t,r)=>{"use strict";r.d(t,{Z:()=>n});const n=function(){var e={location:{},history:{},open:()=>{},close:()=>{},File:function(){}};if("undefined"==typeof window)return e;try{e=window;for(var t of["File","Blob","FormData"])t in window&&(e[t]=window[t])}catch(e){console.error(e)}return e}()},19069:(e,t,r)=>{"use strict";r.d(t,{Z:()=>c});var n=r(14418),o=r.n(n),a=r(58118),i=r.n(a),s=r(43393),l=r.n(s);const u=l().Set.of("type","format","items","default","maximum","exclusiveMaximum","minimum","exclusiveMinimum","maxLength","minLength","pattern","maxItems","minItems","uniqueItems","enum","multipleOf");function c(e){let{isOAS3:t}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!l().Map.isMap(e))return{schema:l().Map(),parameterContentMediaType:null};if(!t)return"body"===e.get("in")?{schema:e.get("schema",l().Map()),parameterContentMediaType:null}:{schema:o()(e).call(e,((e,t)=>i()(u).call(u,t))),parameterContentMediaType:null};if(e.get("content")){const t=e.get("content",l().Map({})).keySeq().first();return{schema:e.getIn(["content",t,"schema"],l().Map()),parameterContentMediaType:t}}return{schema:e.get("schema",l().Map()),parameterContentMediaType:null}}},60314:(e,t,r)=>{"use strict";r.d(t,{Z:()=>x});var n=r(58309),o=r.n(n),a=r(2250),i=r.n(a),s=r(25110),l=r.n(s),u=r(8712),c=r.n(u),p=r(51679),f=r.n(p),h=r(12373),d=r.n(h),m=r(18492),g=r.n(m),v=r(88306),y=r.n(v);const b=e=>t=>o()(e)&&o()(t)&&e.length===t.length&&i()(e).call(e,((e,r)=>e===t[r])),w=function(){for(var e=arguments.length,t=new Array(e),r=0;r1&&void 0!==arguments[1]?arguments[1]:w;const{Cache:r}=y();y().Cache=E;const n=y()(e,t);return y().Cache=r,n}},79742:(e,t)=>{"use strict";t.byteLength=function(e){var t=l(e),r=t[0],n=t[1];return 3*(r+n)/4-n},t.toByteArray=function(e){var t,r,a=l(e),i=a[0],s=a[1],u=new o(function(e,t,r){return 3*(t+r)/4-r}(0,i,s)),c=0,p=s>0?i-4:i;for(r=0;r>16&255,u[c++]=t>>8&255,u[c++]=255&t;2===s&&(t=n[e.charCodeAt(r)]<<2|n[e.charCodeAt(r+1)]>>4,u[c++]=255&t);1===s&&(t=n[e.charCodeAt(r)]<<10|n[e.charCodeAt(r+1)]<<4|n[e.charCodeAt(r+2)]>>2,u[c++]=t>>8&255,u[c++]=255&t);return u},t.fromByteArray=function(e){for(var t,n=e.length,o=n%3,a=[],i=16383,s=0,l=n-o;sl?l:s+i));1===o?(t=e[n-1],a.push(r[t>>2]+r[t<<4&63]+"==")):2===o&&(t=(e[n-2]<<8)+e[n-1],a.push(r[t>>10]+r[t>>4&63]+r[t<<2&63]+"="));return a.join("")};for(var r=[],n=[],o="undefined"!=typeof Uint8Array?Uint8Array:Array,a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",i=0,s=a.length;i0)throw new Error("Invalid string. Length must be a multiple of 4");var r=e.indexOf("=");return-1===r&&(r=t),[r,r===t?0:4-r%4]}function u(e,t,n){for(var o,a,i=[],s=t;s>18&63]+r[a>>12&63]+r[a>>6&63]+r[63&a]);return i.join("")}n["-".charCodeAt(0)]=62,n["_".charCodeAt(0)]=63},48764:(e,t,r)=>{"use strict";const n=r(79742),o=r(80645),a="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):null;t.Buffer=l,t.SlowBuffer=function(e){+e!=e&&(e=0);return l.alloc(+e)},t.INSPECT_MAX_BYTES=50;const i=2147483647;function s(e){if(e>i)throw new RangeError('The value "'+e+'" is invalid for option "size"');const t=new Uint8Array(e);return Object.setPrototypeOf(t,l.prototype),t}function l(e,t,r){if("number"==typeof e){if("string"==typeof t)throw new TypeError('The "string" argument must be of type string. Received type number');return p(e)}return u(e,t,r)}function u(e,t,r){if("string"==typeof e)return function(e,t){"string"==typeof t&&""!==t||(t="utf8");if(!l.isEncoding(t))throw new TypeError("Unknown encoding: "+t);const r=0|m(e,t);let n=s(r);const o=n.write(e,t);o!==r&&(n=n.slice(0,o));return n}(e,t);if(ArrayBuffer.isView(e))return function(e){if(G(e,Uint8Array)){const t=new Uint8Array(e);return h(t.buffer,t.byteOffset,t.byteLength)}return f(e)}(e);if(null==e)throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof e);if(G(e,ArrayBuffer)||e&&G(e.buffer,ArrayBuffer))return h(e,t,r);if("undefined"!=typeof SharedArrayBuffer&&(G(e,SharedArrayBuffer)||e&&G(e.buffer,SharedArrayBuffer)))return h(e,t,r);if("number"==typeof e)throw new TypeError('The "value" argument must not be of type number. Received type number');const n=e.valueOf&&e.valueOf();if(null!=n&&n!==e)return l.from(n,t,r);const o=function(e){if(l.isBuffer(e)){const t=0|d(e.length),r=s(t);return 0===r.length||e.copy(r,0,0,t),r}if(void 0!==e.length)return"number"!=typeof e.length||Z(e.length)?s(0):f(e);if("Buffer"===e.type&&Array.isArray(e.data))return f(e.data)}(e);if(o)return o;if("undefined"!=typeof Symbol&&null!=Symbol.toPrimitive&&"function"==typeof e[Symbol.toPrimitive])return l.from(e[Symbol.toPrimitive]("string"),t,r);throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof e)}function c(e){if("number"!=typeof e)throw new TypeError('"size" argument must be of type number');if(e<0)throw new RangeError('The value "'+e+'" is invalid for option "size"')}function p(e){return c(e),s(e<0?0:0|d(e))}function f(e){const t=e.length<0?0:0|d(e.length),r=s(t);for(let n=0;n=i)throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+i.toString(16)+" bytes");return 0|e}function m(e,t){if(l.isBuffer(e))return e.length;if(ArrayBuffer.isView(e)||G(e,ArrayBuffer))return e.byteLength;if("string"!=typeof e)throw new TypeError('The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type '+typeof e);const r=e.length,n=arguments.length>2&&!0===arguments[2];if(!n&&0===r)return 0;let o=!1;for(;;)switch(t){case"ascii":case"latin1":case"binary":return r;case"utf8":case"utf-8":return H(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*r;case"hex":return r>>>1;case"base64":return J(e).length;default:if(o)return n?-1:H(e).length;t=(""+t).toLowerCase(),o=!0}}function g(e,t,r){let n=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===r||r>this.length)&&(r=this.length),r<=0)return"";if((r>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return I(this,t,r);case"utf8":case"utf-8":return k(this,t,r);case"ascii":return O(this,t,r);case"latin1":case"binary":return j(this,t,r);case"base64":return A(this,t,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return N(this,t,r);default:if(n)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),n=!0}}function v(e,t,r){const n=e[t];e[t]=e[r],e[r]=n}function y(e,t,r,n,o){if(0===e.length)return-1;if("string"==typeof r?(n=r,r=0):r>2147483647?r=2147483647:r<-2147483648&&(r=-2147483648),Z(r=+r)&&(r=o?0:e.length-1),r<0&&(r=e.length+r),r>=e.length){if(o)return-1;r=e.length-1}else if(r<0){if(!o)return-1;r=0}if("string"==typeof t&&(t=l.from(t,n)),l.isBuffer(t))return 0===t.length?-1:b(e,t,r,n,o);if("number"==typeof t)return t&=255,"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(e,t,r):Uint8Array.prototype.lastIndexOf.call(e,t,r):b(e,[t],r,n,o);throw new TypeError("val must be string, number or Buffer")}function b(e,t,r,n,o){let a,i=1,s=e.length,l=t.length;if(void 0!==n&&("ucs2"===(n=String(n).toLowerCase())||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(e.length<2||t.length<2)return-1;i=2,s/=2,l/=2,r/=2}function u(e,t){return 1===i?e[t]:e.readUInt16BE(t*i)}if(o){let n=-1;for(a=r;as&&(r=s-l),a=r;a>=0;a--){let r=!0;for(let n=0;no&&(n=o):n=o;const a=t.length;let i;for(n>a/2&&(n=a/2),i=0;i>8,o=r%256,a.push(o),a.push(n);return a}(t,e.length-r),e,r,n)}function A(e,t,r){return 0===t&&r===e.length?n.fromByteArray(e):n.fromByteArray(e.slice(t,r))}function k(e,t,r){r=Math.min(e.length,r);const n=[];let o=t;for(;o239?4:t>223?3:t>191?2:1;if(o+i<=r){let r,n,s,l;switch(i){case 1:t<128&&(a=t);break;case 2:r=e[o+1],128==(192&r)&&(l=(31&t)<<6|63&r,l>127&&(a=l));break;case 3:r=e[o+1],n=e[o+2],128==(192&r)&&128==(192&n)&&(l=(15&t)<<12|(63&r)<<6|63&n,l>2047&&(l<55296||l>57343)&&(a=l));break;case 4:r=e[o+1],n=e[o+2],s=e[o+3],128==(192&r)&&128==(192&n)&&128==(192&s)&&(l=(15&t)<<18|(63&r)<<12|(63&n)<<6|63&s,l>65535&&l<1114112&&(a=l))}}null===a?(a=65533,i=1):a>65535&&(a-=65536,n.push(a>>>10&1023|55296),a=56320|1023&a),n.push(a),o+=i}return function(e){const t=e.length;if(t<=C)return String.fromCharCode.apply(String,e);let r="",n=0;for(;nn.length?(l.isBuffer(t)||(t=l.from(t)),t.copy(n,o)):Uint8Array.prototype.set.call(n,t,o);else{if(!l.isBuffer(t))throw new TypeError('"list" argument must be an Array of Buffers');t.copy(n,o)}o+=t.length}return n},l.byteLength=m,l.prototype._isBuffer=!0,l.prototype.swap16=function(){const e=this.length;if(e%2!=0)throw new RangeError("Buffer size must be a multiple of 16-bits");for(let t=0;tr&&(e+=" ... "),""},a&&(l.prototype[a]=l.prototype.inspect),l.prototype.compare=function(e,t,r,n,o){if(G(e,Uint8Array)&&(e=l.from(e,e.offset,e.byteLength)),!l.isBuffer(e))throw new TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type '+typeof e);if(void 0===t&&(t=0),void 0===r&&(r=e?e.length:0),void 0===n&&(n=0),void 0===o&&(o=this.length),t<0||r>e.length||n<0||o>this.length)throw new RangeError("out of range index");if(n>=o&&t>=r)return 0;if(n>=o)return-1;if(t>=r)return 1;if(this===e)return 0;let a=(o>>>=0)-(n>>>=0),i=(r>>>=0)-(t>>>=0);const s=Math.min(a,i),u=this.slice(n,o),c=e.slice(t,r);for(let e=0;e>>=0,isFinite(r)?(r>>>=0,void 0===n&&(n="utf8")):(n=r,r=void 0)}const o=this.length-t;if((void 0===r||r>o)&&(r=o),e.length>0&&(r<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");n||(n="utf8");let a=!1;for(;;)switch(n){case"hex":return w(this,e,t,r);case"utf8":case"utf-8":return E(this,e,t,r);case"ascii":case"latin1":case"binary":return x(this,e,t,r);case"base64":return _(this,e,t,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return S(this,e,t,r);default:if(a)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),a=!0}},l.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};const C=4096;function O(e,t,r){let n="";r=Math.min(e.length,r);for(let o=t;on)&&(r=n);let o="";for(let n=t;nr)throw new RangeError("Trying to access beyond buffer length")}function P(e,t,r,n,o,a){if(!l.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>o||te.length)throw new RangeError("Index out of range")}function R(e,t,r,n,o){q(t,n,o,e,r,7);let a=Number(t&BigInt(4294967295));e[r++]=a,a>>=8,e[r++]=a,a>>=8,e[r++]=a,a>>=8,e[r++]=a;let i=Number(t>>BigInt(32)&BigInt(4294967295));return e[r++]=i,i>>=8,e[r++]=i,i>>=8,e[r++]=i,i>>=8,e[r++]=i,r}function M(e,t,r,n,o){q(t,n,o,e,r,7);let a=Number(t&BigInt(4294967295));e[r+7]=a,a>>=8,e[r+6]=a,a>>=8,e[r+5]=a,a>>=8,e[r+4]=a;let i=Number(t>>BigInt(32)&BigInt(4294967295));return e[r+3]=i,i>>=8,e[r+2]=i,i>>=8,e[r+1]=i,i>>=8,e[r]=i,r+8}function D(e,t,r,n,o,a){if(r+n>e.length)throw new RangeError("Index out of range");if(r<0)throw new RangeError("Index out of range")}function L(e,t,r,n,a){return t=+t,r>>>=0,a||D(e,0,r,4),o.write(e,t,r,n,23,4),r+4}function B(e,t,r,n,a){return t=+t,r>>>=0,a||D(e,0,r,8),o.write(e,t,r,n,52,8),r+8}l.prototype.slice=function(e,t){const r=this.length;(e=~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),(t=void 0===t?r:~~t)<0?(t+=r)<0&&(t=0):t>r&&(t=r),t>>=0,t>>>=0,r||T(e,t,this.length);let n=this[e],o=1,a=0;for(;++a>>=0,t>>>=0,r||T(e,t,this.length);let n=this[e+--t],o=1;for(;t>0&&(o*=256);)n+=this[e+--t]*o;return n},l.prototype.readUint8=l.prototype.readUInt8=function(e,t){return e>>>=0,t||T(e,1,this.length),this[e]},l.prototype.readUint16LE=l.prototype.readUInt16LE=function(e,t){return e>>>=0,t||T(e,2,this.length),this[e]|this[e+1]<<8},l.prototype.readUint16BE=l.prototype.readUInt16BE=function(e,t){return e>>>=0,t||T(e,2,this.length),this[e]<<8|this[e+1]},l.prototype.readUint32LE=l.prototype.readUInt32LE=function(e,t){return e>>>=0,t||T(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},l.prototype.readUint32BE=l.prototype.readUInt32BE=function(e,t){return e>>>=0,t||T(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},l.prototype.readBigUInt64LE=Q((function(e){V(e>>>=0,"offset");const t=this[e],r=this[e+7];void 0!==t&&void 0!==r||$(e,this.length-8);const n=t+256*this[++e]+65536*this[++e]+this[++e]*2**24,o=this[++e]+256*this[++e]+65536*this[++e]+r*2**24;return BigInt(n)+(BigInt(o)<>>=0,"offset");const t=this[e],r=this[e+7];void 0!==t&&void 0!==r||$(e,this.length-8);const n=t*2**24+65536*this[++e]+256*this[++e]+this[++e],o=this[++e]*2**24+65536*this[++e]+256*this[++e]+r;return(BigInt(n)<>>=0,t>>>=0,r||T(e,t,this.length);let n=this[e],o=1,a=0;for(;++a=o&&(n-=Math.pow(2,8*t)),n},l.prototype.readIntBE=function(e,t,r){e>>>=0,t>>>=0,r||T(e,t,this.length);let n=t,o=1,a=this[e+--n];for(;n>0&&(o*=256);)a+=this[e+--n]*o;return o*=128,a>=o&&(a-=Math.pow(2,8*t)),a},l.prototype.readInt8=function(e,t){return e>>>=0,t||T(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},l.prototype.readInt16LE=function(e,t){e>>>=0,t||T(e,2,this.length);const r=this[e]|this[e+1]<<8;return 32768&r?4294901760|r:r},l.prototype.readInt16BE=function(e,t){e>>>=0,t||T(e,2,this.length);const r=this[e+1]|this[e]<<8;return 32768&r?4294901760|r:r},l.prototype.readInt32LE=function(e,t){return e>>>=0,t||T(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},l.prototype.readInt32BE=function(e,t){return e>>>=0,t||T(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},l.prototype.readBigInt64LE=Q((function(e){V(e>>>=0,"offset");const t=this[e],r=this[e+7];void 0!==t&&void 0!==r||$(e,this.length-8);const n=this[e+4]+256*this[e+5]+65536*this[e+6]+(r<<24);return(BigInt(n)<>>=0,"offset");const t=this[e],r=this[e+7];void 0!==t&&void 0!==r||$(e,this.length-8);const n=(t<<24)+65536*this[++e]+256*this[++e]+this[++e];return(BigInt(n)<>>=0,t||T(e,4,this.length),o.read(this,e,!0,23,4)},l.prototype.readFloatBE=function(e,t){return e>>>=0,t||T(e,4,this.length),o.read(this,e,!1,23,4)},l.prototype.readDoubleLE=function(e,t){return e>>>=0,t||T(e,8,this.length),o.read(this,e,!0,52,8)},l.prototype.readDoubleBE=function(e,t){return e>>>=0,t||T(e,8,this.length),o.read(this,e,!1,52,8)},l.prototype.writeUintLE=l.prototype.writeUIntLE=function(e,t,r,n){if(e=+e,t>>>=0,r>>>=0,!n){P(this,e,t,r,Math.pow(2,8*r)-1,0)}let o=1,a=0;for(this[t]=255&e;++a>>=0,r>>>=0,!n){P(this,e,t,r,Math.pow(2,8*r)-1,0)}let o=r-1,a=1;for(this[t+o]=255&e;--o>=0&&(a*=256);)this[t+o]=e/a&255;return t+r},l.prototype.writeUint8=l.prototype.writeUInt8=function(e,t,r){return e=+e,t>>>=0,r||P(this,e,t,1,255,0),this[t]=255&e,t+1},l.prototype.writeUint16LE=l.prototype.writeUInt16LE=function(e,t,r){return e=+e,t>>>=0,r||P(this,e,t,2,65535,0),this[t]=255&e,this[t+1]=e>>>8,t+2},l.prototype.writeUint16BE=l.prototype.writeUInt16BE=function(e,t,r){return e=+e,t>>>=0,r||P(this,e,t,2,65535,0),this[t]=e>>>8,this[t+1]=255&e,t+2},l.prototype.writeUint32LE=l.prototype.writeUInt32LE=function(e,t,r){return e=+e,t>>>=0,r||P(this,e,t,4,4294967295,0),this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e,t+4},l.prototype.writeUint32BE=l.prototype.writeUInt32BE=function(e,t,r){return e=+e,t>>>=0,r||P(this,e,t,4,4294967295,0),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},l.prototype.writeBigUInt64LE=Q((function(e,t=0){return R(this,e,t,BigInt(0),BigInt("0xffffffffffffffff"))})),l.prototype.writeBigUInt64BE=Q((function(e,t=0){return M(this,e,t,BigInt(0),BigInt("0xffffffffffffffff"))})),l.prototype.writeIntLE=function(e,t,r,n){if(e=+e,t>>>=0,!n){const n=Math.pow(2,8*r-1);P(this,e,t,r,n-1,-n)}let o=0,a=1,i=0;for(this[t]=255&e;++o>0)-i&255;return t+r},l.prototype.writeIntBE=function(e,t,r,n){if(e=+e,t>>>=0,!n){const n=Math.pow(2,8*r-1);P(this,e,t,r,n-1,-n)}let o=r-1,a=1,i=0;for(this[t+o]=255&e;--o>=0&&(a*=256);)e<0&&0===i&&0!==this[t+o+1]&&(i=1),this[t+o]=(e/a>>0)-i&255;return t+r},l.prototype.writeInt8=function(e,t,r){return e=+e,t>>>=0,r||P(this,e,t,1,127,-128),e<0&&(e=255+e+1),this[t]=255&e,t+1},l.prototype.writeInt16LE=function(e,t,r){return e=+e,t>>>=0,r||P(this,e,t,2,32767,-32768),this[t]=255&e,this[t+1]=e>>>8,t+2},l.prototype.writeInt16BE=function(e,t,r){return e=+e,t>>>=0,r||P(this,e,t,2,32767,-32768),this[t]=e>>>8,this[t+1]=255&e,t+2},l.prototype.writeInt32LE=function(e,t,r){return e=+e,t>>>=0,r||P(this,e,t,4,2147483647,-2147483648),this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24,t+4},l.prototype.writeInt32BE=function(e,t,r){return e=+e,t>>>=0,r||P(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},l.prototype.writeBigInt64LE=Q((function(e,t=0){return R(this,e,t,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))})),l.prototype.writeBigInt64BE=Q((function(e,t=0){return M(this,e,t,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))})),l.prototype.writeFloatLE=function(e,t,r){return L(this,e,t,!0,r)},l.prototype.writeFloatBE=function(e,t,r){return L(this,e,t,!1,r)},l.prototype.writeDoubleLE=function(e,t,r){return B(this,e,t,!0,r)},l.prototype.writeDoubleBE=function(e,t,r){return B(this,e,t,!1,r)},l.prototype.copy=function(e,t,r,n){if(!l.isBuffer(e))throw new TypeError("argument should be a Buffer");if(r||(r=0),n||0===n||(n=this.length),t>=e.length&&(t=e.length),t||(t=0),n>0&&n=this.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("sourceEnd out of bounds");n>this.length&&(n=this.length),e.length-t>>=0,r=void 0===r?this.length:r>>>0,e||(e=0),"number"==typeof e)for(o=t;o=n+4;r-=3)t=`_${e.slice(r-3,r)}${t}`;return`${e.slice(0,r)}${t}`}function q(e,t,r,n,o,a){if(e>r||e3?0===t||t===BigInt(0)?`>= 0${n} and < 2${n} ** ${8*(a+1)}${n}`:`>= -(2${n} ** ${8*(a+1)-1}${n}) and < 2 ** ${8*(a+1)-1}${n}`:`>= ${t}${n} and <= ${r}${n}`,new F.ERR_OUT_OF_RANGE("value",o,e)}!function(e,t,r){V(t,"offset"),void 0!==e[t]&&void 0!==e[t+r]||$(t,e.length-(r+1))}(n,o,a)}function V(e,t){if("number"!=typeof e)throw new F.ERR_INVALID_ARG_TYPE(t,"number",e)}function $(e,t,r){if(Math.floor(e)!==e)throw V(e,r),new F.ERR_OUT_OF_RANGE(r||"offset","an integer",e);if(t<0)throw new F.ERR_BUFFER_OUT_OF_BOUNDS;throw new F.ERR_OUT_OF_RANGE(r||"offset",`>= ${r?1:0} and <= ${t}`,e)}z("ERR_BUFFER_OUT_OF_BOUNDS",(function(e){return e?`${e} is outside of buffer bounds`:"Attempt to access memory outside buffer bounds"}),RangeError),z("ERR_INVALID_ARG_TYPE",(function(e,t){return`The "${e}" argument must be of type number. Received type ${typeof t}`}),TypeError),z("ERR_OUT_OF_RANGE",(function(e,t,r){let n=`The value of "${e}" is out of range.`,o=r;return Number.isInteger(r)&&Math.abs(r)>2**32?o=U(String(r)):"bigint"==typeof r&&(o=String(r),(r>BigInt(2)**BigInt(32)||r<-(BigInt(2)**BigInt(32)))&&(o=U(o)),o+="n"),n+=` It must be ${t}. Received ${o}`,n}),RangeError);const W=/[^+/0-9A-Za-z-_]/g;function H(e,t){let r;t=t||1/0;const n=e.length;let o=null;const a=[];for(let i=0;i55295&&r<57344){if(!o){if(r>56319){(t-=3)>-1&&a.push(239,191,189);continue}if(i+1===n){(t-=3)>-1&&a.push(239,191,189);continue}o=r;continue}if(r<56320){(t-=3)>-1&&a.push(239,191,189),o=r;continue}r=65536+(o-55296<<10|r-56320)}else o&&(t-=3)>-1&&a.push(239,191,189);if(o=null,r<128){if((t-=1)<0)break;a.push(r)}else if(r<2048){if((t-=2)<0)break;a.push(r>>6|192,63&r|128)}else if(r<65536){if((t-=3)<0)break;a.push(r>>12|224,r>>6&63|128,63&r|128)}else{if(!(r<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;a.push(r>>18|240,r>>12&63|128,r>>6&63|128,63&r|128)}}return a}function J(e){return n.toByteArray(function(e){if((e=(e=e.split("=")[0]).trim().replace(W,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function K(e,t,r,n){let o;for(o=0;o=t.length||o>=e.length);++o)t[o+r]=e[o];return o}function G(e,t){return e instanceof t||null!=e&&null!=e.constructor&&null!=e.constructor.name&&e.constructor.name===t.name}function Z(e){return e!=e}const Y=function(){const e="0123456789abcdef",t=new Array(256);for(let r=0;r<16;++r){const n=16*r;for(let o=0;o<16;++o)t[n+o]=e[r]+e[o]}return t}();function Q(e){return"undefined"==typeof BigInt?X:e}function X(){throw new Error("BigInt not supported")}},21924:(e,t,r)=>{"use strict";var n=r(40210),o=r(55559),a=o(n("String.prototype.indexOf"));e.exports=function(e,t){var r=n(e,!!t);return"function"==typeof r&&a(e,".prototype.")>-1?o(r):r}},55559:(e,t,r)=>{"use strict";var n=r(58612),o=r(40210),a=o("%Function.prototype.apply%"),i=o("%Function.prototype.call%"),s=o("%Reflect.apply%",!0)||n.call(i,a),l=o("%Object.getOwnPropertyDescriptor%",!0),u=o("%Object.defineProperty%",!0),c=o("%Math.max%");if(u)try{u({},"a",{value:1})}catch(e){u=null}e.exports=function(e){var t=s(n,i,arguments);if(l&&u){var r=l(t,"length");r.configurable&&u(t,"length",{value:1+c(0,e.length-(arguments.length-1))})}return t};var p=function(){return s(n,a,arguments)};u?u(e.exports,"apply",{value:p}):e.exports.apply=p},94184:(e,t)=>{var r;!function(){"use strict";var n={}.hasOwnProperty;function o(){for(var e=[],t=0;t{"use strict";var n=r(11742),o={"text/plain":"Text","text/html":"Url",default:"Text"};e.exports=function(e,t){var r,a,i,s,l,u,c=!1;t||(t={}),r=t.debug||!1;try{if(i=n(),s=document.createRange(),l=document.getSelection(),(u=document.createElement("span")).textContent=e,u.style.all="unset",u.style.position="fixed",u.style.top=0,u.style.clip="rect(0, 0, 0, 0)",u.style.whiteSpace="pre",u.style.webkitUserSelect="text",u.style.MozUserSelect="text",u.style.msUserSelect="text",u.style.userSelect="text",u.addEventListener("copy",(function(n){if(n.stopPropagation(),t.format)if(n.preventDefault(),void 0===n.clipboardData){r&&console.warn("unable to use e.clipboardData"),r&&console.warn("trying IE specific stuff"),window.clipboardData.clearData();var a=o[t.format]||o.default;window.clipboardData.setData(a,e)}else n.clipboardData.clearData(),n.clipboardData.setData(t.format,e);t.onCopy&&(n.preventDefault(),t.onCopy(n.clipboardData))})),document.body.appendChild(u),s.selectNodeContents(u),l.addRange(s),!document.execCommand("copy"))throw new Error("copy command was unsuccessful");c=!0}catch(n){r&&console.error("unable to copy using execCommand: ",n),r&&console.warn("trying IE specific stuff");try{window.clipboardData.setData(t.format||"text",e),t.onCopy&&t.onCopy(window.clipboardData),c=!0}catch(n){r&&console.error("unable to copy using clipboardData: ",n),r&&console.error("falling back to prompt"),a=function(e){var t=(/mac os x/i.test(navigator.userAgent)?"⌘":"Ctrl")+"+C";return e.replace(/#{\s*key\s*}/g,t)}("message"in t?t.message:"Copy to clipboard: #{key}, Enter"),window.prompt(a,e)}}finally{l&&("function"==typeof l.removeRange?l.removeRange(s):l.removeAllRanges()),u&&document.body.removeChild(u),i()}return c}},95299:(e,t,r)=>{var n=r(24848);e.exports=n},83450:(e,t,r)=>{var n=r(83363);e.exports=n},66820:(e,t,r)=>{var n=r(56243);e.exports=n},5023:(e,t,r)=>{var n=r(72369);e.exports=n},90093:(e,t,r)=>{var n=r(28196);e.exports=n},3688:(e,t,r)=>{var n=r(11955);e.exports=n},83838:(e,t,r)=>{var n=r(46279);e.exports=n},15684:(e,t,r)=>{var n=r(19373);e.exports=n},99826:(e,t,r)=>{var n=r(28427);e.exports=n},84234:(e,t,r)=>{var n=r(82073);e.exports=n},65362:(e,t,r)=>{var n=r(63383);e.exports=n},32271:(e,t,r)=>{var n=r(14471);e.exports=n},91254:(e,t,r)=>{var n=r(57396);e.exports=n},43536:(e,t,r)=>{var n=r(41910);e.exports=n},37331:(e,t,r)=>{var n=r(79427);e.exports=n},68522:(e,t,r)=>{var n=r(62857);e.exports=n},73151:(e,t,r)=>{var n=r(9534);e.exports=n},99565:(e,t,r)=>{var n=r(96507);e.exports=n},45012:(e,t,r)=>{var n=r(23059);e.exports=n},78690:(e,t,r)=>{var n=r(16670);e.exports=n},25626:(e,t,r)=>{var n=r(27460);e.exports=n},80281:(e,t,r)=>{var n=r(92547);e.exports=n},40031:(e,t,r)=>{var n=r(46509);e.exports=n},54493:(e,t,r)=>{r(77971),r(53242);var n=r(54058);e.exports=n.Array.from},24034:(e,t,r)=>{r(92737);var n=r(54058);e.exports=n.Array.isArray},15367:(e,t,r)=>{r(85906);var n=r(35703);e.exports=n("Array").concat},12710:(e,t,r)=>{r(66274),r(55967);var n=r(35703);e.exports=n("Array").entries},51459:(e,t,r)=>{r(48851);var n=r(35703);e.exports=n("Array").every},6172:(e,t,r)=>{r(80290);var n=r(35703);e.exports=n("Array").fill},62383:(e,t,r)=>{r(21501);var n=r(35703);e.exports=n("Array").filter},60009:(e,t,r)=>{r(44929);var n=r(35703);e.exports=n("Array").findIndex},17671:(e,t,r)=>{r(80833);var n=r(35703);e.exports=n("Array").find},99324:(e,t,r)=>{r(2437);var n=r(35703);e.exports=n("Array").forEach},80991:(e,t,r)=>{r(97690);var n=r(35703);e.exports=n("Array").includes},8700:(e,t,r)=>{r(99076);var n=r(35703);e.exports=n("Array").indexOf},95909:(e,t,r)=>{r(66274),r(55967);var n=r(35703);e.exports=n("Array").keys},6442:(e,t,r)=>{r(75915);var n=r(35703);e.exports=n("Array").lastIndexOf},23866:(e,t,r)=>{r(68787);var n=r(35703);e.exports=n("Array").map},52999:(e,t,r)=>{r(81876);var n=r(35703);e.exports=n("Array").reduce},91876:(e,t,r)=>{r(11490);var n=r(35703);e.exports=n("Array").reverse},24900:(e,t,r)=>{r(60186);var n=r(35703);e.exports=n("Array").slice},3824:(e,t,r)=>{r(36026);var n=r(35703);e.exports=n("Array").some},2948:(e,t,r)=>{r(4115);var n=r(35703);e.exports=n("Array").sort},78209:(e,t,r)=>{r(98611);var n=r(35703);e.exports=n("Array").splice},14423:(e,t,r)=>{r(66274),r(55967);var n=r(35703);e.exports=n("Array").values},81103:(e,t,r)=>{r(95160);var n=r(54058);e.exports=n.Date.now},27700:(e,t,r)=>{r(73381);var n=r(35703);e.exports=n("Function").bind},13830:(e,t,r)=>{r(66274),r(77971);var n=r(22902);e.exports=n},91031:(e,t,r)=>{r(52595),e.exports=r(21899)},16246:(e,t,r)=>{var n=r(7046),o=r(27700),a=Function.prototype;e.exports=function(e){var t=e.bind;return e===a||n(a,e)&&t===a.bind?o:t}},56043:(e,t,r)=>{var n=r(7046),o=r(15367),a=Array.prototype;e.exports=function(e){var t=e.concat;return e===a||n(a,e)&&t===a.concat?o:t}},13160:(e,t,r)=>{var n=r(7046),o=r(51459),a=Array.prototype;e.exports=function(e){var t=e.every;return e===a||n(a,e)&&t===a.every?o:t}},80446:(e,t,r)=>{var n=r(7046),o=r(6172),a=Array.prototype;e.exports=function(e){var t=e.fill;return e===a||n(a,e)&&t===a.fill?o:t}},2480:(e,t,r)=>{var n=r(7046),o=r(62383),a=Array.prototype;e.exports=function(e){var t=e.filter;return e===a||n(a,e)&&t===a.filter?o:t}},7147:(e,t,r)=>{var n=r(7046),o=r(60009),a=Array.prototype;e.exports=function(e){var t=e.findIndex;return e===a||n(a,e)&&t===a.findIndex?o:t}},32236:(e,t,r)=>{var n=r(7046),o=r(17671),a=Array.prototype;e.exports=function(e){var t=e.find;return e===a||n(a,e)&&t===a.find?o:t}},58557:(e,t,r)=>{var n=r(7046),o=r(80991),a=r(21631),i=Array.prototype,s=String.prototype;e.exports=function(e){var t=e.includes;return e===i||n(i,e)&&t===i.includes?o:"string"==typeof e||e===s||n(s,e)&&t===s.includes?a:t}},34570:(e,t,r)=>{var n=r(7046),o=r(8700),a=Array.prototype;e.exports=function(e){var t=e.indexOf;return e===a||n(a,e)&&t===a.indexOf?o:t}},57564:(e,t,r)=>{var n=r(7046),o=r(6442),a=Array.prototype;e.exports=function(e){var t=e.lastIndexOf;return e===a||n(a,e)&&t===a.lastIndexOf?o:t}},88287:(e,t,r)=>{var n=r(7046),o=r(23866),a=Array.prototype;e.exports=function(e){var t=e.map;return e===a||n(a,e)&&t===a.map?o:t}},68025:(e,t,r)=>{var n=r(7046),o=r(52999),a=Array.prototype;e.exports=function(e){var t=e.reduce;return e===a||n(a,e)&&t===a.reduce?o:t}},59257:(e,t,r)=>{var n=r(7046),o=r(80454),a=String.prototype;e.exports=function(e){var t=e.repeat;return"string"==typeof e||e===a||n(a,e)&&t===a.repeat?o:t}},91060:(e,t,r)=>{var n=r(7046),o=r(91876),a=Array.prototype;e.exports=function(e){var t=e.reverse;return e===a||n(a,e)&&t===a.reverse?o:t}},69601:(e,t,r)=>{var n=r(7046),o=r(24900),a=Array.prototype;e.exports=function(e){var t=e.slice;return e===a||n(a,e)&&t===a.slice?o:t}},28299:(e,t,r)=>{var n=r(7046),o=r(3824),a=Array.prototype;e.exports=function(e){var t=e.some;return e===a||n(a,e)&&t===a.some?o:t}},69355:(e,t,r)=>{var n=r(7046),o=r(2948),a=Array.prototype;e.exports=function(e){var t=e.sort;return e===a||n(a,e)&&t===a.sort?o:t}},18339:(e,t,r)=>{var n=r(7046),o=r(78209),a=Array.prototype;e.exports=function(e){var t=e.splice;return e===a||n(a,e)&&t===a.splice?o:t}},71611:(e,t,r)=>{var n=r(7046),o=r(3269),a=String.prototype;e.exports=function(e){var t=e.startsWith;return"string"==typeof e||e===a||n(a,e)&&t===a.startsWith?o:t}},62774:(e,t,r)=>{var n=r(7046),o=r(13348),a=String.prototype;e.exports=function(e){var t=e.trim;return"string"==typeof e||e===a||n(a,e)&&t===a.trim?o:t}},84426:(e,t,r)=>{r(32619);var n=r(54058),o=r(79730);n.JSON||(n.JSON={stringify:JSON.stringify}),e.exports=function(e,t,r){return o(n.JSON.stringify,null,arguments)}},91018:(e,t,r)=>{r(66274),r(37501),r(55967),r(77971);var n=r(54058);e.exports=n.Map},45999:(e,t,r)=>{r(49221);var n=r(54058);e.exports=n.Object.assign},35254:(e,t,r)=>{r(53882);var n=r(54058).Object;e.exports=function(e,t){return n.create(e,t)}},7702:(e,t,r)=>{r(74979);var n=r(54058).Object,o=e.exports=function(e,t){return n.defineProperties(e,t)};n.defineProperties.sham&&(o.sham=!0)},48171:(e,t,r)=>{r(86450);var n=r(54058).Object,o=e.exports=function(e,t,r){return n.defineProperty(e,t,r)};n.defineProperty.sham&&(o.sham=!0)},73081:(e,t,r)=>{r(94366);var n=r(54058);e.exports=n.Object.entries},286:(e,t,r)=>{r(46924);var n=r(54058).Object,o=e.exports=function(e,t){return n.getOwnPropertyDescriptor(e,t)};n.getOwnPropertyDescriptor.sham&&(o.sham=!0)},92766:(e,t,r)=>{r(88482);var n=r(54058);e.exports=n.Object.getOwnPropertyDescriptors},30498:(e,t,r)=>{r(35824);var n=r(54058);e.exports=n.Object.getOwnPropertySymbols},13966:(e,t,r)=>{r(17405);var n=r(54058);e.exports=n.Object.getPrototypeOf},48494:(e,t,r)=>{r(21724);var n=r(54058);e.exports=n.Object.keys},3065:(e,t,r)=>{r(90108);var n=r(54058);e.exports=n.Object.setPrototypeOf},98430:(e,t,r)=>{r(26614);var n=r(54058);e.exports=n.Object.values},52956:(e,t,r)=>{r(47627),r(66274),r(55967),r(98881),r(4560),r(91302),r(44349),r(77971);var n=r(54058);e.exports=n.Promise},21631:(e,t,r)=>{r(11035);var n=r(35703);e.exports=n("String").includes},80454:(e,t,r)=>{r(60986);var n=r(35703);e.exports=n("String").repeat},3269:(e,t,r)=>{r(94761);var n=r(35703);e.exports=n("String").startsWith},13348:(e,t,r)=>{r(57398);var n=r(35703);e.exports=n("String").trim},57473:(e,t,r)=>{r(85906),r(55967),r(35824),r(8555),r(52615),r(21732),r(35903),r(1825),r(28394),r(45915),r(61766),r(62737),r(89911),r(74315),r(63131),r(64714),r(70659),r(69120),r(79413),r(1502);var n=r(54058);e.exports=n.Symbol},24227:(e,t,r)=>{r(66274),r(55967),r(77971),r(1825);var n=r(11477);e.exports=n.f("iterator")},32304:(e,t,r)=>{r(66274),r(55967),r(54334);var n=r(54058);e.exports=n.WeakMap},27385:(e,t,r)=>{var n=r(95299);e.exports=n},81522:(e,t,r)=>{var n=r(83450);e.exports=n},32209:(e,t,r)=>{var n=r(66820);e.exports=n},30888:(e,t,r)=>{r(9668);var n=r(5023);e.exports=n},14122:(e,t,r)=>{var n=r(90093);e.exports=n},44442:(e,t,r)=>{var n=r(3688);e.exports=n},57152:(e,t,r)=>{var n=r(83838);e.exports=n},69447:(e,t,r)=>{var n=r(15684);e.exports=n},17579:(e,t,r)=>{var n=r(99826);e.exports=n},81493:(e,t,r)=>{var n=r(84234);e.exports=n},60269:(e,t,r)=>{var n=r(65362);e.exports=n},76094:(e,t,r)=>{var n=r(32271);e.exports=n},70573:(e,t,r)=>{var n=r(91254);e.exports=n},73685:(e,t,r)=>{var n=r(43536);e.exports=n},27533:(e,t,r)=>{var n=r(37331);e.exports=n},39057:(e,t,r)=>{var n=r(68522);e.exports=n},84710:(e,t,r)=>{var n=r(73151);e.exports=n},74303:(e,t,r)=>{var n=r(99565);e.exports=n},93799:(e,t,r)=>{var n=r(45012);e.exports=n},55122:(e,t,r)=>{var n=r(78690);e.exports=n},29531:(e,t,r)=>{var n=r(25626);r(89731),r(55708),r(30014),r(88731),e.exports=n},86600:(e,t,r)=>{var n=r(80281);r(28783),r(43975),r(65799),r(45414),r(46774),r(80620),r(36172),e.exports=n},9759:(e,t,r)=>{var n=r(40031);e.exports=n},24883:(e,t,r)=>{var n=r(21899),o=r(57475),a=r(69826),i=n.TypeError;e.exports=function(e){if(o(e))return e;throw i(a(e)+" is not a function")}},174:(e,t,r)=>{var n=r(21899),o=r(24284),a=r(69826),i=n.TypeError;e.exports=function(e){if(o(e))return e;throw i(a(e)+" is not a constructor")}},11851:(e,t,r)=>{var n=r(21899),o=r(57475),a=n.String,i=n.TypeError;e.exports=function(e){if("object"==typeof e||o(e))return e;throw i("Can't set "+a(e)+" as a prototype")}},18479:e=>{e.exports=function(){}},5743:(e,t,r)=>{var n=r(21899),o=r(7046),a=n.TypeError;e.exports=function(e,t){if(o(t,e))return e;throw a("Incorrect invocation")}},96059:(e,t,r)=>{var n=r(21899),o=r(10941),a=n.String,i=n.TypeError;e.exports=function(e){if(o(e))return e;throw i(a(e)+" is not an object")}},97135:(e,t,r)=>{var n=r(95981);e.exports=n((function(){if("function"==typeof ArrayBuffer){var e=new ArrayBuffer(8);Object.isExtensible(e)&&Object.defineProperty(e,"a",{value:8})}}))},91860:(e,t,r)=>{"use strict";var n=r(89678),o=r(59413),a=r(10623);e.exports=function(e){for(var t=n(this),r=a(t),i=arguments.length,s=o(i>1?arguments[1]:void 0,r),l=i>2?arguments[2]:void 0,u=void 0===l?r:o(l,r);u>s;)t[s++]=e;return t}},56837:(e,t,r)=>{"use strict";var n=r(3610).forEach,o=r(34194)("forEach");e.exports=o?[].forEach:function(e){return n(this,e,arguments.length>1?arguments[1]:void 0)}},11354:(e,t,r)=>{"use strict";var n=r(21899),o=r(86843),a=r(78834),i=r(89678),s=r(75196),l=r(6782),u=r(24284),c=r(10623),p=r(55449),f=r(53476),h=r(22902),d=n.Array;e.exports=function(e){var t=i(e),r=u(this),n=arguments.length,m=n>1?arguments[1]:void 0,g=void 0!==m;g&&(m=o(m,n>2?arguments[2]:void 0));var v,y,b,w,E,x,_=h(t),S=0;if(!_||this==d&&l(_))for(v=c(t),y=r?new this(v):d(v);v>S;S++)x=g?m(t[S],S):t[S],p(y,S,x);else for(E=(w=f(t,_)).next,y=r?new this:[];!(b=a(E,w)).done;S++)x=g?s(w,m,[b.value,S],!0):b.value,p(y,S,x);return y.length=S,y}},31692:(e,t,r)=>{var n=r(74529),o=r(59413),a=r(10623),i=function(e){return function(t,r,i){var s,l=n(t),u=a(l),c=o(i,u);if(e&&r!=r){for(;u>c;)if((s=l[c++])!=s)return!0}else for(;u>c;c++)if((e||c in l)&&l[c]===r)return e||c||0;return!e&&-1}};e.exports={includes:i(!0),indexOf:i(!1)}},3610:(e,t,r)=>{var n=r(86843),o=r(95329),a=r(37026),i=r(89678),s=r(10623),l=r(64692),u=o([].push),c=function(e){var t=1==e,r=2==e,o=3==e,c=4==e,p=6==e,f=7==e,h=5==e||p;return function(d,m,g,v){for(var y,b,w=i(d),E=a(w),x=n(m,g),_=s(E),S=0,A=v||l,k=t?A(d,_):r||f?A(d,0):void 0;_>S;S++)if((h||S in E)&&(b=x(y=E[S],S,w),e))if(t)k[S]=b;else if(b)switch(e){case 3:return!0;case 5:return y;case 6:return S;case 2:u(k,y)}else switch(e){case 4:return!1;case 7:u(k,y)}return p?-1:o||c?c:k}};e.exports={forEach:c(0),map:c(1),filter:c(2),some:c(3),every:c(4),find:c(5),findIndex:c(6),filterReject:c(7)}},67145:(e,t,r)=>{"use strict";var n=r(79730),o=r(74529),a=r(62435),i=r(10623),s=r(34194),l=Math.min,u=[].lastIndexOf,c=!!u&&1/[1].lastIndexOf(1,-0)<0,p=s("lastIndexOf"),f=c||!p;e.exports=f?function(e){if(c)return n(u,this,arguments)||0;var t=o(this),r=i(t),s=r-1;for(arguments.length>1&&(s=l(s,a(arguments[1]))),s<0&&(s=r+s);s>=0;s--)if(s in t&&t[s]===e)return s||0;return-1}:u},50568:(e,t,r)=>{var n=r(95981),o=r(99813),a=r(53385),i=o("species");e.exports=function(e){return a>=51||!n((function(){var t=[];return(t.constructor={})[i]=function(){return{foo:1}},1!==t[e](Boolean).foo}))}},34194:(e,t,r)=>{"use strict";var n=r(95981);e.exports=function(e,t){var r=[][e];return!!r&&n((function(){r.call(null,t||function(){throw 1},1)}))}},46499:(e,t,r)=>{var n=r(21899),o=r(24883),a=r(89678),i=r(37026),s=r(10623),l=n.TypeError,u=function(e){return function(t,r,n,u){o(r);var c=a(t),p=i(c),f=s(c),h=e?f-1:0,d=e?-1:1;if(n<2)for(;;){if(h in p){u=p[h],h+=d;break}if(h+=d,e?h<0:f<=h)throw l("Reduce of empty array with no initial value")}for(;e?h>=0:f>h;h+=d)h in p&&(u=r(u,p[h],h,c));return u}};e.exports={left:u(!1),right:u(!0)}},15790:(e,t,r)=>{var n=r(21899),o=r(59413),a=r(10623),i=r(55449),s=n.Array,l=Math.max;e.exports=function(e,t,r){for(var n=a(e),u=o(t,n),c=o(void 0===r?n:r,n),p=s(l(c-u,0)),f=0;u{var n=r(95329);e.exports=n([].slice)},61388:(e,t,r)=>{var n=r(15790),o=Math.floor,a=function(e,t){var r=e.length,l=o(r/2);return r<8?i(e,t):s(e,a(n(e,0,l),t),a(n(e,l),t),t)},i=function(e,t){for(var r,n,o=e.length,a=1;a0;)e[n]=e[--n];n!==a++&&(e[n]=r)}return e},s=function(e,t,r,n){for(var o=t.length,a=r.length,i=0,s=0;i{var n=r(21899),o=r(1052),a=r(24284),i=r(10941),s=r(99813)("species"),l=n.Array;e.exports=function(e){var t;return o(e)&&(t=e.constructor,(a(t)&&(t===l||o(t.prototype))||i(t)&&null===(t=t[s]))&&(t=void 0)),void 0===t?l:t}},64692:(e,t,r)=>{var n=r(5693);e.exports=function(e,t){return new(n(e))(0===t?0:t)}},75196:(e,t,r)=>{var n=r(96059),o=r(7609);e.exports=function(e,t,r,a){try{return a?t(n(r)[0],r[1]):t(r)}catch(t){o(e,"throw",t)}}},21385:(e,t,r)=>{var n=r(99813)("iterator"),o=!1;try{var a=0,i={next:function(){return{done:!!a++}},return:function(){o=!0}};i[n]=function(){return this},Array.from(i,(function(){throw 2}))}catch(e){}e.exports=function(e,t){if(!t&&!o)return!1;var r=!1;try{var a={};a[n]=function(){return{next:function(){return{done:r=!0}}}},e(a)}catch(e){}return r}},82532:(e,t,r)=>{var n=r(95329),o=n({}.toString),a=n("".slice);e.exports=function(e){return a(o(e),8,-1)}},9697:(e,t,r)=>{var n=r(21899),o=r(22885),a=r(57475),i=r(82532),s=r(99813)("toStringTag"),l=n.Object,u="Arguments"==i(function(){return arguments}());e.exports=o?i:function(e){var t,r,n;return void 0===e?"Undefined":null===e?"Null":"string"==typeof(r=function(e,t){try{return e[t]}catch(e){}}(t=l(e),s))?r:u?i(t):"Object"==(n=i(t))&&a(t.callee)?"Arguments":n}},38694:(e,t,r)=>{var n=r(95329)("".replace),o=String(Error("zxcasd").stack),a=/\n\s*at [^:]*:[^\n]*/,i=a.test(o);e.exports=function(e,t){if(i&&"string"==typeof e)for(;t--;)e=n(e,a,"");return e}},85616:(e,t,r)=>{"use strict";var n=r(65988).f,o=r(29290),a=r(87524),i=r(86843),s=r(5743),l=r(93091),u=r(47771),c=r(94431),p=r(55746),f=r(21647).fastKey,h=r(45402),d=h.set,m=h.getterFor;e.exports={getConstructor:function(e,t,r,u){var c=e((function(e,n){s(e,h),d(e,{type:t,index:o(null),first:void 0,last:void 0,size:0}),p||(e.size=0),null!=n&&l(n,e[u],{that:e,AS_ENTRIES:r})})),h=c.prototype,g=m(t),v=function(e,t,r){var n,o,a=g(e),i=y(e,t);return i?i.value=r:(a.last=i={index:o=f(t,!0),key:t,value:r,previous:n=a.last,next:void 0,removed:!1},a.first||(a.first=i),n&&(n.next=i),p?a.size++:e.size++,"F"!==o&&(a.index[o]=i)),e},y=function(e,t){var r,n=g(e),o=f(t);if("F"!==o)return n.index[o];for(r=n.first;r;r=r.next)if(r.key==t)return r};return a(h,{clear:function(){for(var e=g(this),t=e.index,r=e.first;r;)r.removed=!0,r.previous&&(r.previous=r.previous.next=void 0),delete t[r.index],r=r.next;e.first=e.last=void 0,p?e.size=0:this.size=0},delete:function(e){var t=this,r=g(t),n=y(t,e);if(n){var o=n.next,a=n.previous;delete r.index[n.index],n.removed=!0,a&&(a.next=o),o&&(o.previous=a),r.first==n&&(r.first=o),r.last==n&&(r.last=a),p?r.size--:t.size--}return!!n},forEach:function(e){for(var t,r=g(this),n=i(e,arguments.length>1?arguments[1]:void 0);t=t?t.next:r.first;)for(n(t.value,t.key,this);t&&t.removed;)t=t.previous},has:function(e){return!!y(this,e)}}),a(h,r?{get:function(e){var t=y(this,e);return t&&t.value},set:function(e,t){return v(this,0===e?0:e,t)}}:{add:function(e){return v(this,e=0===e?0:e,e)}}),p&&n(h,"size",{get:function(){return g(this).size}}),c},setStrong:function(e,t,r){var n=t+" Iterator",o=m(t),a=m(n);u(e,t,(function(e,t){d(this,{type:n,target:e,state:o(e),kind:t,last:void 0})}),(function(){for(var e=a(this),t=e.kind,r=e.last;r&&r.removed;)r=r.previous;return e.target&&(e.last=r=r?r.next:e.state.first)?"keys"==t?{value:r.key,done:!1}:"values"==t?{value:r.value,done:!1}:{value:[r.key,r.value],done:!1}:(e.target=void 0,{value:void 0,done:!0})}),r?"entries":"values",!r,!0),c(t)}}},8850:(e,t,r)=>{"use strict";var n=r(95329),o=r(87524),a=r(21647).getWeakData,i=r(96059),s=r(10941),l=r(5743),u=r(93091),c=r(3610),p=r(90953),f=r(45402),h=f.set,d=f.getterFor,m=c.find,g=c.findIndex,v=n([].splice),y=0,b=function(e){return e.frozen||(e.frozen=new w)},w=function(){this.entries=[]},E=function(e,t){return m(e.entries,(function(e){return e[0]===t}))};w.prototype={get:function(e){var t=E(this,e);if(t)return t[1]},has:function(e){return!!E(this,e)},set:function(e,t){var r=E(this,e);r?r[1]=t:this.entries.push([e,t])},delete:function(e){var t=g(this.entries,(function(t){return t[0]===e}));return~t&&v(this.entries,t,1),!!~t}},e.exports={getConstructor:function(e,t,r,n){var c=e((function(e,o){l(e,f),h(e,{type:t,id:y++,frozen:void 0}),null!=o&&u(o,e[n],{that:e,AS_ENTRIES:r})})),f=c.prototype,m=d(t),g=function(e,t,r){var n=m(e),o=a(i(t),!0);return!0===o?b(n).set(t,r):o[n.id]=r,e};return o(f,{delete:function(e){var t=m(this);if(!s(e))return!1;var r=a(e);return!0===r?b(t).delete(e):r&&p(r,t.id)&&delete r[t.id]},has:function(e){var t=m(this);if(!s(e))return!1;var r=a(e);return!0===r?b(t).has(e):r&&p(r,t.id)}}),o(f,r?{get:function(e){var t=m(this);if(s(e)){var r=a(e);return!0===r?b(t).get(e):r?r[t.id]:void 0}},set:function(e,t){return g(this,e,t)}}:{add:function(e){return g(this,e,!0)}}),c}}},24683:(e,t,r)=>{"use strict";var n=r(76887),o=r(21899),a=r(21647),i=r(95981),s=r(32029),l=r(93091),u=r(5743),c=r(57475),p=r(10941),f=r(90904),h=r(65988).f,d=r(3610).forEach,m=r(55746),g=r(45402),v=g.set,y=g.getterFor;e.exports=function(e,t,r){var g,b=-1!==e.indexOf("Map"),w=-1!==e.indexOf("Weak"),E=b?"set":"add",x=o[e],_=x&&x.prototype,S={};if(m&&c(x)&&(w||_.forEach&&!i((function(){(new x).entries().next()})))){var A=(g=t((function(t,r){v(u(t,A),{type:e,collection:new x}),null!=r&&l(r,t[E],{that:t,AS_ENTRIES:b})}))).prototype,k=y(e);d(["add","clear","delete","forEach","get","has","set","keys","values","entries"],(function(e){var t="add"==e||"set"==e;!(e in _)||w&&"clear"==e||s(A,e,(function(r,n){var o=k(this).collection;if(!t&&w&&!p(r))return"get"==e&&void 0;var a=o[e](0===r?0:r,n);return t?this:a}))})),w||h(A,"size",{configurable:!0,get:function(){return k(this).collection.size}})}else g=r.getConstructor(t,e,b,E),a.enable();return f(g,e,!1,!0),S[e]=g,n({global:!0,forced:!0},S),w||r.setStrong(g,e,b),g}},23489:(e,t,r)=>{var n=r(90953),o=r(31136),a=r(49677),i=r(65988);e.exports=function(e,t,r){for(var s=o(t),l=i.f,u=a.f,c=0;c{var n=r(99813)("match");e.exports=function(e){var t=/./;try{"/./"[e](t)}catch(r){try{return t[n]=!1,"/./"[e](t)}catch(e){}}return!1}},64160:(e,t,r)=>{var n=r(95981);e.exports=!n((function(){function e(){}return e.prototype.constructor=null,Object.getPrototypeOf(new e)!==e.prototype}))},31046:(e,t,r)=>{"use strict";var n=r(35143).IteratorPrototype,o=r(29290),a=r(31887),i=r(90904),s=r(12077),l=function(){return this};e.exports=function(e,t,r,u){var c=t+" Iterator";return e.prototype=o(n,{next:a(+!u,r)}),i(e,c,!1,!0),s[c]=l,e}},32029:(e,t,r)=>{var n=r(55746),o=r(65988),a=r(31887);e.exports=n?function(e,t,r){return o.f(e,t,a(1,r))}:function(e,t,r){return e[t]=r,e}},31887:e=>{e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},55449:(e,t,r)=>{"use strict";var n=r(83894),o=r(65988),a=r(31887);e.exports=function(e,t,r){var i=n(t);i in e?o.f(e,i,a(0,r)):e[i]=r}},47771:(e,t,r)=>{"use strict";var n=r(76887),o=r(78834),a=r(82529),i=r(79417),s=r(57475),l=r(31046),u=r(249),c=r(88929),p=r(90904),f=r(32029),h=r(99754),d=r(99813),m=r(12077),g=r(35143),v=i.PROPER,y=i.CONFIGURABLE,b=g.IteratorPrototype,w=g.BUGGY_SAFARI_ITERATORS,E=d("iterator"),x="keys",_="values",S="entries",A=function(){return this};e.exports=function(e,t,r,i,d,g,k){l(r,t,i);var C,O,j,I=function(e){if(e===d&&M)return M;if(!w&&e in P)return P[e];switch(e){case x:case _:case S:return function(){return new r(this,e)}}return function(){return new r(this)}},N=t+" Iterator",T=!1,P=e.prototype,R=P[E]||P["@@iterator"]||d&&P[d],M=!w&&R||I(d),D="Array"==t&&P.entries||R;if(D&&(C=u(D.call(new e)))!==Object.prototype&&C.next&&(a||u(C)===b||(c?c(C,b):s(C[E])||h(C,E,A)),p(C,N,!0,!0),a&&(m[N]=A)),v&&d==_&&R&&R.name!==_&&(!a&&y?f(P,"name",_):(T=!0,M=function(){return o(R,this)})),d)if(O={values:I(_),keys:g?M:I(x),entries:I(S)},k)for(j in O)(w||T||!(j in P))&&h(P,j,O[j]);else n({target:t,proto:!0,forced:w||T},O);return a&&!k||P[E]===M||h(P,E,M,{name:d}),m[t]=M,O}},66349:(e,t,r)=>{var n=r(54058),o=r(90953),a=r(11477),i=r(65988).f;e.exports=function(e){var t=n.Symbol||(n.Symbol={});o(t,e)||i(t,e,{value:a.f(e)})}},55746:(e,t,r)=>{var n=r(95981);e.exports=!n((function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]}))},61333:(e,t,r)=>{var n=r(21899),o=r(10941),a=n.document,i=o(a)&&o(a.createElement);e.exports=function(e){return i?a.createElement(e):{}}},63281:e=>{e.exports={CSSRuleList:0,CSSStyleDeclaration:0,CSSValueList:0,ClientRectList:0,DOMRectList:0,DOMStringList:0,DOMTokenList:1,DataTransferItemList:0,FileList:0,HTMLAllCollection:0,HTMLCollection:0,HTMLFormElement:0,HTMLSelectElement:0,MediaList:0,MimeTypeArray:0,NamedNodeMap:0,NodeList:1,PaintRequestList:0,Plugin:0,PluginArray:0,SVGLengthList:0,SVGNumberList:0,SVGPathSegList:0,SVGPointList:0,SVGStringList:0,SVGTransformList:0,SourceBufferList:0,StyleSheetList:0,TextTrackCueList:0,TextTrackList:0,TouchList:0}},34342:(e,t,r)=>{var n=r(2861).match(/firefox\/(\d+)/i);e.exports=!!n&&+n[1]},23321:e=>{e.exports="object"==typeof window},81046:(e,t,r)=>{var n=r(2861);e.exports=/MSIE|Trident/.test(n)},4470:(e,t,r)=>{var n=r(2861),o=r(21899);e.exports=/ipad|iphone|ipod/i.test(n)&&void 0!==o.Pebble},22749:(e,t,r)=>{var n=r(2861);e.exports=/(?:ipad|iphone|ipod).*applewebkit/i.test(n)},6049:(e,t,r)=>{var n=r(82532),o=r(21899);e.exports="process"==n(o.process)},58045:(e,t,r)=>{var n=r(2861);e.exports=/web0s(?!.*chrome)/i.test(n)},2861:(e,t,r)=>{var n=r(626);e.exports=n("navigator","userAgent")||""},53385:(e,t,r)=>{var n,o,a=r(21899),i=r(2861),s=a.process,l=a.Deno,u=s&&s.versions||l&&l.version,c=u&&u.v8;c&&(o=(n=c.split("."))[0]>0&&n[0]<4?1:+(n[0]+n[1])),!o&&i&&(!(n=i.match(/Edge\/(\d+)/))||n[1]>=74)&&(n=i.match(/Chrome\/(\d+)/))&&(o=+n[1]),e.exports=o},18938:(e,t,r)=>{var n=r(2861).match(/AppleWebKit\/(\d+)\./);e.exports=!!n&&+n[1]},35703:(e,t,r)=>{var n=r(54058);e.exports=function(e){return n[e+"Prototype"]}},56759:e=>{e.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},18780:(e,t,r)=>{var n=r(95981),o=r(31887);e.exports=!n((function(){var e=Error("a");return!("stack"in e)||(Object.defineProperty(e,"stack",o(1,7)),7!==e.stack)}))},76887:(e,t,r)=>{"use strict";var n=r(21899),o=r(79730),a=r(95329),i=r(57475),s=r(49677).f,l=r(37252),u=r(54058),c=r(86843),p=r(32029),f=r(90953),h=function(e){var t=function(r,n,a){if(this instanceof t){switch(arguments.length){case 0:return new e;case 1:return new e(r);case 2:return new e(r,n)}return new e(r,n,a)}return o(e,this,arguments)};return t.prototype=e.prototype,t};e.exports=function(e,t){var r,o,d,m,g,v,y,b,w=e.target,E=e.global,x=e.stat,_=e.proto,S=E?n:x?n[w]:(n[w]||{}).prototype,A=E?u:u[w]||p(u,w,{})[w],k=A.prototype;for(d in t)r=!l(E?d:w+(x?".":"#")+d,e.forced)&&S&&f(S,d),g=A[d],r&&(v=e.noTargetGet?(b=s(S,d))&&b.value:S[d]),m=r&&v?v:t[d],r&&typeof g==typeof m||(y=e.bind&&r?c(m,n):e.wrap&&r?h(m):_&&i(m)?a(m):m,(e.sham||m&&m.sham||g&&g.sham)&&p(y,"sham",!0),p(A,d,y),_&&(f(u,o=w+"Prototype")||p(u,o,{}),p(u[o],d,m),e.real&&k&&!k[d]&&p(k,d,m)))}},95981:e=>{e.exports=function(e){try{return!!e()}catch(e){return!0}}},45602:(e,t,r)=>{var n=r(95981);e.exports=!n((function(){return Object.isExtensible(Object.preventExtensions({}))}))},79730:(e,t,r)=>{var n=r(18285),o=Function.prototype,a=o.apply,i=o.call;e.exports="object"==typeof Reflect&&Reflect.apply||(n?i.bind(a):function(){return i.apply(a,arguments)})},86843:(e,t,r)=>{var n=r(95329),o=r(24883),a=r(18285),i=n(n.bind);e.exports=function(e,t){return o(e),void 0===t?e:a?i(e,t):function(){return e.apply(t,arguments)}}},18285:(e,t,r)=>{var n=r(95981);e.exports=!n((function(){var e=function(){}.bind();return"function"!=typeof e||e.hasOwnProperty("prototype")}))},98308:(e,t,r)=>{"use strict";var n=r(21899),o=r(95329),a=r(24883),i=r(10941),s=r(90953),l=r(93765),u=r(18285),c=n.Function,p=o([].concat),f=o([].join),h={},d=function(e,t,r){if(!s(h,t)){for(var n=[],o=0;o{var n=r(18285),o=Function.prototype.call;e.exports=n?o.bind(o):function(){return o.apply(o,arguments)}},79417:(e,t,r)=>{var n=r(55746),o=r(90953),a=Function.prototype,i=n&&Object.getOwnPropertyDescriptor,s=o(a,"name"),l=s&&"something"===function(){}.name,u=s&&(!n||n&&i(a,"name").configurable);e.exports={EXISTS:s,PROPER:l,CONFIGURABLE:u}},95329:(e,t,r)=>{var n=r(18285),o=Function.prototype,a=o.bind,i=o.call,s=n&&a.bind(i,i);e.exports=n?function(e){return e&&s(e)}:function(e){return e&&function(){return i.apply(e,arguments)}}},626:(e,t,r)=>{var n=r(54058),o=r(21899),a=r(57475),i=function(e){return a(e)?e:void 0};e.exports=function(e,t){return arguments.length<2?i(n[e])||i(o[e]):n[e]&&n[e][t]||o[e]&&o[e][t]}},22902:(e,t,r)=>{var n=r(9697),o=r(14229),a=r(12077),i=r(99813)("iterator");e.exports=function(e){if(null!=e)return o(e,i)||o(e,"@@iterator")||a[n(e)]}},53476:(e,t,r)=>{var n=r(21899),o=r(78834),a=r(24883),i=r(96059),s=r(69826),l=r(22902),u=n.TypeError;e.exports=function(e,t){var r=arguments.length<2?l(e):t;if(a(r))return i(o(r,e));throw u(s(e)+" is not iterable")}},14229:(e,t,r)=>{var n=r(24883);e.exports=function(e,t){var r=e[t];return null==r?void 0:n(r)}},21899:(e,t,r)=>{var n=function(e){return e&&e.Math==Math&&e};e.exports=n("object"==typeof globalThis&&globalThis)||n("object"==typeof window&&window)||n("object"==typeof self&&self)||n("object"==typeof r.g&&r.g)||function(){return this}()||Function("return this")()},90953:(e,t,r)=>{var n=r(95329),o=r(89678),a=n({}.hasOwnProperty);e.exports=Object.hasOwn||function(e,t){return a(o(e),t)}},27748:e=>{e.exports={}},34845:(e,t,r)=>{var n=r(21899);e.exports=function(e,t){var r=n.console;r&&r.error&&(1==arguments.length?r.error(e):r.error(e,t))}},15463:(e,t,r)=>{var n=r(626);e.exports=n("document","documentElement")},2840:(e,t,r)=>{var n=r(55746),o=r(95981),a=r(61333);e.exports=!n&&!o((function(){return 7!=Object.defineProperty(a("div"),"a",{get:function(){return 7}}).a}))},37026:(e,t,r)=>{var n=r(21899),o=r(95329),a=r(95981),i=r(82532),s=n.Object,l=o("".split);e.exports=a((function(){return!s("z").propertyIsEnumerable(0)}))?function(e){return"String"==i(e)?l(e,""):s(e)}:s},81302:(e,t,r)=>{var n=r(95329),o=r(57475),a=r(63030),i=n(Function.toString);o(a.inspectSource)||(a.inspectSource=function(e){return i(e)}),e.exports=a.inspectSource},53794:(e,t,r)=>{var n=r(10941),o=r(32029);e.exports=function(e,t){n(t)&&"cause"in t&&o(e,"cause",t.cause)}},21647:(e,t,r)=>{var n=r(76887),o=r(95329),a=r(27748),i=r(10941),s=r(90953),l=r(65988).f,u=r(10946),c=r(684),p=r(91584),f=r(99418),h=r(45602),d=!1,m=f("meta"),g=0,v=function(e){l(e,m,{value:{objectID:"O"+g++,weakData:{}}})},y=e.exports={enable:function(){y.enable=function(){},d=!0;var e=u.f,t=o([].splice),r={};r[m]=1,e(r).length&&(u.f=function(r){for(var n=e(r),o=0,a=n.length;o{var n,o,a,i=r(38019),s=r(21899),l=r(95329),u=r(10941),c=r(32029),p=r(90953),f=r(63030),h=r(44262),d=r(27748),m="Object already initialized",g=s.TypeError,v=s.WeakMap;if(i||f.state){var y=f.state||(f.state=new v),b=l(y.get),w=l(y.has),E=l(y.set);n=function(e,t){if(w(y,e))throw new g(m);return t.facade=e,E(y,e,t),t},o=function(e){return b(y,e)||{}},a=function(e){return w(y,e)}}else{var x=h("state");d[x]=!0,n=function(e,t){if(p(e,x))throw new g(m);return t.facade=e,c(e,x,t),t},o=function(e){return p(e,x)?e[x]:{}},a=function(e){return p(e,x)}}e.exports={set:n,get:o,has:a,enforce:function(e){return a(e)?o(e):n(e,{})},getterFor:function(e){return function(t){var r;if(!u(t)||(r=o(t)).type!==e)throw g("Incompatible receiver, "+e+" required");return r}}}},6782:(e,t,r)=>{var n=r(99813),o=r(12077),a=n("iterator"),i=Array.prototype;e.exports=function(e){return void 0!==e&&(o.Array===e||i[a]===e)}},1052:(e,t,r)=>{var n=r(82532);e.exports=Array.isArray||function(e){return"Array"==n(e)}},57475:e=>{e.exports=function(e){return"function"==typeof e}},24284:(e,t,r)=>{var n=r(95329),o=r(95981),a=r(57475),i=r(9697),s=r(626),l=r(81302),u=function(){},c=[],p=s("Reflect","construct"),f=/^\s*(?:class|function)\b/,h=n(f.exec),d=!f.exec(u),m=function(e){if(!a(e))return!1;try{return p(u,c,e),!0}catch(e){return!1}},g=function(e){if(!a(e))return!1;switch(i(e)){case"AsyncFunction":case"GeneratorFunction":case"AsyncGeneratorFunction":return!1}try{return d||!!h(f,l(e))}catch(e){return!0}};g.sham=!0,e.exports=!p||o((function(){var e;return m(m.call)||!m(Object)||!m((function(){e=!0}))||e}))?g:m},37252:(e,t,r)=>{var n=r(95981),o=r(57475),a=/#|\.prototype\./,i=function(e,t){var r=l[s(e)];return r==c||r!=u&&(o(t)?n(t):!!t)},s=i.normalize=function(e){return String(e).replace(a,".").toLowerCase()},l=i.data={},u=i.NATIVE="N",c=i.POLYFILL="P";e.exports=i},10941:(e,t,r)=>{var n=r(57475);e.exports=function(e){return"object"==typeof e?null!==e:n(e)}},82529:e=>{e.exports=!0},60685:(e,t,r)=>{var n=r(10941),o=r(82532),a=r(99813)("match");e.exports=function(e){var t;return n(e)&&(void 0!==(t=e[a])?!!t:"RegExp"==o(e))}},56664:(e,t,r)=>{var n=r(21899),o=r(626),a=r(57475),i=r(7046),s=r(32302),l=n.Object;e.exports=s?function(e){return"symbol"==typeof e}:function(e){var t=o("Symbol");return a(t)&&i(t.prototype,l(e))}},93091:(e,t,r)=>{var n=r(21899),o=r(86843),a=r(78834),i=r(96059),s=r(69826),l=r(6782),u=r(10623),c=r(7046),p=r(53476),f=r(22902),h=r(7609),d=n.TypeError,m=function(e,t){this.stopped=e,this.result=t},g=m.prototype;e.exports=function(e,t,r){var n,v,y,b,w,E,x,_=r&&r.that,S=!(!r||!r.AS_ENTRIES),A=!(!r||!r.IS_ITERATOR),k=!(!r||!r.INTERRUPTED),C=o(t,_),O=function(e){return n&&h(n,"normal",e),new m(!0,e)},j=function(e){return S?(i(e),k?C(e[0],e[1],O):C(e[0],e[1])):k?C(e,O):C(e)};if(A)n=e;else{if(!(v=f(e)))throw d(s(e)+" is not iterable");if(l(v)){for(y=0,b=u(e);b>y;y++)if((w=j(e[y]))&&c(g,w))return w;return new m(!1)}n=p(e,v)}for(E=n.next;!(x=a(E,n)).done;){try{w=j(x.value)}catch(e){h(n,"throw",e)}if("object"==typeof w&&w&&c(g,w))return w}return new m(!1)}},7609:(e,t,r)=>{var n=r(78834),o=r(96059),a=r(14229);e.exports=function(e,t,r){var i,s;o(e);try{if(!(i=a(e,"return"))){if("throw"===t)throw r;return r}i=n(i,e)}catch(e){s=!0,i=e}if("throw"===t)throw r;if(s)throw i;return o(i),r}},35143:(e,t,r)=>{"use strict";var n,o,a,i=r(95981),s=r(57475),l=r(29290),u=r(249),c=r(99754),p=r(99813),f=r(82529),h=p("iterator"),d=!1;[].keys&&("next"in(a=[].keys())?(o=u(u(a)))!==Object.prototype&&(n=o):d=!0),null==n||i((function(){var e={};return n[h].call(e)!==e}))?n={}:f&&(n=l(n)),s(n[h])||c(n,h,(function(){return this})),e.exports={IteratorPrototype:n,BUGGY_SAFARI_ITERATORS:d}},12077:e=>{e.exports={}},10623:(e,t,r)=>{var n=r(43057);e.exports=function(e){return n(e.length)}},66132:(e,t,r)=>{var n,o,a,i,s,l,u,c,p=r(21899),f=r(86843),h=r(49677).f,d=r(42941).set,m=r(22749),g=r(4470),v=r(58045),y=r(6049),b=p.MutationObserver||p.WebKitMutationObserver,w=p.document,E=p.process,x=p.Promise,_=h(p,"queueMicrotask"),S=_&&_.value;S||(n=function(){var e,t;for(y&&(e=E.domain)&&e.exit();o;){t=o.fn,o=o.next;try{t()}catch(e){throw o?i():a=void 0,e}}a=void 0,e&&e.enter()},m||y||v||!b||!w?!g&&x&&x.resolve?((u=x.resolve(void 0)).constructor=x,c=f(u.then,u),i=function(){c(n)}):y?i=function(){E.nextTick(n)}:(d=f(d,p),i=function(){d(n)}):(s=!0,l=w.createTextNode(""),new b(n).observe(l,{characterData:!0}),i=function(){l.data=s=!s})),e.exports=S||function(e){var t={fn:e,next:void 0};a&&(a.next=t),o||(o=t,i()),a=t}},19297:(e,t,r)=>{var n=r(21899);e.exports=n.Promise},72497:(e,t,r)=>{var n=r(53385),o=r(95981);e.exports=!!Object.getOwnPropertySymbols&&!o((function(){var e=Symbol();return!String(e)||!(Object(e)instanceof Symbol)||!Symbol.sham&&n&&n<41}))},28468:(e,t,r)=>{var n=r(95981),o=r(99813),a=r(82529),i=o("iterator");e.exports=!n((function(){var e=new URL("b?a=1&b=2&c=3","http://a"),t=e.searchParams,r="";return e.pathname="c%20d",t.forEach((function(e,n){t.delete("b"),r+=n+e})),a&&!e.toJSON||!t.sort||"http://a/c%20d?a=1&c=3"!==e.href||"3"!==t.get("c")||"a=1"!==String(new URLSearchParams("?a=1"))||!t[i]||"a"!==new URL("https://a@b").username||"b"!==new URLSearchParams(new URLSearchParams("a=b")).get("a")||"xn--e1aybc"!==new URL("http://тест").host||"#%D0%B1"!==new URL("http://a#б").hash||"a1c3"!==r||"x"!==new URL("http://x",void 0).host}))},38019:(e,t,r)=>{var n=r(21899),o=r(57475),a=r(81302),i=n.WeakMap;e.exports=o(i)&&/native code/.test(a(i))},69520:(e,t,r)=>{"use strict";var n=r(24883),o=function(e){var t,r;this.promise=new e((function(e,n){if(void 0!==t||void 0!==r)throw TypeError("Bad Promise constructor");t=e,r=n})),this.resolve=n(t),this.reject=n(r)};e.exports.f=function(e){return new o(e)}},14649:(e,t,r)=>{var n=r(85803);e.exports=function(e,t){return void 0===e?arguments.length<2?"":t:n(e)}},70344:(e,t,r)=>{var n=r(21899),o=r(60685),a=n.TypeError;e.exports=function(e){if(o(e))throw a("The method doesn't accept regular expressions");return e}},24420:(e,t,r)=>{"use strict";var n=r(55746),o=r(95329),a=r(78834),i=r(95981),s=r(14771),l=r(87857),u=r(36760),c=r(89678),p=r(37026),f=Object.assign,h=Object.defineProperty,d=o([].concat);e.exports=!f||i((function(){if(n&&1!==f({b:1},f(h({},"a",{enumerable:!0,get:function(){h(this,"b",{value:3,enumerable:!1})}}),{b:2})).b)return!0;var e={},t={},r=Symbol(),o="abcdefghijklmnopqrst";return e[r]=7,o.split("").forEach((function(e){t[e]=e})),7!=f({},e)[r]||s(f({},t)).join("")!=o}))?function(e,t){for(var r=c(e),o=arguments.length,i=1,f=l.f,h=u.f;o>i;)for(var m,g=p(arguments[i++]),v=f?d(s(g),f(g)):s(g),y=v.length,b=0;y>b;)m=v[b++],n&&!a(h,g,m)||(r[m]=g[m]);return r}:f},29290:(e,t,r)=>{var n,o=r(96059),a=r(59938),i=r(56759),s=r(27748),l=r(15463),u=r(61333),c=r(44262),p=c("IE_PROTO"),f=function(){},h=function(e){return" + + + + +
+ + + + \ No newline at end of file diff --git a/frontend/favicon.ico b/frontend/favicon.ico new file mode 100644 index 0000000000..413340efb2 Binary files /dev/null and b/frontend/favicon.ico differ diff --git a/frontend/index.d.ts b/frontend/index.d.ts new file mode 100644 index 0000000000..e7461e8266 --- /dev/null +++ b/frontend/index.d.ts @@ -0,0 +1 @@ +declare module 'redux-socket.io-middleware'; diff --git a/frontend/index.html b/frontend/index.html new file mode 100644 index 0000000000..b8776b3bfb --- /dev/null +++ b/frontend/index.html @@ -0,0 +1,16 @@ + + + + + + + InvokeAI - A Stable Diffusion Toolkit + + + + +
+ + + + \ No newline at end of file diff --git a/frontend/package-lock.json b/frontend/package-lock.json new file mode 100644 index 0000000000..5ed016735a --- /dev/null +++ b/frontend/package-lock.json @@ -0,0 +1,10651 @@ +{ + "name": "invoke-ai-ui", + "version": "0.0.1", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "invoke-ai-ui", + "version": "0.0.1", + "dependencies": { + "@chakra-ui/icons": "^2.0.10", + "@chakra-ui/react": "^2.3.1", + "@emotion/react": "^11.10.4", + "@emotion/styled": "^11.10.4", + "@radix-ui/react-context-menu": "^2.0.1", + "@radix-ui/react-slider": "^1.1.0", + "@radix-ui/react-tooltip": "^1.0.2", + "@reduxjs/toolkit": "^1.8.5", + "@types/uuid": "^8.3.4", + "add": "^2.0.6", + "dateformat": "^5.0.3", + "framer-motion": "^7.2.1", + "konva": "^8.3.13", + "lodash": "^4.17.21", + "re-resizable": "^6.9.9", + "react": "^18.2.0", + "react-colorful": "^5.6.1", + "react-dom": "^18.2.0", + "react-dropzone": "^14.2.2", + "react-hotkeys-hook": "^3.4.7", + "react-icons": "^4.4.0", + "react-konva": "^18.2.3", + "react-redux": "^8.0.2", + "react-transition-group": "^4.4.5", + "redux-persist": "^6.0.0", + "socket.io": "^4.5.2", + "socket.io-client": "^4.5.2", + "uuid": "^9.0.0", + "yarn": "^1.22.19" + }, + "devDependencies": { + "@types/dateformat": "^5.0.0", + "@types/react": "^18.0.17", + "@types/react-dom": "^18.0.6", + "@types/react-transition-group": "^4.4.5", + "@typescript-eslint/eslint-plugin": "^5.36.2", + "@typescript-eslint/parser": "^5.36.2", + "@vitejs/plugin-react": "^2.0.1", + "eslint": "^8.23.0", + "eslint-plugin-prettier": "^4.2.1", + "eslint-plugin-react-hooks": "^4.6.0", + "sass": "^1.55.0", + "tsc-watch": "^5.0.3", + "typescript": "^4.6.4", + "vite": "^3.0.7", + "vite-plugin-eslint": "^1.8.1" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "license": "MIT", + "dependencies": { + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.19.3", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.19.3", + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.19.3", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-module-transforms": "^7.19.0", + "@babel/helpers": "^7.19.0", + "@babel/parser": "^7.19.3", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.3", + "@babel/types": "^7.19.3", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.19.3", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.19.3", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", + "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.19.3", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.19.3", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz", + "integrity": "sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.18.6", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.0", + "@babel/types": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", + "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz", + "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz", + "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.0.tgz", + "integrity": "sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.0", + "@babel/types": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.19.3", + "license": "MIT", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", + "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz", + "integrity": "sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/plugin-syntax-jsx": "^7.18.6", + "@babel/types": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz", + "integrity": "sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.18.6.tgz", + "integrity": "sha512-A0LQGx4+4Jv7u/tWzoJF7alZwnBDQd6cGLh9P+Ttk4dpiL+J5p7NSNv/9tlEFFJDq3kjxOavWmbm6t0Gk+A3Ig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.18.6.tgz", + "integrity": "sha512-utZmlASneDfdaMh0m/WausbjUjEdGrQJz0vFK93d7wD3xf5wBtX219+q6IlCNZeguIcxS2f/CvLZrlLSvSHQXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.0.tgz", + "integrity": "sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.13.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.19.3", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.19.3", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.19.3", + "@babel/types": "^7.19.3", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.19.3", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.18.10", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@chakra-ui/accordion": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@chakra-ui/accordion/-/accordion-2.0.12.tgz", + "integrity": "sha512-O3qq8mILo1QODjCGr2xwxC5LNFakBoMzTjEgpvpIMynxWc/1RKfGuFLis3IDfpHIicXmBTK6sNiZXewmna88CQ==", + "license": "MIT", + "dependencies": { + "@chakra-ui/descendant": "3.0.9", + "@chakra-ui/icon": "3.0.9", + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-use-controllable-state": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.3", + "@chakra-ui/transition": "2.0.9" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "framer-motion": ">=4.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/accordion/node_modules/@chakra-ui/icon": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/icon/-/icon-3.0.9.tgz", + "integrity": "sha512-P2Pwm/za6m1W1oqL2kGHH6XrrymsBjqYAFwOW2lB5Q6mI1e+RYe/iMxDoPSLHMYhqdfH7vyib/ffE3Vv3a5oTA==", + "license": "MIT", + "dependencies": { + "@chakra-ui/shared-utils": "2.0.1" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/alert": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/alert/-/alert-2.0.9.tgz", + "integrity": "sha512-hFRIh6ZzQJ0sAESRym15mW/mcZE/yu4z6lFtdToBhpfSlhZLuE7gDdOTxqGkg417hY//48NiNXOCoQ2dUUuHKw==", + "license": "MIT", + "dependencies": { + "@chakra-ui/icon": "3.0.9", + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/spinner": "2.0.9" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/alert/node_modules/@chakra-ui/icon": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/icon/-/icon-3.0.9.tgz", + "integrity": "sha512-P2Pwm/za6m1W1oqL2kGHH6XrrymsBjqYAFwOW2lB5Q6mI1e+RYe/iMxDoPSLHMYhqdfH7vyib/ffE3Vv3a5oTA==", + "license": "MIT", + "dependencies": { + "@chakra-ui/shared-utils": "2.0.1" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/anatomy": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@chakra-ui/anatomy/-/anatomy-2.0.6.tgz", + "integrity": "sha512-Vgop2FFdhVtX7BydjZdJWZAWy+DdXBU1IMaBppz6COaH+/7OXxoI2ec2bs17ehJyBO0M+ud3OLj5UCFQ79YsoQ==", + "license": "MIT" + }, + "node_modules/@chakra-ui/avatar": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/avatar/-/avatar-2.1.0.tgz", + "integrity": "sha512-SRQeH6NNvIBgUc4OsO14ypvcn8I66ndw7r4piIkm+R2zqbYnrzpp1d2zNPNHkChc4xQY71/GenenYO5Fhsi2DA==", + "license": "MIT", + "dependencies": { + "@chakra-ui/image": "2.0.10", + "@chakra-ui/react-children-utils": "2.0.1", + "@chakra-ui/react-context": "2.0.3" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/breadcrumb": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/breadcrumb/-/breadcrumb-2.0.9.tgz", + "integrity": "sha512-cc3WbxrJNRUph4v45qCdcIKJI0xECeV9VikQNIactBB+iexN4d+5P66xZABAkD8wWGmyH5KuSZcd9sFYNmC13w==", + "license": "MIT", + "dependencies": { + "@chakra-ui/react-children-utils": "2.0.1", + "@chakra-ui/react-context": "2.0.3" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/breakpoint-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/breakpoint-utils/-/breakpoint-utils-2.0.3.tgz", + "integrity": "sha512-smi41ZtaiPw4mXaCgicyAh5M45Drt20wypThP+qQUT2CQ51UFZhYlItRA2lCXKQ9QB83POcHPC/oAwIsNOAfTg==", + "license": "MIT" + }, + "node_modules/@chakra-ui/button": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/button/-/button-2.0.9.tgz", + "integrity": "sha512-4BuDBiBlChHW1rQ9iod9MKs87AY3IyvZQwjV3DZTU4IG0KcDDfLQf++jj4dkg9Ttu+pIWhwF42pzA40JxW1oNg==", + "license": "MIT", + "dependencies": { + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.3", + "@chakra-ui/spinner": "2.0.9" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/checkbox": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@chakra-ui/checkbox/-/checkbox-2.1.8.tgz", + "integrity": "sha512-HhRs3nwTFoIE/UpX4N2AZxxW39Xm/Vw01HjwP/59X60kdKs3RBXlm52cODkfUDfveyT9o5ezLhU/jRf0qA909Q==", + "license": "MIT", + "dependencies": { + "@chakra-ui/form-control": "2.0.9", + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-types": "2.0.3", + "@chakra-ui/react-use-callback-ref": "2.0.3", + "@chakra-ui/react-use-controllable-state": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.3", + "@chakra-ui/react-use-safe-layout-effect": "2.0.1", + "@chakra-ui/react-use-update-effect": "2.0.3", + "@chakra-ui/visually-hidden": "2.0.9", + "@zag-js/focus-visible": "0.1.0" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "framer-motion": ">=4.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/clickable": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/clickable/-/clickable-2.0.9.tgz", + "integrity": "sha512-tGXYM6M6I954fif98QkNu5M76oBZmksCTj2mILOan9/BSimpFpu06aPGX3ZIkNsz300nIObn0FdtMvKpIEQueA==", + "license": "MIT", + "dependencies": { + "@chakra-ui/react-use-merge-refs": "2.0.3" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/close-button": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/close-button/-/close-button-2.0.9.tgz", + "integrity": "sha512-0RI/zLR+/mycGbYCCwDAc9hAVG7IIVmdikmo1ET7+rYip4TN94aWR0hA4dYtWqqghG1oW/pYQ9Yja6fEY90V5w==", + "license": "MIT", + "dependencies": { + "@chakra-ui/icon": "3.0.9" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/close-button/node_modules/@chakra-ui/icon": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/icon/-/icon-3.0.9.tgz", + "integrity": "sha512-P2Pwm/za6m1W1oqL2kGHH6XrrymsBjqYAFwOW2lB5Q6mI1e+RYe/iMxDoPSLHMYhqdfH7vyib/ffE3Vv3a5oTA==", + "license": "MIT", + "dependencies": { + "@chakra-ui/shared-utils": "2.0.1" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/color-mode": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@chakra-ui/color-mode/-/color-mode-2.1.7.tgz", + "integrity": "sha512-GAoKJzVRQeuEfCa2i0BZdMwxuOoaGknU3+5wgvLuaSpwlov4OyqpjKMRdSdpjr4IFiqqHK47dsr3H4LQsbO+9w==", + "license": "MIT", + "dependencies": { + "@chakra-ui/react-use-safe-layout-effect": "2.0.1" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/control-box": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/control-box/-/control-box-2.0.9.tgz", + "integrity": "sha512-/viS9OBah1wCLNZbgfwkoQOnVRUYgp8Gypjqk9QNQwnNdFUTEgWc1RWN+1RYO85esJzHLkA2hZFIrYu1TZeZ6g==", + "license": "MIT", + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/counter": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/counter/-/counter-2.0.9.tgz", + "integrity": "sha512-LuqtpyxCOZM19gAmV0vtVeaFd9ccPmEjoGJQ0NoO8CFheltgLC/7m/8YpDbgWiG4+BAkTUfIG+5nLg5hwvvQxw==", + "license": "MIT", + "dependencies": { + "@chakra-ui/number-utils": "2.0.3", + "@chakra-ui/react-use-callback-ref": "2.0.3" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/css-reset": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@chakra-ui/css-reset/-/css-reset-2.0.7.tgz", + "integrity": "sha512-ztGdFQ6U1hX2k6a3HZ8D3A/dZWVxlGe2F5mvUrRU554mFWBYmsq0ydZ7UBEPlykv9NoCz4nN8VCkIxcKJ3p29Q==", + "license": "MIT", + "peerDependencies": { + "@emotion/react": ">=10.0.35", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/descendant": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/descendant/-/descendant-3.0.9.tgz", + "integrity": "sha512-30E5yMWvxgBx43PoI/67r9h9OhbpDfLb/MLOCjtEwebSbD0V5+fmnmCoUELScQbhozQVjA9t195X6UP0VQWj8w==", + "license": "MIT", + "dependencies": { + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.3" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/dom-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/dom-utils/-/dom-utils-2.0.1.tgz", + "integrity": "sha512-sbob9AHQq1+KIQ3XKslafislwtC8pYcpwM0S1SLzgyZumHRwhDimKwdi4MtRQfOCenub0E3diRjp4RpGRL0JuQ==", + "license": "MIT" + }, + "node_modules/@chakra-ui/editable": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/editable/-/editable-2.0.9.tgz", + "integrity": "sha512-s5F3UMR09s6ga3eVhw0UBMGmegtxg6jCp29VLqaEwP5BuWIEOjcJz358gTlnFr3dhvb31e3rcr+B1XiYv4wxqg==", + "license": "MIT", + "dependencies": { + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-types": "2.0.3", + "@chakra-ui/react-use-controllable-state": "2.0.3", + "@chakra-ui/react-use-focus-on-pointer-down": "2.0.1", + "@chakra-ui/react-use-merge-refs": "2.0.3", + "@chakra-ui/react-use-safe-layout-effect": "2.0.1", + "@chakra-ui/react-use-update-effect": "2.0.3", + "@chakra-ui/shared-utils": "2.0.1" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/event-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@chakra-ui/event-utils/-/event-utils-2.0.4.tgz", + "integrity": "sha512-J2YgAM5Dw9hMkwfMsWhsiAG848GfTMxNclUIUcgV9RQhLEs0eTFhelzNiKVOMA3vBxlT6lOARuRun/ESiFZgGg==", + "license": "MIT" + }, + "node_modules/@chakra-ui/focus-lock": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@chakra-ui/focus-lock/-/focus-lock-2.0.10.tgz", + "integrity": "sha512-LeRZYzwfJp0eq84oO8e1pC2qC8v8fJw/P4nYDrCDjuJU753DV6nVjp5MKMRqbkp+6IAElPc+ojy/sp2a9GCocw==", + "license": "MIT", + "dependencies": { + "@chakra-ui/dom-utils": "2.0.1", + "react-focus-lock": "^2.9.1" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/form-control": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/form-control/-/form-control-2.0.9.tgz", + "integrity": "sha512-P8Tr45z/XSAa1m6uAma0eKf1h7Ltg2sLj2jK5YhaXJER9VUUY18iGe96D4JrAXlgEWDhTyWMb63nB+eYO1tKtw==", + "license": "MIT", + "dependencies": { + "@chakra-ui/icon": "3.0.9", + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-types": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.3" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/form-control/node_modules/@chakra-ui/icon": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/icon/-/icon-3.0.9.tgz", + "integrity": "sha512-P2Pwm/za6m1W1oqL2kGHH6XrrymsBjqYAFwOW2lB5Q6mI1e+RYe/iMxDoPSLHMYhqdfH7vyib/ffE3Vv3a5oTA==", + "license": "MIT", + "dependencies": { + "@chakra-ui/shared-utils": "2.0.1" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/hooks": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/hooks/-/hooks-2.0.9.tgz", + "integrity": "sha512-0JRgEPtsBaXr9nQW1xEKlWGA7WwFbLNqac7fQXp9zQvoHOWTfNJkK/NJaVBvyFPgfTLxy37WKHooVSwNG/Lwmg==", + "license": "MIT", + "dependencies": { + "@chakra-ui/react-utils": "2.0.6", + "@chakra-ui/utils": "2.0.9", + "compute-scroll-into-view": "1.0.14", + "copy-to-clipboard": "3.3.1" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/icon": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@chakra-ui/icon/-/icon-3.0.10.tgz", + "integrity": "sha512-utO569d9bptEraJrEhuImfNzQ8v+a8PsQh8kTsodCzg8B16R3t5TTuoqeJqS6Nq16Vq6w87QbX3/4A73CNK5fw==", + "license": "MIT", + "dependencies": { + "@chakra-ui/shared-utils": "2.0.1" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/icons": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@chakra-ui/icons/-/icons-2.0.10.tgz", + "integrity": "sha512-hxMspvysOay2NsJyadM611F/Y4vVzJU/YkXTxsyBjm6v/DbENhpVmPnUf+kwwyl7dINNb9iOF+kuGxnuIEO1Tw==", + "license": "MIT", + "dependencies": { + "@chakra-ui/icon": "3.0.10" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/image": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@chakra-ui/image/-/image-2.0.10.tgz", + "integrity": "sha512-Atc1bdog4V5xv7IbpF2F2UkKWfgG/TD74cIac09JuSpQcYyh7lrJ7iVvhTkeP+LDdCs+QCD7SnTUM4Y0ZlaHbA==", + "license": "MIT", + "dependencies": { + "@chakra-ui/react-use-safe-layout-effect": "2.0.1" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/input": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/input/-/input-2.0.9.tgz", + "integrity": "sha512-6MKydxTyF7JV7PtQHircQ5HBTd6Ik9Vn7p8fCLeAieT0TK8UQTxMWZVPminS7TRWMutrq8W99DcQOBlMz0cKrw==", + "license": "MIT", + "dependencies": { + "@chakra-ui/form-control": "2.0.9", + "@chakra-ui/object-utils": "2.0.3", + "@chakra-ui/react-children-utils": "2.0.1", + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/shared-utils": "2.0.1" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/layout": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@chakra-ui/layout/-/layout-2.1.6.tgz", + "integrity": "sha512-QDNaVu44UI46c+YlSF1KrzJkiwua0UtRXNTnR3jBE1uzcuqRow7xgr3E60dLphY2cPFqAljfQZUNlP3sgvCLww==", + "license": "MIT", + "dependencies": { + "@chakra-ui/breakpoint-utils": "2.0.3", + "@chakra-ui/icon": "3.0.9", + "@chakra-ui/object-utils": "2.0.3", + "@chakra-ui/react-children-utils": "2.0.1", + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/shared-utils": "2.0.1" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/layout/node_modules/@chakra-ui/icon": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/icon/-/icon-3.0.9.tgz", + "integrity": "sha512-P2Pwm/za6m1W1oqL2kGHH6XrrymsBjqYAFwOW2lB5Q6mI1e+RYe/iMxDoPSLHMYhqdfH7vyib/ffE3Vv3a5oTA==", + "license": "MIT", + "dependencies": { + "@chakra-ui/shared-utils": "2.0.1" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/lazy-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/lazy-utils/-/lazy-utils-2.0.1.tgz", + "integrity": "sha512-986YjYq+hEzHDLZiqYlYbdqfiKdC3h2g896Eoe5K2UXtAVxqZI3UOnMH781X6N1R7rGJWquskzG681qFigW/BA==", + "license": "MIT" + }, + "node_modules/@chakra-ui/live-region": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/live-region/-/live-region-2.0.9.tgz", + "integrity": "sha512-ilbo/C5wcUoSHDU5owFPQP3KsabPYGzDEbwV+Z76BlyNdFN2PD0j13RGEH+sBNNZ3HzLyyuuc1YmkVcJi7ycQg==", + "license": "MIT", + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/media-query": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/media-query/-/media-query-3.2.5.tgz", + "integrity": "sha512-V+Dngi/r7u/uj7JhsZerM1RI597Oo4wED2ojNfclnnEVb/IoqktiuFy6RQgbo3HmE7M/E5B1i4yYzt7tQJhXlg==", + "license": "MIT", + "dependencies": { + "@chakra-ui/breakpoint-utils": "2.0.3", + "@chakra-ui/react-env": "2.0.9" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/menu": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@chakra-ui/menu/-/menu-2.0.13.tgz", + "integrity": "sha512-XZYoq9k/txAELUgn5OokyxfXEpVZwBueVYXiT9ji0XvMuzXVxeHd40klJEkiJUctNsOahZf10t5yxlT4B00pwA==", + "license": "MIT", + "dependencies": { + "@chakra-ui/clickable": "2.0.9", + "@chakra-ui/descendant": "3.0.9", + "@chakra-ui/lazy-utils": "2.0.1", + "@chakra-ui/popper": "3.0.7", + "@chakra-ui/react-children-utils": "2.0.1", + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-use-animation-state": "2.0.3", + "@chakra-ui/react-use-controllable-state": "2.0.3", + "@chakra-ui/react-use-disclosure": "2.0.3", + "@chakra-ui/react-use-focus-effect": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.3", + "@chakra-ui/react-use-outside-click": "2.0.3", + "@chakra-ui/react-use-update-effect": "2.0.3", + "@chakra-ui/transition": "2.0.9" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "framer-motion": ">=4.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/modal": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@chakra-ui/modal/-/modal-2.1.7.tgz", + "integrity": "sha512-A+CbvhQYpmLH3SrqJ1wJysUCGm0mNoSDxRjP4wX98j56nMTDAsMYlzttpuLmKaSzvbJ7uEQDLtQV8lZjB0gUuw==", + "license": "MIT", + "dependencies": { + "@chakra-ui/close-button": "2.0.9", + "@chakra-ui/focus-lock": "2.0.10", + "@chakra-ui/portal": "2.0.9", + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-types": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.3", + "@chakra-ui/transition": "2.0.9", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "^2.5.4" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "framer-motion": ">=4.0.0", + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/@chakra-ui/number-input": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/number-input/-/number-input-2.0.9.tgz", + "integrity": "sha512-RsDzoNvSBZMgyXjN543AtQ2v99U1p/0xnGWZy4NCkgCDWMBn3kIXqSzQq5CB9Ot0MD8nnKF5VYdVdXWguXExEQ==", + "license": "MIT", + "dependencies": { + "@chakra-ui/counter": "2.0.9", + "@chakra-ui/form-control": "2.0.9", + "@chakra-ui/icon": "3.0.9", + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-types": "2.0.3", + "@chakra-ui/react-use-callback-ref": "2.0.3", + "@chakra-ui/react-use-event-listener": "2.0.3", + "@chakra-ui/react-use-interval": "2.0.1", + "@chakra-ui/react-use-merge-refs": "2.0.3", + "@chakra-ui/react-use-safe-layout-effect": "2.0.1", + "@chakra-ui/react-use-update-effect": "2.0.3" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/number-input/node_modules/@chakra-ui/icon": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/icon/-/icon-3.0.9.tgz", + "integrity": "sha512-P2Pwm/za6m1W1oqL2kGHH6XrrymsBjqYAFwOW2lB5Q6mI1e+RYe/iMxDoPSLHMYhqdfH7vyib/ffE3Vv3a5oTA==", + "license": "MIT", + "dependencies": { + "@chakra-ui/shared-utils": "2.0.1" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/number-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/number-utils/-/number-utils-2.0.3.tgz", + "integrity": "sha512-oN03kYAUCCp/FNtpLr5mh+cvd/sRTzZWTBoFydmxc955psXq/X950gzs6o5kzoeFCpgXaxMmHAXQm3ReEK2NsQ==", + "license": "MIT" + }, + "node_modules/@chakra-ui/object-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/object-utils/-/object-utils-2.0.3.tgz", + "integrity": "sha512-36prckrqTynVD/JTzyCr8OCWVOrMs/awZo3djVbIiNxRIcJ5iEwUVy26h3MWN4ENSopipBtxNfAwPNTLU5Si/g==", + "license": "MIT" + }, + "node_modules/@chakra-ui/pin-input": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@chakra-ui/pin-input/-/pin-input-2.0.12.tgz", + "integrity": "sha512-gaMRp5AFW+qAJCUj93V1WluuYBBZ/5A3Wy5q796g8Auvw7vufgkVtl6EBznwvtynZN8gJwbRFpMtJxQyXCkUiw==", + "license": "MIT", + "dependencies": { + "@chakra-ui/descendant": "3.0.9", + "@chakra-ui/react-children-utils": "2.0.1", + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-use-controllable-state": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.3" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/popover": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/popover/-/popover-2.0.9.tgz", + "integrity": "sha512-+7tH4RVuheFQOyAZ5KT9x+qsLvz7rGuKaHtb0427+5bhUzLaSAghtr/afzOKHDwUVBwF2tTUNanR23ipW1fXDg==", + "license": "MIT", + "dependencies": { + "@chakra-ui/close-button": "2.0.9", + "@chakra-ui/hooks": "2.0.9", + "@chakra-ui/lazy-utils": "2.0.1", + "@chakra-ui/popper": "3.0.7", + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-types": "2.0.3", + "@chakra-ui/react-use-disclosure": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.3" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "framer-motion": ">=4.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/popper": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@chakra-ui/popper/-/popper-3.0.7.tgz", + "integrity": "sha512-xLYhuNsk1gOjymtek1ZdZlG21hmg2a7Iu2KsD9Hi7+aUxc2K5/XxX+/vyjjz8u4s0gmj83pTqnauQRynb/TCXA==", + "license": "MIT", + "dependencies": { + "@chakra-ui/react-types": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.3", + "@popperjs/core": "^2.9.3" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/portal": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/portal/-/portal-2.0.9.tgz", + "integrity": "sha512-9e9S0MLbkpofPGlyYA12jNYSdndugy6ylPi5pC9nr3/VqG2Kn+8VcBChAeXW8K4ms7WFc74rNX1pBY/UVwr4qg==", + "license": "MIT", + "dependencies": { + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-use-safe-layout-effect": "2.0.1" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/@chakra-ui/progress": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@chakra-ui/progress/-/progress-2.0.10.tgz", + "integrity": "sha512-my0Pi3NG1PYhlvCav4fybg3gL5HBNe+7lO4PVdri4QHEyfJlrDeBWID+1GgqlpUWdTj3sOf7ysku+FEgkeOeSA==", + "license": "MIT", + "dependencies": { + "@chakra-ui/react-context": "2.0.3" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/provider": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/@chakra-ui/provider/-/provider-2.0.16.tgz", + "integrity": "sha512-4t/PmjJ7WXPPaPfoYgw8F1/rVtorZuvknugHfOZcOtAPGQmOPotSv28qjKpu/mCvc1GMGV0swMsvCeInYz7g0w==", + "license": "MIT", + "dependencies": { + "@chakra-ui/css-reset": "2.0.7", + "@chakra-ui/portal": "2.0.9", + "@chakra-ui/react-env": "2.0.9", + "@chakra-ui/system": "2.2.9", + "@chakra-ui/utils": "2.0.9" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0", + "@emotion/styled": "^11.0.0", + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/@chakra-ui/radio": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@chakra-ui/radio/-/radio-2.0.10.tgz", + "integrity": "sha512-LhAWsY22cmb+M/iyhFgkzf2+V9TJmAC77Cd+GbP3M3sxDSEUDtq08KOc3JjoYc3GzeZml3JL1yssbxh+liY3xA==", + "license": "MIT", + "dependencies": { + "@chakra-ui/form-control": "2.0.9", + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-types": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.3", + "@zag-js/focus-visible": "0.1.0" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@chakra-ui/react/-/react-2.3.2.tgz", + "integrity": "sha512-qOcDLbA1x4pnpJPtF4YJ7pZzK/ki6SoQl9Vj7fsR+hJw1lt3y1475NSyYGiA6qgho/8twUgYLhcdrTbQPcmOHg==", + "license": "MIT", + "dependencies": { + "@chakra-ui/accordion": "2.0.12", + "@chakra-ui/alert": "2.0.9", + "@chakra-ui/avatar": "2.1.0", + "@chakra-ui/breadcrumb": "2.0.9", + "@chakra-ui/button": "2.0.9", + "@chakra-ui/checkbox": "2.1.8", + "@chakra-ui/close-button": "2.0.9", + "@chakra-ui/control-box": "2.0.9", + "@chakra-ui/counter": "2.0.9", + "@chakra-ui/css-reset": "2.0.7", + "@chakra-ui/editable": "2.0.9", + "@chakra-ui/form-control": "2.0.9", + "@chakra-ui/hooks": "2.0.9", + "@chakra-ui/icon": "3.0.9", + "@chakra-ui/image": "2.0.10", + "@chakra-ui/input": "2.0.9", + "@chakra-ui/layout": "2.1.6", + "@chakra-ui/live-region": "2.0.9", + "@chakra-ui/media-query": "3.2.5", + "@chakra-ui/menu": "2.0.13", + "@chakra-ui/modal": "2.1.7", + "@chakra-ui/number-input": "2.0.9", + "@chakra-ui/pin-input": "2.0.12", + "@chakra-ui/popover": "2.0.9", + "@chakra-ui/popper": "3.0.7", + "@chakra-ui/portal": "2.0.9", + "@chakra-ui/progress": "2.0.10", + "@chakra-ui/provider": "2.0.16", + "@chakra-ui/radio": "2.0.10", + "@chakra-ui/react-env": "2.0.9", + "@chakra-ui/select": "2.0.10", + "@chakra-ui/skeleton": "2.0.15", + "@chakra-ui/slider": "2.0.10", + "@chakra-ui/spinner": "2.0.9", + "@chakra-ui/stat": "2.0.9", + "@chakra-ui/switch": "2.0.11", + "@chakra-ui/system": "2.2.9", + "@chakra-ui/table": "2.0.9", + "@chakra-ui/tabs": "2.1.1", + "@chakra-ui/tag": "2.0.9", + "@chakra-ui/textarea": "2.0.10", + "@chakra-ui/theme": "2.1.11", + "@chakra-ui/toast": "3.0.10", + "@chakra-ui/tooltip": "2.0.10", + "@chakra-ui/transition": "2.0.9", + "@chakra-ui/utils": "2.0.9", + "@chakra-ui/visually-hidden": "2.0.9" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0", + "@emotion/styled": "^11.0.0", + "framer-motion": ">=4.0.0", + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/@chakra-ui/react-children-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-children-utils/-/react-children-utils-2.0.1.tgz", + "integrity": "sha512-sEgpuh/vWSt2+W0F49EGYXXUyjmg0lbosjVg6qUKHv9sAyx5tbrOrZ6df/TaMUSAe9m3AUOMGqUIPLpxno0DjA==", + "license": "MIT" + }, + "node_modules/@chakra-ui/react-context": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-context/-/react-context-2.0.3.tgz", + "integrity": "sha512-KmPq6sb1y05WsOUqXZtBBC4LsNKZIFrp2thTsLBwcuH7lkXZwPMHmJGKa9K980P+SWEgfH2s2PY2z+QrIuqWGg==", + "license": "MIT", + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-env": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-env/-/react-env-2.0.9.tgz", + "integrity": "sha512-4AJHNUGBR19hzVyOILYpZZgq8jGrpEcbhvR++CppbvPH7vfPZpoz6L/cBtHxS07YwDtUeBL8yCNiLlTxctV//Q==", + "license": "MIT", + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-types": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-types/-/react-types-2.0.3.tgz", + "integrity": "sha512-1mJYOQldFTALE0Wr3j6tk/MYvgQIp6CKkJulNzZrI8QN+ox/bJOh8OVP4vhwqvfigdLTui0g0k8M9h+j2ub/Mw==", + "license": "MIT", + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-animation-state": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-animation-state/-/react-use-animation-state-2.0.3.tgz", + "integrity": "sha512-sjGgzMMmxurwKDSFhDLpLNn3SWUERI5iAZOOa0pYnyOLGVXMowgIjK6jpZxre1vc3A+unjJk5P4qeiyY+C4uwQ==", + "license": "MIT", + "dependencies": { + "@chakra-ui/dom-utils": "2.0.1", + "@chakra-ui/react-use-event-listener": "2.0.3" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-callback-ref": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-callback-ref/-/react-use-callback-ref-2.0.3.tgz", + "integrity": "sha512-kdYlhgnQKWWLNwl3WSv/Oq3+mlnu2p3y4Xc1AqKVHVcBOdQE9lpW3d7ZaOoK2aIXXWq1rocscOiXBUtM0Vqd2A==", + "license": "MIT", + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-controllable-state": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-controllable-state/-/react-use-controllable-state-2.0.3.tgz", + "integrity": "sha512-su8efwCWWnY2LQUU6PEnYwSGJX8kvPSO2KyUKuymx8q3fNWuyhzAZriG/TbeeCxESLp70+wuniUlSGRa4vxylQ==", + "license": "MIT", + "dependencies": { + "@chakra-ui/react-use-callback-ref": "2.0.3" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-disclosure": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-disclosure/-/react-use-disclosure-2.0.3.tgz", + "integrity": "sha512-3IdrzvQZcgjqSx5wTVffInOyhMU+d3ZlIE26JmqejMyN/B+qAs932iKfm0A1mTMPTz38ZnNtuaKazmzyfR1ePg==", + "license": "MIT", + "dependencies": { + "@chakra-ui/react-use-callback-ref": "2.0.3" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-event-listener": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-event-listener/-/react-use-event-listener-2.0.3.tgz", + "integrity": "sha512-m3ZdJjo3QQ1HcQGnehlBTgHaCVewz5fwIRTXVzbZTraVJr4k589Zf87eagW57tT4dyv656lSmdhaFGZ8p5Snww==", + "license": "MIT", + "dependencies": { + "@chakra-ui/react-use-callback-ref": "2.0.3" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-focus-effect": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-focus-effect/-/react-use-focus-effect-2.0.3.tgz", + "integrity": "sha512-N0rho7P+rH5cn13dbS8GUOye+6RYXAmXhmlS+WW/3lWidGH3HAbMoOVf56UiuSnE1+2or8/U7qRshUryj2H1nA==", + "license": "MIT", + "dependencies": { + "@chakra-ui/dom-utils": "2.0.1", + "@chakra-ui/react-use-event-listener": "2.0.3", + "@chakra-ui/react-use-update-effect": "2.0.3" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-focus-on-pointer-down": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-focus-on-pointer-down/-/react-use-focus-on-pointer-down-2.0.1.tgz", + "integrity": "sha512-f0qL2iWvajUo+0jwDZyJpUMJ6J6BH3WjDZE2Rp6cns4pgI6uYuv2gj+FqQ5jnoYdXkeER6lBI56a+aIW/1RYiA==", + "license": "MIT", + "dependencies": { + "@chakra-ui/react-use-event-listener": "2.0.3" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-interval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-interval/-/react-use-interval-2.0.1.tgz", + "integrity": "sha512-6ZLzKA7Ga894UZcXO3bbGYThlhviiau1oxZ1UcJG5pUXNM9Up7O/4Joq31sL+KcpteCN45vd1etomilsv/blxw==", + "license": "MIT", + "dependencies": { + "@chakra-ui/react-use-callback-ref": "2.0.3" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-merge-refs": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-merge-refs/-/react-use-merge-refs-2.0.3.tgz", + "integrity": "sha512-n35BmVbasy5Esa6qxznWmiV3NaRxGpqMpZH0n+X7aXt8VkGAJzRpAVjUmKCLNYyCLpqsQceCmAEK8a5SR6vxqw==", + "license": "MIT", + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-outside-click": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-outside-click/-/react-use-outside-click-2.0.3.tgz", + "integrity": "sha512-r5OohM8lOuZTz6e3vVHvfm/3sEkd06nUPBNU+r3rWh1I7bR9z5Gia/BOQD6GE4jUTanDkHcH76Pf9qJ45kpibQ==", + "license": "MIT", + "dependencies": { + "@chakra-ui/react-use-callback-ref": "2.0.3" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-pan-event": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-pan-event/-/react-use-pan-event-2.0.4.tgz", + "integrity": "sha512-lcEjngfCgIjE5qZeJiaDx+aJzZPLjbjUmbWumi8pIgWOnDL8Ffjh7AMKW4CddP5OgcRnDDb+7aqJbb55wraboA==", + "license": "MIT", + "dependencies": { + "@chakra-ui/event-utils": "2.0.4", + "framesync": "5.3.0" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-previous": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-previous/-/react-use-previous-2.0.1.tgz", + "integrity": "sha512-ROi+/puVd8D1QaxBSOcGlJNqV2x02ppSgmXzZZJhM8ryFLZjY9ojV3HhamB2IJ/7SIb1rMSSV1GPedFw7YMCwA==", + "license": "MIT", + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-safe-layout-effect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-safe-layout-effect/-/react-use-safe-layout-effect-2.0.1.tgz", + "integrity": "sha512-H+ZOjkPqv3KBPEoP68JKpQBNdLOI0mwzEiTT397UdvBVCCJ+1/ijWVUT+Ub/pYic60O6xUghy5ORaWqJHhnKDA==", + "license": "MIT", + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-size": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-size/-/react-use-size-2.0.3.tgz", + "integrity": "sha512-hr4hKepPUmM2paXseSZiOTK2y+ZqnSzYNusDEB01f+cDerFjdN1jSfNJKXpiKF0+hNESXfOPQb3Zt0eDusRdoA==", + "license": "MIT", + "dependencies": { + "@zag-js/element-size": "0.1.0" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-timeout": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-timeout/-/react-use-timeout-2.0.1.tgz", + "integrity": "sha512-zXh9RH+GciKr8hvaOADHOoHP72B7UZUEymA8CWCV4WEs/9s/PfQJH7X1bwvaj43CcOmfVQg4oODWqCYQM1lSsg==", + "license": "MIT", + "dependencies": { + "@chakra-ui/react-use-callback-ref": "2.0.3" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-update-effect": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-update-effect/-/react-use-update-effect-2.0.3.tgz", + "integrity": "sha512-8hkP1o/UUUA49w/R+XyAlPiCjxXTCWCNsHWUOEhAitjJfoCNUjgaNKOD52hT07kc5ACJEcJQHA5327LnwtiIlg==", + "license": "MIT", + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-utils/-/react-utils-2.0.6.tgz", + "integrity": "sha512-ZL0FPaolovXOxMzYRSLHgBYtvxIkA/c5GTSYpXL8DcC+TBLZnAmQ8BPTS2b6xys6xvwdQjkZRUeQ0cBNFaryJg==", + "license": "MIT", + "dependencies": { + "@chakra-ui/utils": "2.0.9" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react/node_modules/@chakra-ui/icon": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/icon/-/icon-3.0.9.tgz", + "integrity": "sha512-P2Pwm/za6m1W1oqL2kGHH6XrrymsBjqYAFwOW2lB5Q6mI1e+RYe/iMxDoPSLHMYhqdfH7vyib/ffE3Vv3a5oTA==", + "license": "MIT", + "dependencies": { + "@chakra-ui/shared-utils": "2.0.1" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/select": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@chakra-ui/select/-/select-2.0.10.tgz", + "integrity": "sha512-7AslBWwI/JyczjMMGtPuN34M/C38koVd+N/pb6swHoIP9TRkkdvDlonIakcmtO1oLEzlNIFKmt4FQ7bUp9ea5Q==", + "license": "MIT", + "dependencies": { + "@chakra-ui/form-control": "2.0.9" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/shared-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/shared-utils/-/shared-utils-2.0.1.tgz", + "integrity": "sha512-NXDBl/u4wrSNp0ON5R3r3evkRurrAz2yuO7neooaG+O5HEenVouGqm4CsXd6lUAPmjwiGzA0LQFNCt0Hj92dXg==", + "license": "MIT" + }, + "node_modules/@chakra-ui/skeleton": { + "version": "2.0.15", + "resolved": "https://registry.npmjs.org/@chakra-ui/skeleton/-/skeleton-2.0.15.tgz", + "integrity": "sha512-QVMkXwrH9jLfim8uJTZcjHeGjzoquNcHGXD5wapd7eDqp9BygvmMXAHBxFm8eEJLHuvIqLX94P6DLeiieYwX7Q==", + "license": "MIT", + "dependencies": { + "@chakra-ui/media-query": "3.2.5", + "@chakra-ui/react-use-previous": "2.0.1" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/slider": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@chakra-ui/slider/-/slider-2.0.10.tgz", + "integrity": "sha512-F0RGl2ruADbXO/GnoBUiTEl+przxhZo2e0tfw9VTtS+RsJZ22uHrTNVvVJHNmjK7/E3++kBfaLCacoJFz/io+g==", + "license": "MIT", + "dependencies": { + "@chakra-ui/number-utils": "2.0.3", + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-types": "2.0.3", + "@chakra-ui/react-use-callback-ref": "2.0.3", + "@chakra-ui/react-use-controllable-state": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.3", + "@chakra-ui/react-use-pan-event": "2.0.4", + "@chakra-ui/react-use-size": "2.0.3", + "@chakra-ui/react-use-update-effect": "2.0.3" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/spinner": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/spinner/-/spinner-2.0.9.tgz", + "integrity": "sha512-9ALl51fiVWptDu2J2xcv0TSfGf4buumpHrEXHvV2Qy+HZ6rYnUmSThBSb/VgoQS+rASG8bAbLUPlQTQ+v9ibFg==", + "license": "MIT", + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/stat": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/stat/-/stat-2.0.9.tgz", + "integrity": "sha512-C9cytqegWSGJ/hh3/qwsgGlerXLYHrU0iQcJQ+pKSRFJhshXsv3go5IR6kVL72Yf2s4Gs5c3GsMZrLM22ePpDg==", + "license": "MIT", + "dependencies": { + "@chakra-ui/icon": "3.0.9", + "@chakra-ui/react-context": "2.0.3" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/stat/node_modules/@chakra-ui/icon": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/icon/-/icon-3.0.9.tgz", + "integrity": "sha512-P2Pwm/za6m1W1oqL2kGHH6XrrymsBjqYAFwOW2lB5Q6mI1e+RYe/iMxDoPSLHMYhqdfH7vyib/ffE3Vv3a5oTA==", + "license": "MIT", + "dependencies": { + "@chakra-ui/shared-utils": "2.0.1" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/styled-system": { + "version": "2.3.4", + "license": "MIT", + "peer": true, + "dependencies": { + "csstype": "^3.0.11", + "lodash.mergewith": "4.6.2" + } + }, + "node_modules/@chakra-ui/switch": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@chakra-ui/switch/-/switch-2.0.11.tgz", + "integrity": "sha512-gY8OGBnoPosZpq7dDNVf432t67pTc/cz5VkGhbtER7bbjXSoXe0DAiAYL+HT2kD7mbTJQzzHK/y0St0WimR1Mw==", + "license": "MIT", + "dependencies": { + "@chakra-ui/checkbox": "2.1.8" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "framer-motion": ">=4.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/system": { + "version": "2.2.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/system/-/system-2.2.9.tgz", + "integrity": "sha512-SyTeIGm+goyYK8vqX4dU6oeLhxUAeGI3Cl+mxA+aiKIX01YTALhTWhpbrsuMYBevV+l9EGK12egPUQE+Mo3WlQ==", + "license": "MIT", + "dependencies": { + "@chakra-ui/color-mode": "2.1.7", + "@chakra-ui/react-utils": "2.0.6", + "@chakra-ui/styled-system": "2.3.1", + "@chakra-ui/utils": "2.0.9", + "react-fast-compare": "3.2.0" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0", + "@emotion/styled": "^11.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/system/node_modules/@chakra-ui/styled-system": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/styled-system/-/styled-system-2.3.1.tgz", + "integrity": "sha512-jyR9s2yk5TEyq4HUfjrgUeaOzd9ZTZrbjK96UjtiTCZGO/q4j2RXtYvfheUjUyW1UnzI2A1ffHOJca8tBMDjpA==", + "license": "MIT", + "dependencies": { + "csstype": "^3.0.11", + "lodash.mergewith": "4.6.2" + } + }, + "node_modules/@chakra-ui/table": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/table/-/table-2.0.9.tgz", + "integrity": "sha512-XRz6+x4dMeQX3xyViyG2H/P1STI/2vwvgU2cjzzwS+5fZ2JdGaTgYzBb+IZoH9agEq1Ma3rlKMUPDrRCFb7kLQ==", + "license": "MIT", + "dependencies": { + "@chakra-ui/react-context": "2.0.3" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/tabs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/tabs/-/tabs-2.1.1.tgz", + "integrity": "sha512-xA+vwqpAHb0nBLrkiO5Lea2UDGROyAIBqsyp/8XXXEr6eKxtNe1I6WJPbDQy0aazB2ToAA0R6fT34HjLaXP8MQ==", + "license": "MIT", + "dependencies": { + "@chakra-ui/clickable": "2.0.9", + "@chakra-ui/descendant": "3.0.9", + "@chakra-ui/lazy-utils": "2.0.1", + "@chakra-ui/react-children-utils": "2.0.1", + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-use-controllable-state": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.3", + "@chakra-ui/react-use-safe-layout-effect": "2.0.1" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/tag": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/tag/-/tag-2.0.9.tgz", + "integrity": "sha512-NKARwhsZ04t2vkrdRhNcakEiVtg1q44yUUsDw2Jwdu4idAWQupZGGochQI2Ac4T2MI1b66zQUkaGnm3l1mhTtg==", + "license": "MIT", + "dependencies": { + "@chakra-ui/icon": "3.0.9", + "@chakra-ui/react-context": "2.0.3" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/tag/node_modules/@chakra-ui/icon": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/icon/-/icon-3.0.9.tgz", + "integrity": "sha512-P2Pwm/za6m1W1oqL2kGHH6XrrymsBjqYAFwOW2lB5Q6mI1e+RYe/iMxDoPSLHMYhqdfH7vyib/ffE3Vv3a5oTA==", + "license": "MIT", + "dependencies": { + "@chakra-ui/shared-utils": "2.0.1" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/textarea": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@chakra-ui/textarea/-/textarea-2.0.10.tgz", + "integrity": "sha512-HSo0EPsY8XKGA+Af6jTob1oe1T6NKZwgjLmX0binK3MMM9pDTXsUTw8GD0g971lxw9oktVMLK/O9QVAgVAm5mw==", + "license": "MIT", + "dependencies": { + "@chakra-ui/form-control": "2.0.9" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/theme": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/@chakra-ui/theme/-/theme-2.1.11.tgz", + "integrity": "sha512-gI0NLU6wO/5cRq8gbDHuy24Y/ZhJxN4D/2uucNN9is3h+d58/En5jV3fwzZW8PLiLKW/T2CmbYWEZWV2YkcUVA==", + "license": "MIT", + "dependencies": { + "@chakra-ui/anatomy": "2.0.6", + "@chakra-ui/theme-tools": "2.0.11" + }, + "peerDependencies": { + "@chakra-ui/styled-system": ">=2.0.0" + } + }, + "node_modules/@chakra-ui/theme-tools": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@chakra-ui/theme-tools/-/theme-tools-2.0.11.tgz", + "integrity": "sha512-0Juf98bAyOgnBeQ39nMKWqRsOxZDw75BbAB8o0oVyjhYVS1wJh7tFX1ZRV8N/+AN6fuRXEznZPpyUh3J+ZTiRg==", + "license": "MIT", + "dependencies": { + "@chakra-ui/anatomy": "2.0.6", + "@ctrl/tinycolor": "^3.4.0" + }, + "peerDependencies": { + "@chakra-ui/styled-system": ">=2.0.0" + } + }, + "node_modules/@chakra-ui/toast": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@chakra-ui/toast/-/toast-3.0.10.tgz", + "integrity": "sha512-i/oEtzmarO0hM6fxa55OmA8ZGkZv9b+vIC2xs5kQ/C0rJaC0ycibok8srq2Stjq9309fZNezyzThQp6e9acUYQ==", + "license": "MIT", + "dependencies": { + "@chakra-ui/alert": "2.0.9", + "@chakra-ui/close-button": "2.0.9", + "@chakra-ui/portal": "2.0.9", + "@chakra-ui/react-use-timeout": "2.0.1", + "@chakra-ui/react-use-update-effect": "2.0.3", + "@chakra-ui/theme": "2.1.11" + }, + "peerDependencies": { + "@chakra-ui/system": "2.2.9", + "framer-motion": ">=4.0.0", + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/@chakra-ui/tooltip": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@chakra-ui/tooltip/-/tooltip-2.0.10.tgz", + "integrity": "sha512-pBILBdZoux2K3EW9V6JuyZYUWz2/Y7oYCVO6AwNOesiEBGAONyzoDwFV728EzPEHe9e+YBcKOSZ9tEpDdrzHMA==", + "license": "MIT", + "dependencies": { + "@chakra-ui/popper": "3.0.7", + "@chakra-ui/portal": "2.0.9", + "@chakra-ui/react-types": "2.0.3", + "@chakra-ui/react-use-disclosure": "2.0.3", + "@chakra-ui/react-use-event-listener": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.3" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "framer-motion": ">=4.0.0", + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/@chakra-ui/transition": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/transition/-/transition-2.0.9.tgz", + "integrity": "sha512-cVfKdZl128AEj0LDS8M9dzXao4wmTVj3gRJBnm91Qcg243Pm8OlgIBNbHEwsq/Fps+PsN431BtEGfL4w79wQEA==", + "license": "MIT", + "peerDependencies": { + "framer-motion": ">=4.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/utils": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/utils/-/utils-2.0.9.tgz", + "integrity": "sha512-7ct5562Jw6pZdtj63XfUkEUXXsCCVqdqIXyLtQ9VgOKtRQWwDxzc8uPI5Zjdw9AleEITZFUH8TNKWn75nm54kQ==", + "license": "MIT", + "dependencies": { + "@types/lodash.mergewith": "4.6.6", + "css-box-model": "1.2.1", + "framesync": "5.3.0", + "lodash.mergewith": "4.6.2" + } + }, + "node_modules/@chakra-ui/visually-hidden": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/visually-hidden/-/visually-hidden-2.0.9.tgz", + "integrity": "sha512-PkNxrRGp9H3bdqEaoo8XGt/AL9UuGRTom0/9XJa+G/Dj8Cy1sDuamOWk3pN/ZQs46RokfK9Uh5LqPY5dwSDweg==", + "license": "MIT", + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@ctrl/tinycolor": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.4.1.tgz", + "integrity": "sha512-ej5oVy6lykXsvieQtqZxCOaLT+xD4+QNarq78cIYISHmZXshCvROLudpQN3lfL8G0NL7plMSSK+zlyvCaIJ4Iw==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/@emotion/babel-plugin": { + "version": "11.10.2", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.2.tgz", + "integrity": "sha512-xNQ57njWTFVfPAc3cjfuaPdsgLp5QOSuRsj9MA6ndEhH/AzuZM86qIQzt6rq+aGBwj3n5/TkLmU5lhAfdRmogA==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/plugin-syntax-jsx": "^7.17.12", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.0", + "@emotion/memoize": "^0.8.0", + "@emotion/serialize": "^1.1.0", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.0.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@emotion/cache": { + "version": "11.10.3", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.3.tgz", + "integrity": "sha512-Psmp/7ovAa8appWh3g51goxu/z3iVms7JXOreq136D8Bbn6dYraPnmL6mdM8GThEx9vwSn92Fz+mGSjBzN8UPQ==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.8.0", + "@emotion/sheet": "^1.2.0", + "@emotion/utils": "^1.2.0", + "@emotion/weak-memoize": "^0.3.0", + "stylis": "4.0.13" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz", + "integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ==", + "license": "MIT" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", + "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.8.0" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", + "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==", + "license": "MIT" + }, + "node_modules/@emotion/react": { + "version": "11.10.4", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.4.tgz", + "integrity": "sha512-j0AkMpr6BL8gldJZ6XQsQ8DnS9TxEQu1R+OGmDZiWjBAJtCcbt0tS3I/YffoqHXxH6MjgI7KdMbYKw3MEiU9eA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.10.0", + "@emotion/cache": "^11.10.0", + "@emotion/serialize": "^1.1.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", + "@emotion/utils": "^1.2.0", + "@emotion/weak-memoize": "^0.3.0", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.0.tgz", + "integrity": "sha512-F1ZZZW51T/fx+wKbVlwsfchr5q97iW8brAnXmsskz4d0hVB4O3M/SiA3SaeH06x02lSNzkkQv+n3AX3kCXKSFA==", + "license": "MIT", + "dependencies": { + "@emotion/hash": "^0.9.0", + "@emotion/memoize": "^0.8.0", + "@emotion/unitless": "^0.8.0", + "@emotion/utils": "^1.2.0", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.0.tgz", + "integrity": "sha512-OiTkRgpxescko+M51tZsMq7Puu/KP55wMT8BgpcXVG2hqXc0Vo0mfymJ/Uj24Hp0i083ji/o0aLddh08UEjq8w==", + "license": "MIT" + }, + "node_modules/@emotion/styled": { + "version": "11.10.4", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.10.4.tgz", + "integrity": "sha512-pRl4R8Ez3UXvOPfc2bzIoV8u9P97UedgHS4FPX594ntwEuAMA114wlaHvOK24HB48uqfXiGlYIZYCxVJ1R1ttQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.10.0", + "@emotion/is-prop-valid": "^1.2.0", + "@emotion/serialize": "^1.1.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", + "@emotion/utils": "^1.2.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", + "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==", + "license": "MIT" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz", + "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz", + "integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw==", + "license": "MIT" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz", + "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==", + "license": "MIT" + }, + "node_modules/@eslint/eslintrc": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.2.tgz", + "integrity": "sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@floating-ui/core": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-0.7.3.tgz", + "integrity": "sha512-buc8BXHmG9l82+OQXOFU3Kr2XQx9ys01U/Q9HMIrZ300iLc8HLMgh7dcCqgYzAzf4BkoQvDcXf5Y+CuEZ5JBYg==" + }, + "node_modules/@floating-ui/dom": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-0.5.4.tgz", + "integrity": "sha512-419BMceRLq0RrmTSDxn8hf9R3VCJv2K9PUfugh5JyEFmdjzDo+e8U5EdR8nzKq8Yj1htzLm3b6eQEEam3/rrtg==", + "dependencies": { + "@floating-ui/core": "^0.7.3" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-0.7.2.tgz", + "integrity": "sha512-1T0sJcpHgX/u4I1OzIEhlcrvkUN8ln39nz7fMoE/2HDHrPiMFoOGR7++GYyfUmIQHkkrTinaeQsO3XWubjSvGg==", + "dependencies": { + "@floating-ui/dom": "^0.5.3", + "use-isomorphic-layout-effect": "^1.1.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz", + "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/gitignore-to-minimatch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", + "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", + "dev": true, + "license": "Apache-2.0", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.15", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", + "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@motionone/animation": { + "version": "10.14.0", + "resolved": "https://registry.npmjs.org/@motionone/animation/-/animation-10.14.0.tgz", + "integrity": "sha512-h+1sdyBP8vbxEBW5gPFDnj+m2DCqdlAuf2g6Iafb1lcMnqjsRXWlPw1AXgvUMXmreyhqmPbJqoNfIKdytampRQ==", + "license": "MIT", + "dependencies": { + "@motionone/easing": "^10.14.0", + "@motionone/types": "^10.14.0", + "@motionone/utils": "^10.14.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/dom": { + "version": "10.13.1", + "resolved": "https://registry.npmjs.org/@motionone/dom/-/dom-10.13.1.tgz", + "integrity": "sha512-zjfX+AGMIt/fIqd/SL1Lj93S6AiJsEA3oc5M9VkUr+Gz+juRmYN1vfvZd6MvEkSqEjwPQgcjN7rGZHrDB9APfQ==", + "license": "MIT", + "dependencies": { + "@motionone/animation": "^10.13.1", + "@motionone/generators": "^10.13.1", + "@motionone/types": "^10.13.0", + "@motionone/utils": "^10.13.1", + "hey-listen": "^1.0.8", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/easing": { + "version": "10.14.0", + "resolved": "https://registry.npmjs.org/@motionone/easing/-/easing-10.14.0.tgz", + "integrity": "sha512-2vUBdH9uWTlRbuErhcsMmt1jvMTTqvGmn9fHq8FleFDXBlHFs5jZzHJT9iw+4kR1h6a4SZQuCf72b9ji92qNYA==", + "license": "MIT", + "dependencies": { + "@motionone/utils": "^10.14.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/generators": { + "version": "10.14.0", + "resolved": "https://registry.npmjs.org/@motionone/generators/-/generators-10.14.0.tgz", + "integrity": "sha512-6kRHezoFfIjFN7pPpaxmkdZXD36tQNcyJe3nwVqwJ+ZfC0e3rFmszR8kp9DEVFs9QL/akWjuGPSLBI1tvz+Vjg==", + "license": "MIT", + "dependencies": { + "@motionone/types": "^10.14.0", + "@motionone/utils": "^10.14.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/types": { + "version": "10.14.0", + "resolved": "https://registry.npmjs.org/@motionone/types/-/types-10.14.0.tgz", + "integrity": "sha512-3bNWyYBHtVd27KncnJLhksMFQ5o2MSdk1cA/IZqsHtA9DnRM1SYgN01CTcJ8Iw8pCXF5Ocp34tyAjY7WRpOJJQ==", + "license": "MIT" + }, + "node_modules/@motionone/utils": { + "version": "10.14.0", + "resolved": "https://registry.npmjs.org/@motionone/utils/-/utils-10.14.0.tgz", + "integrity": "sha512-sLWBLPzRqkxmOTRzSaD3LFQXCPHvDzyHJ1a3VP9PRzBxyVd2pv51/gMOsdAcxQ9n+MIeGJnxzXBYplUHKj4jkw==", + "license": "MIT", + "dependencies": { + "@motionone/types": "^10.14.0", + "hey-listen": "^1.0.8", + "tslib": "^2.3.1" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.6", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz", + "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@radix-ui/number": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.0.tgz", + "integrity": "sha512-Ofwh/1HX69ZfJRiRBMTy7rgjAzHmwe4kW9C9Y99HTRUcYLUuVT0KESFj15rPjRgKJs20GPq8Bm5aEDJ8DuA3vA==", + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@radix-ui/primitive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.0.tgz", + "integrity": "sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA==", + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.0.1.tgz", + "integrity": "sha512-1yientwXqXcErDHEv8av9ZVNEBldH8L9scVR3is20lL+jOCfcJyMFZFEY5cgIrgexsq1qggSXqiEL/d/4f+QXA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.1" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.0.1.tgz", + "integrity": "sha512-uuiFbs+YCKjn3X1DTSx9G7BHApu4GHbi3kgiwsnFUbOKCrwejAJv4eE4Vc8C0Oaxt9T0aV4ox0WCOdx+39Xo+g==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-slot": "1.0.1" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.0.tgz", + "integrity": "sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.0.tgz", + "integrity": "sha512-1pVM9RfOQ+n/N5PJK33kRSKsr1glNxomxONs5c49MliinBY6Yw2Q995qfBUUo0/Mbg05B/sGA0gkgPI7kmSHBg==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-context-menu": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context-menu/-/react-context-menu-2.0.1.tgz", + "integrity": "sha512-7DuhU4xDcUk3AMJUlb5tHHOvJZ1GF4+snDIpjtWGlTvO0VktNKgbvBuGLlirdkYoUSI0mJXwOUcUXQapgIyefw==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-menu": "2.0.1", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-use-callback-ref": "1.0.0", + "@radix-ui/react-use-controllable-state": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.0.tgz", + "integrity": "sha512-2HV05lGUgYcA6xgLQ4BKPDmtL+QbIZYH5fCOTAOOcJ5O0QbWS3i9lKaurLzliYUDhORI2Qr3pyjhJh44lKA3rQ==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.2.tgz", + "integrity": "sha512-WjJzMrTWROozDqLB0uRWYvj4UuXsM/2L19EmQ3Au+IJWqwvwq9Bwd+P8ivo0Deg9JDPArR1I6MbWNi1CmXsskg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-use-callback-ref": "1.0.0", + "@radix-ui/react-use-escape-keydown": "1.0.2" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.0.tgz", + "integrity": "sha512-UagjDk4ijOAnGu4WMUPj9ahi7/zJJqNZ9ZAiGPp7waUWJO0O1aWXi/udPphI0IUjvrhBsZJGSN66dR2dsueLWQ==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.1.tgz", + "integrity": "sha512-Ej2MQTit8IWJiS2uuujGUmxXjF/y5xZptIIQnyd2JHLwtV0R2j9NRVoRj/1j/gJ7e3REdaBw4Hjf4a1ImhkZcQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-use-callback-ref": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.0.tgz", + "integrity": "sha512-Q6iAB/U7Tq3NTolBBQbHTgclPmGWE3OlktGGqrClPozSw4vkQ1DfQAOtzgRPecKsMdJINE05iaoDUG8tRzCBjw==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-layout-effect": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-menu": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.0.1.tgz", + "integrity": "sha512-I5FFZQxCl2fHoJ7R0m5/oWA9EX8/ttH4AbgneoCH7DAXQioFeb0XMAYnOVSp1GgJZ1Nx/mohxNQSeTMcaF1YPw==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-collection": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-direction": "1.0.0", + "@radix-ui/react-dismissable-layer": "1.0.2", + "@radix-ui/react-focus-guards": "1.0.0", + "@radix-ui/react-focus-scope": "1.0.1", + "@radix-ui/react-id": "1.0.0", + "@radix-ui/react-popper": "1.0.1", + "@radix-ui/react-portal": "1.0.1", + "@radix-ui/react-presence": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-roving-focus": "1.0.1", + "@radix-ui/react-slot": "1.0.1", + "@radix-ui/react-use-callback-ref": "1.0.0", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.5" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-popper": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.0.1.tgz", + "integrity": "sha512-J4Vj7k3k+EHNWgcKrE+BLlQfpewxA7Zd76h5I0bIa+/EqaIZ3DuwrbPj49O3wqN+STnXsBuxiHLiF0iU3yfovw==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@floating-ui/react-dom": "0.7.2", + "@radix-ui/react-arrow": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.0", + "@radix-ui/react-use-rect": "1.0.0", + "@radix-ui/react-use-size": "1.0.0", + "@radix-ui/rect": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.1.tgz", + "integrity": "sha512-NY2vUWI5WENgAT1nfC6JS7RU5xRYBfjZVLq0HmgEN1Ezy3rk/UruMV4+Rd0F40PEaFC5SrLS1ixYvcYIQrb4Ig==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.1" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.0.tgz", + "integrity": "sha512-A+6XEvN01NfVWiKu38ybawfHsBjWum42MRPnEuqPsBZ4eV7e/7K321B5VgYMPv3Xx5An6o1/l9ZuDBgmcmWK3w==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-use-layout-effect": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.1.tgz", + "integrity": "sha512-fHbmislWVkZaIdeF6GZxF0A/NH/3BjrGIYj+Ae6eTmTCr7EB0RQAAVEiqsXK6p3/JcRqVSBQoceZroj30Jj3XA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.1" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.1.tgz", + "integrity": "sha512-TB76u5TIxKpqMpUAuYH2VqMhHYKa+4Vs1NHygo/llLvlffN6mLVsFhz0AnSFlSBAvTBYVHYAkHAyEt7x1gPJOA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-collection": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-direction": "1.0.0", + "@radix-ui/react-id": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-use-callback-ref": "1.0.0", + "@radix-ui/react-use-controllable-state": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-slider": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.1.0.tgz", + "integrity": "sha512-5H/QB4xD3GF9UfoSCVLBx2JjlXamMcmTyL6gr4kkd/MiAGaYB0W7Exi4MQa0tJApBFJe+KmS5InKCI56p2kmjA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/number": "1.0.0", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-collection": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-direction": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-use-controllable-state": "1.0.0", + "@radix-ui/react-use-layout-effect": "1.0.0", + "@radix-ui/react-use-previous": "1.0.0", + "@radix-ui/react-use-size": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.1.tgz", + "integrity": "sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-tooltip": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.0.2.tgz", + "integrity": "sha512-11gUlok2rv5mu+KBtxniOKKNKjqC/uTbgFHWoQdbF46vMV+zjDaBvCtVDK9+MTddlpmlisGPGvvojX7Qm0yr+g==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-dismissable-layer": "1.0.2", + "@radix-ui/react-id": "1.0.0", + "@radix-ui/react-popper": "1.0.1", + "@radix-ui/react-portal": "1.0.1", + "@radix-ui/react-presence": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-slot": "1.0.1", + "@radix-ui/react-use-controllable-state": "1.0.0", + "@radix-ui/react-visually-hidden": "1.0.1" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.0.tgz", + "integrity": "sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.0.tgz", + "integrity": "sha512-FohDoZvk3mEXh9AWAVyRTYR4Sq7/gavuofglmiXB2g1aKyboUD4YtgWxKj8O5n+Uak52gXQ4wKz5IFST4vtJHg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.2.tgz", + "integrity": "sha512-DXGim3x74WgUv+iMNCF+cAo8xUHHeqvjx8zs7trKf+FkQKPQXLk2sX7Gx1ysH7Q76xCpZuxIJE7HLPxRE+Q+GA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.0.tgz", + "integrity": "sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-use-previous": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.0.0.tgz", + "integrity": "sha512-RG2K8z/K7InnOKpq6YLDmT49HGjNmrK+fr82UCVKT2sW0GYfVnYp4wZWBooT/EYfQ5faA9uIjvsuMMhH61rheg==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-use-rect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.0.0.tgz", + "integrity": "sha512-TB7pID8NRMEHxb/qQJpvSt3hQU4sqNPM1VCTjTRjEOa7cEop/QMuq8S6fb/5Tsz64kqSvB9WnwsDHtjnrM9qew==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/rect": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.0.0.tgz", + "integrity": "sha512-imZ3aYcoYCKhhgNpkNDh/aTiU05qw9hX+HHI1QDBTyIlcFjgeFlKKySNGMwTp7nYFLQg/j0VA2FmCY4WPDDHMg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-layout-effect": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.0.1.tgz", + "integrity": "sha512-K1hJcCMfWfiYUibRqf3V8r5Drpyf7rh44jnrwAbdvI5iCCijilBBeyQv9SKidYNZIopMdCyR9FnIjkHxHN0FcQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.1" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/rect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.0.0.tgz", + "integrity": "sha512-d0O68AYy/9oeEy1DdC07bz1/ZXX+DqCskRd3i4JzLSTXwefzaepQrKjXC7aNM8lTHjFLDO0pDgaEiQ7jEk+HVg==", + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@reduxjs/toolkit": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.8.5.tgz", + "integrity": "sha512-f4D5EXO7A7Xq35T0zRbWq5kJQyXzzscnHKmjnu2+37B3rwHU6mX9PYlbfXdnxcY6P/7zfmjhgan0Z+yuOfeBmA==", + "license": "MIT", + "dependencies": { + "immer": "^9.0.7", + "redux": "^4.1.2", + "redux-thunk": "^2.4.1", + "reselect": "^4.1.5" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18", + "react-redux": "^7.2.1 || ^8.0.2" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==", + "license": "MIT" + }, + "node_modules/@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", + "license": "MIT" + }, + "node_modules/@types/cors": { + "version": "2.8.12", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", + "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==", + "license": "MIT" + }, + "node_modules/@types/dateformat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/dateformat/-/dateformat-5.0.0.tgz", + "integrity": "sha512-SZg4JdHIWHQGEokbYGZSDvo5wA4TLYPXaqhigs/wH+REDOejcJzgH+qyY+HtEUtWOZxEUkbhbdYPqQDiEgrXeA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/eslint": { + "version": "8.4.6", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.6.tgz", + "integrity": "sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", + "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", + "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", + "license": "MIT", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/lodash": { + "version": "4.14.185", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.185.tgz", + "integrity": "sha512-evMDG1bC4rgQg4ku9tKpuMh5iBNEwNa3tf9zRHdP1qlv+1WUg44xat4IxCE14gIpZRGUUWAx2VhItCZc25NfMA==", + "license": "MIT" + }, + "node_modules/@types/lodash.mergewith": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/@types/lodash.mergewith/-/lodash.mergewith-4.6.6.tgz", + "integrity": "sha512-RY/8IaVENjG19rxTZu9Nukqh0W2UrYgmBj5sdns4hWRZaV8PqR7wIKHFKzvOTjo4zVRV7sVI+yFhAJql12Kfqg==", + "license": "MIT", + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/node": { + "version": "18.8.3", + "license": "MIT" + }, + "node_modules/@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "license": "MIT" + }, + "node_modules/@types/prop-types": { + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.0.20", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.20.tgz", + "integrity": "sha512-MWul1teSPxujEHVwZl4a5HxQ9vVNsjTchVA+xRqv/VYGCuKGAU6UhfrTdF5aBefwD1BHUD8i/zq+O/vyCm/FrA==", + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.0.6", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.6.tgz", + "integrity": "sha512-/5OFZgfIPSwy+YuIBP/FgJnQnsxhZhjjrnxudMddeblOouIodEQ75X14Rr4wGSG/bknL+Omy9iWlLo1u/9GzAA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-reconciler": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.28.0.tgz", + "integrity": "sha512-5cjk9ottZAj7eaTsqzPUIlrVbh3hBAO2YaEL1rkjHKB3xNAId7oU8GhzvAX+gfmlfoxTwJnBjPxEHyxkEA1Ffg==", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", + "license": "MIT" + }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==", + "license": "MIT" + }, + "node_modules/@types/uuid": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.37.0.tgz", + "integrity": "sha512-Fde6W0IafXktz1UlnhGkrrmnnGpAo1kyX7dnyHHVrmwJOn72Oqm3eYtddrpOwwel2W8PAK9F3pIL5S+lfoM0og==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "5.37.0", + "@typescript-eslint/type-utils": "5.37.0", + "@typescript-eslint/utils": "5.37.0", + "debug": "^4.3.4", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.2.0", + "regexpp": "^3.2.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.37.0.tgz", + "integrity": "sha512-01VzI/ipYKuaG5PkE5+qyJ6m02fVALmMPY3Qq5BHflDx3y4VobbLdHQkSMg9VPRS4KdNt4oYTMaomFoHonBGAw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "5.37.0", + "@typescript-eslint/types": "5.37.0", + "@typescript-eslint/typescript-estree": "5.37.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.37.0.tgz", + "integrity": "sha512-F67MqrmSXGd/eZnujjtkPgBQzgespu/iCZ+54Ok9X5tALb9L2v3G+QBSoWkXG0p3lcTJsL+iXz5eLUEdSiJU9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "5.37.0", + "@typescript-eslint/visitor-keys": "5.37.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.37.0.tgz", + "integrity": "sha512-BSx/O0Z0SXOF5tY0bNTBcDEKz2Ec20GVYvq/H/XNKiUorUFilH7NPbFUuiiyzWaSdN3PA8JV0OvYx0gH/5aFAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "5.37.0", + "@typescript-eslint/utils": "5.37.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.37.0.tgz", + "integrity": "sha512-3frIJiTa5+tCb2iqR/bf7XwU20lnU05r/sgPJnRpwvfZaqCJBrl8Q/mw9vr3NrNdB/XtVyMA0eppRMMBqdJ1bA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.37.0.tgz", + "integrity": "sha512-JkFoFIt/cx59iqEDSgIGnQpCTRv96MQnXCYvJi7QhBC24uyuzbD8wVbajMB1b9x4I0octYFJ3OwjAwNqk1AjDA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "5.37.0", + "@typescript-eslint/visitor-keys": "5.37.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.37.0.tgz", + "integrity": "sha512-jUEJoQrWbZhmikbcWSMDuUSxEE7ID2W/QCV/uz10WtQqfOuKZUqFGjqLJ+qhDd17rjgp+QJPqTdPIBWwoob2NQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.37.0", + "@typescript-eslint/types": "5.37.0", + "@typescript-eslint/typescript-estree": "5.37.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.37.0.tgz", + "integrity": "sha512-Hp7rT4cENBPIzMwrlehLW/28EVCOcE9U1Z1BQTc8EA8v5qpr7GRGuG+U58V5tTY48zvUOA3KHvw3rA8tY9fbdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "5.37.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-2.1.0.tgz", + "integrity": "sha512-am6rPyyU3LzUYne3Gd9oj9c4Rzbq5hQnuGXSMT6Gujq45Il/+bunwq3lrB7wghLkiF45ygMwft37vgJ/NE8IAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.18.13", + "@babel/plugin-transform-react-jsx": "^7.18.10", + "@babel/plugin-transform-react-jsx-development": "^7.18.6", + "@babel/plugin-transform-react-jsx-self": "^7.18.6", + "@babel/plugin-transform-react-jsx-source": "^7.18.6", + "magic-string": "^0.26.2", + "react-refresh": "^0.14.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^3.0.0" + } + }, + "node_modules/@zag-js/element-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@zag-js/element-size/-/element-size-0.1.0.tgz", + "integrity": "sha512-QF8wp0+V8++z+FHXiIw93+zudtubYszOtYbNgK39fg3pi+nCZtuSm4L1jC5QZMatNZ83MfOzyNCfgUubapagJQ==", + "license": "MIT" + }, + "node_modules/@zag-js/focus-visible": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@zag-js/focus-visible/-/focus-visible-0.1.0.tgz", + "integrity": "sha512-PeaBcTmdZWcFf7n1aM+oiOdZc+sy14qi0emPIeUuGMTjbP0xLGrZu43kdpHnWSXy7/r4Ubp/vlg50MCV8+9Isg==", + "license": "MIT" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/add": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/add/-/add-2.0.6.tgz", + "integrity": "sha512-j5QzrmsokwWWp6kUcJQySpbG+xfOBqqKnup3OIk1pz+kB/80SLorZ9V8zHFLO92Lcd+hbvq8bT+zOGoPkmBV0Q==" + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/aria-hidden": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.1.tgz", + "integrity": "sha512-PN344VAf9j1EAi+jyVHOJ8XidQdPVssGco39eNcsGdM4wcsILtxrKLkbuiMfLWYROK1FjRQasMWCBttrhjnr6A==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0", + "react": "^16.9.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/attr-accept": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz", + "integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "license": "MIT", + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001402", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001402.tgz", + "integrity": "sha512-Mx4MlhXO5NwuvXGgVb+hg65HZ+bhUYsz8QtDGDo2QmaJS2GBX47Xfi2koL86lc8K+l+htXeTEB/Aeqvezoo6Ew==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, + "node_modules/compute-scroll-into-view": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.14.tgz", + "integrity": "sha512-mKDjINe3tc6hGelUMNDzuhorIUZ7kS7BwyY0r2wQd2HOH2tRuJykiC06iSEX8y1TuhNzvz4GcJnK16mM2J1NMQ==", + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/copy-to-clipboard": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz", + "integrity": "sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==", + "license": "MIT", + "dependencies": { + "toggle-selection": "^1.0.6" + } + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cosmiconfig": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", + "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-box-model": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz", + "integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==", + "license": "MIT", + "dependencies": { + "tiny-invariant": "^1.0.6" + } + }, + "node_modules/csstype": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", + "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==", + "license": "MIT" + }, + "node_modules/dateformat": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-5.0.3.tgz", + "integrity": "sha512-Kvr6HmPXUMerlLcLF+Pwq3K7apHpYmGDVqrxcDasBg86UcKeTSNWbEzU8bwdXnxnR44FtMhJAxI4Bov6Y/KUfA==", + "license": "MIT", + "engines": { + "node": ">=12.20" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", + "license": "MIT" + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.4.253", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.253.tgz", + "integrity": "sha512-1pezJ2E1UyBTGbA7fUlHdPSXQw1k+82VhTFLG5G0AUqLGvsZqFzleOblceqegZzxYX4kC7hGEEdzIQI9RZ1Cuw==", + "license": "ISC" + }, + "node_modules/engine.io": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.0.tgz", + "integrity": "sha512-4KzwW3F3bk+KlzSOY57fj/Jx6LyRQ1nbcyIadehl+AnXjKT7gDO0ORdRi/84ixvMKTym6ZKuxvbzN62HDDU1Lg==", + "license": "MIT", + "dependencies": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.0.3", + "ws": "~8.2.3" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io-client": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.2.2.tgz", + "integrity": "sha512-8ZQmx0LQGRTYkHuogVZuGSpDqYZtCM/nv8zQ68VZ+JkOpazJ7ICdsSpaO6iXwvaU30oFg5QJOJWj8zWqhbKjkQ==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.0.3", + "ws": "~8.2.3", + "xmlhttprequest-ssl": "~2.0.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz", + "integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/esbuild": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.7.tgz", + "integrity": "sha512-7V8tzllIbAQV1M4QoE52ImKu8hT/NLGlGXkiDsbEU5PS6K8Mn09ZnYoS+dcmHxOS9CRsV4IRAMdT3I67IyUNXw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/linux-loong64": "0.15.7", + "esbuild-android-64": "0.15.7", + "esbuild-android-arm64": "0.15.7", + "esbuild-darwin-64": "0.15.7", + "esbuild-darwin-arm64": "0.15.7", + "esbuild-freebsd-64": "0.15.7", + "esbuild-freebsd-arm64": "0.15.7", + "esbuild-linux-32": "0.15.7", + "esbuild-linux-64": "0.15.7", + "esbuild-linux-arm": "0.15.7", + "esbuild-linux-arm64": "0.15.7", + "esbuild-linux-mips64le": "0.15.7", + "esbuild-linux-ppc64le": "0.15.7", + "esbuild-linux-riscv64": "0.15.7", + "esbuild-linux-s390x": "0.15.7", + "esbuild-netbsd-64": "0.15.7", + "esbuild-openbsd-64": "0.15.7", + "esbuild-sunos-64": "0.15.7", + "esbuild-windows-32": "0.15.7", + "esbuild-windows-64": "0.15.7", + "esbuild-windows-arm64": "0.15.7" + } + }, + "node_modules/esbuild-darwin-arm64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.7.tgz", + "integrity": "sha512-kBIHvtVqbSGajN88lYMnR3aIleH3ABZLLFLxwL2stiuIGAjGlQW741NxVTpUHQXUmPzxi6POqc9npkXa8AcSZQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.23.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.1.tgz", + "integrity": "sha512-w7C1IXCc6fNqjpuYd0yPlcTKKmHlHHktRkzmBPZ+7cvNBQuiNjx0xaMTjAJGCafJhQkrFJooREv0CtrVzmHwqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint/eslintrc": "^1.3.2", + "@humanwhocodes/config-array": "^0.10.4", + "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@humanwhocodes/module-importer": "^1.0.1", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.1", + "globals": "^13.15.0", + "globby": "^11.1.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", + "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prettier-linter-helpers": "^1.0.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "eslint": ">=7.28.0", + "prettier": ">=2.0.0" + }, + "peerDependenciesMeta": { + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/espree": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/event-stream": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", + "integrity": "sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexer": "~0.1.1", + "from": "~0", + "map-stream": "~0.1.0", + "pause-stream": "0.0.11", + "split": "0.3", + "stream-combiner": "~0.0.4", + "through": "~2.3.1" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/file-selector": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.6.0.tgz", + "integrity": "sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==", + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "license": "MIT" + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/focus-lock": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-0.11.2.tgz", + "integrity": "sha512-pZ2bO++NWLHhiKkgP1bEXHhR1/OjVcSvlCJ98aNJDFeb7H5OOQaO+SKOZle6041O9rv2tmbrO4JzClAvDUHf0g==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/framer-motion": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-7.3.5.tgz", + "integrity": "sha512-JrLLVCi59LMI3+ZvSSbxf/Z7SOIdYRZrgdkUvJkzyT2RXu34HtGy26n41jNrcD5K85boqlZhGTbfqnAIfMHRLQ==", + "license": "MIT", + "dependencies": { + "@motionone/dom": "10.13.1", + "framesync": "6.1.2", + "hey-listen": "^1.0.8", + "popmotion": "11.0.5", + "style-value-types": "5.1.2", + "tslib": "2.4.0" + }, + "optionalDependencies": { + "@emotion/is-prop-valid": "^0.8.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/framer-motion/node_modules/@emotion/is-prop-valid": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", + "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emotion/memoize": "0.7.4" + } + }, + "node_modules/framer-motion/node_modules/@emotion/memoize": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", + "license": "MIT", + "optional": true + }, + "node_modules/framer-motion/node_modules/framesync": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/framesync/-/framesync-6.1.2.tgz", + "integrity": "sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g==", + "license": "MIT", + "dependencies": { + "tslib": "2.4.0" + } + }, + "node_modules/framesync": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/framesync/-/framesync-5.3.0.tgz", + "integrity": "sha512-oc5m68HDO/tuK2blj7ZcdEBRx3p1PjrgHazL8GYEpvULhrtGIFbQArN6cQS2QhW8mitffaB+VYzMjDqBxxQeoA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==", + "dev": true, + "license": "MIT" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "license": "MIT" + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true, + "license": "MIT" + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/hey-listen": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz", + "integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==", + "license": "MIT" + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hotkeys-js": { + "version": "3.9.4", + "resolved": "https://registry.npmjs.org/hotkeys-js/-/hotkeys-js-3.9.4.tgz", + "integrity": "sha512-2zuLt85Ta+gIyvs4N88pCYskNrxf1TFv3LR9t5mdAZIX8BcgQQ48F2opUptvHa6m8zsy5v/a0i9mWzTrlNWU0Q==", + "license": "MIT" + }, + "node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immer": { + "version": "9.0.15", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.15.tgz", + "integrity": "sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/immutable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", + "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "license": "MIT", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/its-fine": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/its-fine/-/its-fine-1.0.6.tgz", + "integrity": "sha512-VZJZPwVT2kxe5KQv+TxCjojfLiUIut8zXDNLTxcM7gJ/xQ/bSPk5M0neZ+j3myy45KKkltY1mm1jyJgx3Fxsdg==", + "dependencies": { + "@types/react-reconciler": "^0.28.0" + }, + "peerDependencies": { + "react": ">=18.0" + } + }, + "node_modules/js-sdsl": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz", + "integrity": "sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/konva": { + "version": "8.3.13", + "resolved": "https://registry.npmjs.org/konva/-/konva-8.3.13.tgz", + "integrity": "sha512-O5VxHfRfTj4PscTglQH1NimS8+CC5hQYLeB8YQstu8MN/i2L8GjA1T9d7xxzITF2TD5+xcIs5ei7en3cztbNXg==", + "funding": [ + { + "type": "patreon", + "url": "https://www.patreon.com/lavrton" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/konva" + }, + { + "type": "github", + "url": "https://github.com/sponsors/lavrton" + } + ] + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/magic-string": { + "version": "0.26.3", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.3.tgz", + "integrity": "sha512-u1Po0NDyFcwdg2nzHT88wSK0+Rih0N1M+Ph1Sp08k8yvFFU3KR72wryS7e1qMPJypt99WB7fIFVCA92mQrMjrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sourcemap-codec": "^1.4.8" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/map-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", + "integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "dev": true, + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-cleanup": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/node-cleanup/-/node-cleanup-2.1.2.tgz", + "integrity": "sha512-qN8v/s2PAJwGUtr1/hYTpNKlD6Y9rc4p8KSmJXyGdYGZsDGKXrGThikLFP9OCHFeLeEpQzPwiAtdIvBLqm//Hw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pause-stream": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", + "dev": true, + "license": [ + "MIT", + "Apache2" + ], + "dependencies": { + "through": "~2.3" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/popmotion": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/popmotion/-/popmotion-11.0.5.tgz", + "integrity": "sha512-la8gPM1WYeFznb/JqF4GiTkRRPZsfaj2+kCxqQgr2MJylMmIKUwBfWW8Wa5fml/8gmtlD5yI01MP1QCZPWmppA==", + "license": "MIT", + "dependencies": { + "framesync": "6.1.2", + "hey-listen": "^1.0.8", + "style-value-types": "5.1.2", + "tslib": "2.4.0" + } + }, + "node_modules/popmotion/node_modules/framesync": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/framesync/-/framesync-6.1.2.tgz", + "integrity": "sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g==", + "license": "MIT", + "dependencies": { + "tslib": "2.4.0" + } + }, + "node_modules/postcss": { + "version": "8.4.16", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz", + "integrity": "sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.7.1", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/ps-tree": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz", + "integrity": "sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "event-stream": "=3.3.4" + }, + "bin": { + "ps-tree": "bin/ps-tree.js" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/re-resizable": { + "version": "6.9.9", + "resolved": "https://registry.npmjs.org/re-resizable/-/re-resizable-6.9.9.tgz", + "integrity": "sha512-l+MBlKZffv/SicxDySKEEh42hR6m5bAHfNu3Tvxks2c4Ah+ldnWjfnVRwxo/nxF27SsUsxDS0raAzFuJNKABXA==", + "license": "MIT", + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-clientside-effect": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/react-clientside-effect/-/react-clientside-effect-1.2.6.tgz", + "integrity": "sha512-XGGGRQAKY+q25Lz9a/4EPqom7WRjz3z9R2k4jhVKA/puQFH/5Nt27vFZYql4m4NVNdUvX8PS3O7r/Zzm7cjUlg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.13" + }, + "peerDependencies": { + "react": "^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-colorful": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/react-colorful/-/react-colorful-5.6.1.tgz", + "integrity": "sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==", + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/react-dropzone": { + "version": "14.2.2", + "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.2.2.tgz", + "integrity": "sha512-5oyGN/B5rNhop2ggUnxztXBQ6q6zii+OMEftPzsxAR2hhpVWz0nAV+3Ktxo2h5bZzdcCKrpd8bfWAVsveIBM+w==", + "license": "MIT", + "dependencies": { + "attr-accept": "^2.2.2", + "file-selector": "^0.6.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">= 10.13" + }, + "peerDependencies": { + "react": ">= 16.8 || 18.0.0" + } + }, + "node_modules/react-fast-compare": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", + "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==", + "license": "MIT" + }, + "node_modules/react-focus-lock": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.9.1.tgz", + "integrity": "sha512-pSWOQrUmiKLkffPO6BpMXN7SNKXMsuOakl652IBuALAu1esk+IcpJyM+ALcYzPTTFz1rD0R54aB9A4HuP5t1Wg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.0.0", + "focus-lock": "^0.11.2", + "prop-types": "^15.6.2", + "react-clientside-effect": "^1.2.6", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-hotkeys-hook": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/react-hotkeys-hook/-/react-hotkeys-hook-3.4.7.tgz", + "integrity": "sha512-+bbPmhPAl6ns9VkXkNNyxlmCAIyDAcWbB76O4I0ntr3uWCRuIQf/aRLartUahe9chVMPj+OEzzfk3CQSjclUEQ==", + "license": "MIT", + "dependencies": { + "hotkeys-js": "3.9.4" + }, + "peerDependencies": { + "react": ">=16.8.1", + "react-dom": ">=16.8.1" + } + }, + "node_modules/react-icons": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.4.0.tgz", + "integrity": "sha512-fSbvHeVYo/B5/L4VhB7sBA1i2tS8MkT0Hb9t2H1AVPkwGfVHLJCqyr2Py9dKMxsyM63Eng1GkdZfbWj+Fmv8Rg==", + "license": "MIT", + "peerDependencies": { + "react": "*" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/react-konva": { + "version": "18.2.3", + "resolved": "https://registry.npmjs.org/react-konva/-/react-konva-18.2.3.tgz", + "integrity": "sha512-OPxjBTgaEGU9pt/VJSVM7QNXYHEZ5CkulX+4fTTvbaH+Wh+vMLbXmH3yjWw4kT/5Qi6t0UQKHPPmirCv8/9sdg==", + "funding": [ + { + "type": "patreon", + "url": "https://www.patreon.com/lavrton" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/konva" + }, + { + "type": "github", + "url": "https://github.com/sponsors/lavrton" + } + ], + "dependencies": { + "its-fine": "^1.0.6", + "react-reconciler": "~0.29.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "konva": "^8.0.1 || ^7.2.5", + "react": ">=18.0.0", + "react-dom": ">=18.0.0" + } + }, + "node_modules/react-reconciler": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.29.0.tgz", + "integrity": "sha512-wa0fGj7Zht1EYMRhKWwoo1H9GApxYLBuhoAuXN0TlltESAjDssB+Apf0T/DngVqaMyPypDmabL37vw/2aRM98Q==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/react-redux": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.2.tgz", + "integrity": "sha512-nBwiscMw3NoP59NFCXFf02f8xdo+vSHT/uZ1ldDwF7XaTpzm+Phk97VT4urYBl5TYAPNVaFm12UHAEyzkpNzRA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.1", + "@types/hoist-non-react-statics": "^3.3.1", + "@types/use-sync-external-store": "^0.0.3", + "hoist-non-react-statics": "^3.3.2", + "react-is": "^18.0.0", + "use-sync-external-store": "^1.0.0" + }, + "peerDependencies": { + "@types/react": "^16.8 || ^17.0 || ^18.0", + "@types/react-dom": "^16.8 || ^17.0 || ^18.0", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0", + "react-native": ">=0.59", + "redux": "^4" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, + "node_modules/react-redux/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "license": "MIT" + }, + "node_modules/react-refresh": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", + "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-remove-scroll": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz", + "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==", + "license": "MIT", + "dependencies": { + "react-remove-scroll-bar": "^2.3.3", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.3.tgz", + "integrity": "sha512-i9GMNWwpz8XpUpQ6QlevUtFjHGqnPG4Hxs+wlIJntu/xcsZVEpJcIV71K3ZkqNy2q3GfgvkD7y6t/Sv8ofYSbw==", + "license": "MIT", + "dependencies": { + "react-style-singleton": "^2.2.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", + "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", + "license": "MIT", + "dependencies": { + "get-nonce": "^1.0.0", + "invariant": "^2.2.4", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/redux": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.0.tgz", + "integrity": "sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, + "node_modules/redux-persist": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-6.0.0.tgz", + "integrity": "sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ==", + "license": "MIT", + "peerDependencies": { + "redux": ">4.0.0" + } + }, + "node_modules/redux-thunk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.1.tgz", + "integrity": "sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q==", + "license": "MIT", + "peerDependencies": { + "redux": "^4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", + "license": "MIT" + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/reselect": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.6.tgz", + "integrity": "sha512-ZovIuXqto7elwnxyXbBtCPo9YFEr3uJqj2rRbcOOog1bmu2Ag85M4hixSwFWyaBMKXNgvPaJ9OSu9SkBPIeJHQ==", + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "2.78.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.78.1.tgz", + "integrity": "sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg==", + "dev": true, + "license": "MIT", + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/sass": { + "version": "1.55.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.55.0.tgz", + "integrity": "sha512-Pk+PMy7OGLs9WaxZGJMn7S96dvlyVBwwtToX895WmCpAOr5YiJYEUJfiJidMuKb613z2xNWcXCHEuOvjZbqC6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/socket.io": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.2.tgz", + "integrity": "sha512-6fCnk4ARMPZN448+SQcnn1u8OHUC72puJcNtSgg2xS34Cu7br1gQ09YKkO1PFfDn/wyUE9ZgMAwosJed003+NQ==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "debug": "~4.3.2", + "engine.io": "~6.2.0", + "socket.io-adapter": "~2.4.0", + "socket.io-parser": "~4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz", + "integrity": "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg==", + "license": "MIT" + }, + "node_modules/socket.io-client": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.5.2.tgz", + "integrity": "sha512-naqYfFu7CLDiQ1B7AlLhRXKX3gdeaIMfgigwavDzgJoIUYulc1qHH5+2XflTsXTPY7BlPH5rppJyUjhjrKQKLg==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.2.1", + "socket.io-parser": "~4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz", + "integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "dev": true, + "license": "MIT" + }, + "node_modules/split": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", + "integrity": "sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/stream-combiner": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", + "integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexer": "~0.1.1" + } + }, + "node_modules/string-argv": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.1.2.tgz", + "integrity": "sha512-mBqPGEOMNJKXRo7z0keX0wlAhbBAjilUdPW13nN0PecVryZxdHIeM7TqbsSUA7VYuS00HGC6mojP7DlQzfa9ZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-value-types": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/style-value-types/-/style-value-types-5.1.2.tgz", + "integrity": "sha512-Vs9fNreYF9j6W2VvuDTP7kepALi7sk0xtk2Tu8Yxi9UoajJdEVpNpCov0HsLTqXvNGKX+Uv09pkozVITi1jf3Q==", + "license": "MIT", + "dependencies": { + "hey-listen": "^1.0.8", + "tslib": "2.4.0" + } + }, + "node_modules/stylis": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz", + "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==", + "license": "MIT" + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT" + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tiny-invariant": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.2.0.tgz", + "integrity": "sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg==", + "license": "MIT" + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==", + "license": "MIT" + }, + "node_modules/tsc-watch": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/tsc-watch/-/tsc-watch-5.0.3.tgz", + "integrity": "sha512-Hz2UawwELMSLOf0xHvAFc7anLeMw62cMVXr1flYmhRuOhOyOljwmb1l/O60ZwRyy1k7N1iC1mrn1QYM2zITfuw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "node-cleanup": "^2.1.2", + "ps-tree": "^1.2.0", + "string-argv": "^0.1.1", + "strip-ansi": "^6.0.0" + }, + "bin": { + "tsc-watch": "index.js" + }, + "engines": { + "node": ">=8.17.0" + }, + "peerDependencies": { + "typescript": "*" + } + }, + "node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "license": "0BSD" + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true, + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.3.tgz", + "integrity": "sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz", + "integrity": "sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/use-callback-ref": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.0.tgz", + "integrity": "sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-isomorphic-layout-effect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", + "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", + "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", + "license": "MIT", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vite": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-3.1.1.tgz", + "integrity": "sha512-hgxQWev/AL7nWYrqByYo8nfcH9n97v6oFsta9+JX8h6cEkni7nHKP2kJleNYV2kcGhE8jsbaY1aStwPZXzPbgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.15.6", + "postcss": "^8.4.16", + "resolve": "^1.22.1", + "rollup": "~2.78.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "less": "*", + "sass": "*", + "stylus": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-plugin-eslint": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/vite-plugin-eslint/-/vite-plugin-eslint-1.8.1.tgz", + "integrity": "sha512-PqdMf3Y2fLO9FsNPmMX+//2BF5SF8nEWspZdgl4kSt7UvHDRHVVfHvxsD7ULYzZrJDGRxR81Nq7TOFgwMnUang==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^4.2.1", + "@types/eslint": "^8.4.5", + "rollup": "^2.77.2" + }, + "peerDependencies": { + "eslint": ">=7", + "vite": ">=2" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", + "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yarn": { + "version": "1.22.19", + "resolved": "https://registry.npmjs.org/yarn/-/yarn-1.22.19.tgz", + "integrity": "sha512-/0V5q0WbslqnwP91tirOvldvYISzaqhClxzyUKXYxs07yUILIs5jx/k6CFe8bvKSkds5w+eiOqta39Wk3WxdcQ==", + "hasInstallScript": true, + "bin": { + "yarn": "bin/yarn.js", + "yarnpkg": "bin/yarn.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "requires": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "requires": { + "@babel/highlight": "^7.18.6" + } + }, + "@babel/compat-data": { + "version": "7.19.3" + }, + "@babel/core": { + "version": "7.19.3", + "requires": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.19.3", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-module-transforms": "^7.19.0", + "@babel/helpers": "^7.19.0", + "@babel/parser": "^7.19.3", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.3", + "@babel/types": "^7.19.3", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" + } + }, + "@babel/generator": { + "version": "7.19.3", + "requires": { + "@babel/types": "^7.19.3", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "dependencies": { + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + } + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", + "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.19.3", + "requires": { + "@babel/compat-data": "^7.19.3", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "semver": "^6.3.0" + } + }, + "@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==" + }, + "@babel/helper-function-name": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "requires": { + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-module-transforms": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz", + "integrity": "sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==", + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.18.6", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.0", + "@babel/types": "^7.19.0" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", + "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==" + }, + "@babel/helper-simple-access": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz", + "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-string-parser": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz", + "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==" + }, + "@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==" + }, + "@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==" + }, + "@babel/helpers": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.0.tgz", + "integrity": "sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==", + "requires": { + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.0", + "@babel/types": "^7.19.0" + } + }, + "@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "requires": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.19.3" + }, + "@babel/plugin-syntax-jsx": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", + "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-react-jsx": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz", + "integrity": "sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/plugin-syntax-jsx": "^7.18.6", + "@babel/types": "^7.19.0" + } + }, + "@babel/plugin-transform-react-jsx-development": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz", + "integrity": "sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==", + "dev": true, + "requires": { + "@babel/plugin-transform-react-jsx": "^7.18.6" + } + }, + "@babel/plugin-transform-react-jsx-self": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.18.6.tgz", + "integrity": "sha512-A0LQGx4+4Jv7u/tWzoJF7alZwnBDQd6cGLh9P+Ttk4dpiL+J5p7NSNv/9tlEFFJDq3kjxOavWmbm6t0Gk+A3Ig==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-react-jsx-source": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.18.6.tgz", + "integrity": "sha512-utZmlASneDfdaMh0m/WausbjUjEdGrQJz0vFK93d7wD3xf5wBtX219+q6IlCNZeguIcxS2f/CvLZrlLSvSHQXw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/runtime": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.0.tgz", + "integrity": "sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/template": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" + } + }, + "@babel/traverse": { + "version": "7.19.3", + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.19.3", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.19.3", + "@babel/types": "^7.19.3", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.19.3", + "requires": { + "@babel/helper-string-parser": "^7.18.10", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + }, + "@chakra-ui/accordion": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@chakra-ui/accordion/-/accordion-2.0.12.tgz", + "integrity": "sha512-O3qq8mILo1QODjCGr2xwxC5LNFakBoMzTjEgpvpIMynxWc/1RKfGuFLis3IDfpHIicXmBTK6sNiZXewmna88CQ==", + "requires": { + "@chakra-ui/descendant": "3.0.9", + "@chakra-ui/icon": "3.0.9", + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-use-controllable-state": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.3", + "@chakra-ui/transition": "2.0.9" + }, + "dependencies": { + "@chakra-ui/icon": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/icon/-/icon-3.0.9.tgz", + "integrity": "sha512-P2Pwm/za6m1W1oqL2kGHH6XrrymsBjqYAFwOW2lB5Q6mI1e+RYe/iMxDoPSLHMYhqdfH7vyib/ffE3Vv3a5oTA==", + "requires": { + "@chakra-ui/shared-utils": "2.0.1" + } + } + } + }, + "@chakra-ui/alert": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/alert/-/alert-2.0.9.tgz", + "integrity": "sha512-hFRIh6ZzQJ0sAESRym15mW/mcZE/yu4z6lFtdToBhpfSlhZLuE7gDdOTxqGkg417hY//48NiNXOCoQ2dUUuHKw==", + "requires": { + "@chakra-ui/icon": "3.0.9", + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/spinner": "2.0.9" + }, + "dependencies": { + "@chakra-ui/icon": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/icon/-/icon-3.0.9.tgz", + "integrity": "sha512-P2Pwm/za6m1W1oqL2kGHH6XrrymsBjqYAFwOW2lB5Q6mI1e+RYe/iMxDoPSLHMYhqdfH7vyib/ffE3Vv3a5oTA==", + "requires": { + "@chakra-ui/shared-utils": "2.0.1" + } + } + } + }, + "@chakra-ui/anatomy": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@chakra-ui/anatomy/-/anatomy-2.0.6.tgz", + "integrity": "sha512-Vgop2FFdhVtX7BydjZdJWZAWy+DdXBU1IMaBppz6COaH+/7OXxoI2ec2bs17ehJyBO0M+ud3OLj5UCFQ79YsoQ==" + }, + "@chakra-ui/avatar": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/avatar/-/avatar-2.1.0.tgz", + "integrity": "sha512-SRQeH6NNvIBgUc4OsO14ypvcn8I66ndw7r4piIkm+R2zqbYnrzpp1d2zNPNHkChc4xQY71/GenenYO5Fhsi2DA==", + "requires": { + "@chakra-ui/image": "2.0.10", + "@chakra-ui/react-children-utils": "2.0.1", + "@chakra-ui/react-context": "2.0.3" + } + }, + "@chakra-ui/breadcrumb": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/breadcrumb/-/breadcrumb-2.0.9.tgz", + "integrity": "sha512-cc3WbxrJNRUph4v45qCdcIKJI0xECeV9VikQNIactBB+iexN4d+5P66xZABAkD8wWGmyH5KuSZcd9sFYNmC13w==", + "requires": { + "@chakra-ui/react-children-utils": "2.0.1", + "@chakra-ui/react-context": "2.0.3" + } + }, + "@chakra-ui/breakpoint-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/breakpoint-utils/-/breakpoint-utils-2.0.3.tgz", + "integrity": "sha512-smi41ZtaiPw4mXaCgicyAh5M45Drt20wypThP+qQUT2CQ51UFZhYlItRA2lCXKQ9QB83POcHPC/oAwIsNOAfTg==" + }, + "@chakra-ui/button": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/button/-/button-2.0.9.tgz", + "integrity": "sha512-4BuDBiBlChHW1rQ9iod9MKs87AY3IyvZQwjV3DZTU4IG0KcDDfLQf++jj4dkg9Ttu+pIWhwF42pzA40JxW1oNg==", + "requires": { + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.3", + "@chakra-ui/spinner": "2.0.9" + } + }, + "@chakra-ui/checkbox": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@chakra-ui/checkbox/-/checkbox-2.1.8.tgz", + "integrity": "sha512-HhRs3nwTFoIE/UpX4N2AZxxW39Xm/Vw01HjwP/59X60kdKs3RBXlm52cODkfUDfveyT9o5ezLhU/jRf0qA909Q==", + "requires": { + "@chakra-ui/form-control": "2.0.9", + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-types": "2.0.3", + "@chakra-ui/react-use-callback-ref": "2.0.3", + "@chakra-ui/react-use-controllable-state": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.3", + "@chakra-ui/react-use-safe-layout-effect": "2.0.1", + "@chakra-ui/react-use-update-effect": "2.0.3", + "@chakra-ui/visually-hidden": "2.0.9", + "@zag-js/focus-visible": "0.1.0" + } + }, + "@chakra-ui/clickable": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/clickable/-/clickable-2.0.9.tgz", + "integrity": "sha512-tGXYM6M6I954fif98QkNu5M76oBZmksCTj2mILOan9/BSimpFpu06aPGX3ZIkNsz300nIObn0FdtMvKpIEQueA==", + "requires": { + "@chakra-ui/react-use-merge-refs": "2.0.3" + } + }, + "@chakra-ui/close-button": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/close-button/-/close-button-2.0.9.tgz", + "integrity": "sha512-0RI/zLR+/mycGbYCCwDAc9hAVG7IIVmdikmo1ET7+rYip4TN94aWR0hA4dYtWqqghG1oW/pYQ9Yja6fEY90V5w==", + "requires": { + "@chakra-ui/icon": "3.0.9" + }, + "dependencies": { + "@chakra-ui/icon": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/icon/-/icon-3.0.9.tgz", + "integrity": "sha512-P2Pwm/za6m1W1oqL2kGHH6XrrymsBjqYAFwOW2lB5Q6mI1e+RYe/iMxDoPSLHMYhqdfH7vyib/ffE3Vv3a5oTA==", + "requires": { + "@chakra-ui/shared-utils": "2.0.1" + } + } + } + }, + "@chakra-ui/color-mode": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@chakra-ui/color-mode/-/color-mode-2.1.7.tgz", + "integrity": "sha512-GAoKJzVRQeuEfCa2i0BZdMwxuOoaGknU3+5wgvLuaSpwlov4OyqpjKMRdSdpjr4IFiqqHK47dsr3H4LQsbO+9w==", + "requires": { + "@chakra-ui/react-use-safe-layout-effect": "2.0.1" + } + }, + "@chakra-ui/control-box": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/control-box/-/control-box-2.0.9.tgz", + "integrity": "sha512-/viS9OBah1wCLNZbgfwkoQOnVRUYgp8Gypjqk9QNQwnNdFUTEgWc1RWN+1RYO85esJzHLkA2hZFIrYu1TZeZ6g==", + "requires": {} + }, + "@chakra-ui/counter": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/counter/-/counter-2.0.9.tgz", + "integrity": "sha512-LuqtpyxCOZM19gAmV0vtVeaFd9ccPmEjoGJQ0NoO8CFheltgLC/7m/8YpDbgWiG4+BAkTUfIG+5nLg5hwvvQxw==", + "requires": { + "@chakra-ui/number-utils": "2.0.3", + "@chakra-ui/react-use-callback-ref": "2.0.3" + } + }, + "@chakra-ui/css-reset": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@chakra-ui/css-reset/-/css-reset-2.0.7.tgz", + "integrity": "sha512-ztGdFQ6U1hX2k6a3HZ8D3A/dZWVxlGe2F5mvUrRU554mFWBYmsq0ydZ7UBEPlykv9NoCz4nN8VCkIxcKJ3p29Q==", + "requires": {} + }, + "@chakra-ui/descendant": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/descendant/-/descendant-3.0.9.tgz", + "integrity": "sha512-30E5yMWvxgBx43PoI/67r9h9OhbpDfLb/MLOCjtEwebSbD0V5+fmnmCoUELScQbhozQVjA9t195X6UP0VQWj8w==", + "requires": { + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.3" + } + }, + "@chakra-ui/dom-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/dom-utils/-/dom-utils-2.0.1.tgz", + "integrity": "sha512-sbob9AHQq1+KIQ3XKslafislwtC8pYcpwM0S1SLzgyZumHRwhDimKwdi4MtRQfOCenub0E3diRjp4RpGRL0JuQ==" + }, + "@chakra-ui/editable": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/editable/-/editable-2.0.9.tgz", + "integrity": "sha512-s5F3UMR09s6ga3eVhw0UBMGmegtxg6jCp29VLqaEwP5BuWIEOjcJz358gTlnFr3dhvb31e3rcr+B1XiYv4wxqg==", + "requires": { + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-types": "2.0.3", + "@chakra-ui/react-use-controllable-state": "2.0.3", + "@chakra-ui/react-use-focus-on-pointer-down": "2.0.1", + "@chakra-ui/react-use-merge-refs": "2.0.3", + "@chakra-ui/react-use-safe-layout-effect": "2.0.1", + "@chakra-ui/react-use-update-effect": "2.0.3", + "@chakra-ui/shared-utils": "2.0.1" + } + }, + "@chakra-ui/event-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@chakra-ui/event-utils/-/event-utils-2.0.4.tgz", + "integrity": "sha512-J2YgAM5Dw9hMkwfMsWhsiAG848GfTMxNclUIUcgV9RQhLEs0eTFhelzNiKVOMA3vBxlT6lOARuRun/ESiFZgGg==" + }, + "@chakra-ui/focus-lock": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@chakra-ui/focus-lock/-/focus-lock-2.0.10.tgz", + "integrity": "sha512-LeRZYzwfJp0eq84oO8e1pC2qC8v8fJw/P4nYDrCDjuJU753DV6nVjp5MKMRqbkp+6IAElPc+ojy/sp2a9GCocw==", + "requires": { + "@chakra-ui/dom-utils": "2.0.1", + "react-focus-lock": "^2.9.1" + } + }, + "@chakra-ui/form-control": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/form-control/-/form-control-2.0.9.tgz", + "integrity": "sha512-P8Tr45z/XSAa1m6uAma0eKf1h7Ltg2sLj2jK5YhaXJER9VUUY18iGe96D4JrAXlgEWDhTyWMb63nB+eYO1tKtw==", + "requires": { + "@chakra-ui/icon": "3.0.9", + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-types": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.3" + }, + "dependencies": { + "@chakra-ui/icon": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/icon/-/icon-3.0.9.tgz", + "integrity": "sha512-P2Pwm/za6m1W1oqL2kGHH6XrrymsBjqYAFwOW2lB5Q6mI1e+RYe/iMxDoPSLHMYhqdfH7vyib/ffE3Vv3a5oTA==", + "requires": { + "@chakra-ui/shared-utils": "2.0.1" + } + } + } + }, + "@chakra-ui/hooks": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/hooks/-/hooks-2.0.9.tgz", + "integrity": "sha512-0JRgEPtsBaXr9nQW1xEKlWGA7WwFbLNqac7fQXp9zQvoHOWTfNJkK/NJaVBvyFPgfTLxy37WKHooVSwNG/Lwmg==", + "requires": { + "@chakra-ui/react-utils": "2.0.6", + "@chakra-ui/utils": "2.0.9", + "compute-scroll-into-view": "1.0.14", + "copy-to-clipboard": "3.3.1" + } + }, + "@chakra-ui/icon": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@chakra-ui/icon/-/icon-3.0.10.tgz", + "integrity": "sha512-utO569d9bptEraJrEhuImfNzQ8v+a8PsQh8kTsodCzg8B16R3t5TTuoqeJqS6Nq16Vq6w87QbX3/4A73CNK5fw==", + "requires": { + "@chakra-ui/shared-utils": "2.0.1" + } + }, + "@chakra-ui/icons": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@chakra-ui/icons/-/icons-2.0.10.tgz", + "integrity": "sha512-hxMspvysOay2NsJyadM611F/Y4vVzJU/YkXTxsyBjm6v/DbENhpVmPnUf+kwwyl7dINNb9iOF+kuGxnuIEO1Tw==", + "requires": { + "@chakra-ui/icon": "3.0.10" + } + }, + "@chakra-ui/image": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@chakra-ui/image/-/image-2.0.10.tgz", + "integrity": "sha512-Atc1bdog4V5xv7IbpF2F2UkKWfgG/TD74cIac09JuSpQcYyh7lrJ7iVvhTkeP+LDdCs+QCD7SnTUM4Y0ZlaHbA==", + "requires": { + "@chakra-ui/react-use-safe-layout-effect": "2.0.1" + } + }, + "@chakra-ui/input": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/input/-/input-2.0.9.tgz", + "integrity": "sha512-6MKydxTyF7JV7PtQHircQ5HBTd6Ik9Vn7p8fCLeAieT0TK8UQTxMWZVPminS7TRWMutrq8W99DcQOBlMz0cKrw==", + "requires": { + "@chakra-ui/form-control": "2.0.9", + "@chakra-ui/object-utils": "2.0.3", + "@chakra-ui/react-children-utils": "2.0.1", + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/shared-utils": "2.0.1" + } + }, + "@chakra-ui/layout": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@chakra-ui/layout/-/layout-2.1.6.tgz", + "integrity": "sha512-QDNaVu44UI46c+YlSF1KrzJkiwua0UtRXNTnR3jBE1uzcuqRow7xgr3E60dLphY2cPFqAljfQZUNlP3sgvCLww==", + "requires": { + "@chakra-ui/breakpoint-utils": "2.0.3", + "@chakra-ui/icon": "3.0.9", + "@chakra-ui/object-utils": "2.0.3", + "@chakra-ui/react-children-utils": "2.0.1", + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/shared-utils": "2.0.1" + }, + "dependencies": { + "@chakra-ui/icon": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/icon/-/icon-3.0.9.tgz", + "integrity": "sha512-P2Pwm/za6m1W1oqL2kGHH6XrrymsBjqYAFwOW2lB5Q6mI1e+RYe/iMxDoPSLHMYhqdfH7vyib/ffE3Vv3a5oTA==", + "requires": { + "@chakra-ui/shared-utils": "2.0.1" + } + } + } + }, + "@chakra-ui/lazy-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/lazy-utils/-/lazy-utils-2.0.1.tgz", + "integrity": "sha512-986YjYq+hEzHDLZiqYlYbdqfiKdC3h2g896Eoe5K2UXtAVxqZI3UOnMH781X6N1R7rGJWquskzG681qFigW/BA==" + }, + "@chakra-ui/live-region": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/live-region/-/live-region-2.0.9.tgz", + "integrity": "sha512-ilbo/C5wcUoSHDU5owFPQP3KsabPYGzDEbwV+Z76BlyNdFN2PD0j13RGEH+sBNNZ3HzLyyuuc1YmkVcJi7ycQg==", + "requires": {} + }, + "@chakra-ui/media-query": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/media-query/-/media-query-3.2.5.tgz", + "integrity": "sha512-V+Dngi/r7u/uj7JhsZerM1RI597Oo4wED2ojNfclnnEVb/IoqktiuFy6RQgbo3HmE7M/E5B1i4yYzt7tQJhXlg==", + "requires": { + "@chakra-ui/breakpoint-utils": "2.0.3", + "@chakra-ui/react-env": "2.0.9" + } + }, + "@chakra-ui/menu": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@chakra-ui/menu/-/menu-2.0.13.tgz", + "integrity": "sha512-XZYoq9k/txAELUgn5OokyxfXEpVZwBueVYXiT9ji0XvMuzXVxeHd40klJEkiJUctNsOahZf10t5yxlT4B00pwA==", + "requires": { + "@chakra-ui/clickable": "2.0.9", + "@chakra-ui/descendant": "3.0.9", + "@chakra-ui/lazy-utils": "2.0.1", + "@chakra-ui/popper": "3.0.7", + "@chakra-ui/react-children-utils": "2.0.1", + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-use-animation-state": "2.0.3", + "@chakra-ui/react-use-controllable-state": "2.0.3", + "@chakra-ui/react-use-disclosure": "2.0.3", + "@chakra-ui/react-use-focus-effect": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.3", + "@chakra-ui/react-use-outside-click": "2.0.3", + "@chakra-ui/react-use-update-effect": "2.0.3", + "@chakra-ui/transition": "2.0.9" + } + }, + "@chakra-ui/modal": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@chakra-ui/modal/-/modal-2.1.7.tgz", + "integrity": "sha512-A+CbvhQYpmLH3SrqJ1wJysUCGm0mNoSDxRjP4wX98j56nMTDAsMYlzttpuLmKaSzvbJ7uEQDLtQV8lZjB0gUuw==", + "requires": { + "@chakra-ui/close-button": "2.0.9", + "@chakra-ui/focus-lock": "2.0.10", + "@chakra-ui/portal": "2.0.9", + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-types": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.3", + "@chakra-ui/transition": "2.0.9", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "^2.5.4" + } + }, + "@chakra-ui/number-input": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/number-input/-/number-input-2.0.9.tgz", + "integrity": "sha512-RsDzoNvSBZMgyXjN543AtQ2v99U1p/0xnGWZy4NCkgCDWMBn3kIXqSzQq5CB9Ot0MD8nnKF5VYdVdXWguXExEQ==", + "requires": { + "@chakra-ui/counter": "2.0.9", + "@chakra-ui/form-control": "2.0.9", + "@chakra-ui/icon": "3.0.9", + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-types": "2.0.3", + "@chakra-ui/react-use-callback-ref": "2.0.3", + "@chakra-ui/react-use-event-listener": "2.0.3", + "@chakra-ui/react-use-interval": "2.0.1", + "@chakra-ui/react-use-merge-refs": "2.0.3", + "@chakra-ui/react-use-safe-layout-effect": "2.0.1", + "@chakra-ui/react-use-update-effect": "2.0.3" + }, + "dependencies": { + "@chakra-ui/icon": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/icon/-/icon-3.0.9.tgz", + "integrity": "sha512-P2Pwm/za6m1W1oqL2kGHH6XrrymsBjqYAFwOW2lB5Q6mI1e+RYe/iMxDoPSLHMYhqdfH7vyib/ffE3Vv3a5oTA==", + "requires": { + "@chakra-ui/shared-utils": "2.0.1" + } + } + } + }, + "@chakra-ui/number-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/number-utils/-/number-utils-2.0.3.tgz", + "integrity": "sha512-oN03kYAUCCp/FNtpLr5mh+cvd/sRTzZWTBoFydmxc955psXq/X950gzs6o5kzoeFCpgXaxMmHAXQm3ReEK2NsQ==" + }, + "@chakra-ui/object-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/object-utils/-/object-utils-2.0.3.tgz", + "integrity": "sha512-36prckrqTynVD/JTzyCr8OCWVOrMs/awZo3djVbIiNxRIcJ5iEwUVy26h3MWN4ENSopipBtxNfAwPNTLU5Si/g==" + }, + "@chakra-ui/pin-input": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@chakra-ui/pin-input/-/pin-input-2.0.12.tgz", + "integrity": "sha512-gaMRp5AFW+qAJCUj93V1WluuYBBZ/5A3Wy5q796g8Auvw7vufgkVtl6EBznwvtynZN8gJwbRFpMtJxQyXCkUiw==", + "requires": { + "@chakra-ui/descendant": "3.0.9", + "@chakra-ui/react-children-utils": "2.0.1", + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-use-controllable-state": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.3" + } + }, + "@chakra-ui/popover": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/popover/-/popover-2.0.9.tgz", + "integrity": "sha512-+7tH4RVuheFQOyAZ5KT9x+qsLvz7rGuKaHtb0427+5bhUzLaSAghtr/afzOKHDwUVBwF2tTUNanR23ipW1fXDg==", + "requires": { + "@chakra-ui/close-button": "2.0.9", + "@chakra-ui/hooks": "2.0.9", + "@chakra-ui/lazy-utils": "2.0.1", + "@chakra-ui/popper": "3.0.7", + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-types": "2.0.3", + "@chakra-ui/react-use-disclosure": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.3" + } + }, + "@chakra-ui/popper": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@chakra-ui/popper/-/popper-3.0.7.tgz", + "integrity": "sha512-xLYhuNsk1gOjymtek1ZdZlG21hmg2a7Iu2KsD9Hi7+aUxc2K5/XxX+/vyjjz8u4s0gmj83pTqnauQRynb/TCXA==", + "requires": { + "@chakra-ui/react-types": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.3", + "@popperjs/core": "^2.9.3" + } + }, + "@chakra-ui/portal": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/portal/-/portal-2.0.9.tgz", + "integrity": "sha512-9e9S0MLbkpofPGlyYA12jNYSdndugy6ylPi5pC9nr3/VqG2Kn+8VcBChAeXW8K4ms7WFc74rNX1pBY/UVwr4qg==", + "requires": { + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-use-safe-layout-effect": "2.0.1" + } + }, + "@chakra-ui/progress": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@chakra-ui/progress/-/progress-2.0.10.tgz", + "integrity": "sha512-my0Pi3NG1PYhlvCav4fybg3gL5HBNe+7lO4PVdri4QHEyfJlrDeBWID+1GgqlpUWdTj3sOf7ysku+FEgkeOeSA==", + "requires": { + "@chakra-ui/react-context": "2.0.3" + } + }, + "@chakra-ui/provider": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/@chakra-ui/provider/-/provider-2.0.16.tgz", + "integrity": "sha512-4t/PmjJ7WXPPaPfoYgw8F1/rVtorZuvknugHfOZcOtAPGQmOPotSv28qjKpu/mCvc1GMGV0swMsvCeInYz7g0w==", + "requires": { + "@chakra-ui/css-reset": "2.0.7", + "@chakra-ui/portal": "2.0.9", + "@chakra-ui/react-env": "2.0.9", + "@chakra-ui/system": "2.2.9", + "@chakra-ui/utils": "2.0.9" + } + }, + "@chakra-ui/radio": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@chakra-ui/radio/-/radio-2.0.10.tgz", + "integrity": "sha512-LhAWsY22cmb+M/iyhFgkzf2+V9TJmAC77Cd+GbP3M3sxDSEUDtq08KOc3JjoYc3GzeZml3JL1yssbxh+liY3xA==", + "requires": { + "@chakra-ui/form-control": "2.0.9", + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-types": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.3", + "@zag-js/focus-visible": "0.1.0" + } + }, + "@chakra-ui/react": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@chakra-ui/react/-/react-2.3.2.tgz", + "integrity": "sha512-qOcDLbA1x4pnpJPtF4YJ7pZzK/ki6SoQl9Vj7fsR+hJw1lt3y1475NSyYGiA6qgho/8twUgYLhcdrTbQPcmOHg==", + "requires": { + "@chakra-ui/accordion": "2.0.12", + "@chakra-ui/alert": "2.0.9", + "@chakra-ui/avatar": "2.1.0", + "@chakra-ui/breadcrumb": "2.0.9", + "@chakra-ui/button": "2.0.9", + "@chakra-ui/checkbox": "2.1.8", + "@chakra-ui/close-button": "2.0.9", + "@chakra-ui/control-box": "2.0.9", + "@chakra-ui/counter": "2.0.9", + "@chakra-ui/css-reset": "2.0.7", + "@chakra-ui/editable": "2.0.9", + "@chakra-ui/form-control": "2.0.9", + "@chakra-ui/hooks": "2.0.9", + "@chakra-ui/icon": "3.0.9", + "@chakra-ui/image": "2.0.10", + "@chakra-ui/input": "2.0.9", + "@chakra-ui/layout": "2.1.6", + "@chakra-ui/live-region": "2.0.9", + "@chakra-ui/media-query": "3.2.5", + "@chakra-ui/menu": "2.0.13", + "@chakra-ui/modal": "2.1.7", + "@chakra-ui/number-input": "2.0.9", + "@chakra-ui/pin-input": "2.0.12", + "@chakra-ui/popover": "2.0.9", + "@chakra-ui/popper": "3.0.7", + "@chakra-ui/portal": "2.0.9", + "@chakra-ui/progress": "2.0.10", + "@chakra-ui/provider": "2.0.16", + "@chakra-ui/radio": "2.0.10", + "@chakra-ui/react-env": "2.0.9", + "@chakra-ui/select": "2.0.10", + "@chakra-ui/skeleton": "2.0.15", + "@chakra-ui/slider": "2.0.10", + "@chakra-ui/spinner": "2.0.9", + "@chakra-ui/stat": "2.0.9", + "@chakra-ui/switch": "2.0.11", + "@chakra-ui/system": "2.2.9", + "@chakra-ui/table": "2.0.9", + "@chakra-ui/tabs": "2.1.1", + "@chakra-ui/tag": "2.0.9", + "@chakra-ui/textarea": "2.0.10", + "@chakra-ui/theme": "2.1.11", + "@chakra-ui/toast": "3.0.10", + "@chakra-ui/tooltip": "2.0.10", + "@chakra-ui/transition": "2.0.9", + "@chakra-ui/utils": "2.0.9", + "@chakra-ui/visually-hidden": "2.0.9" + }, + "dependencies": { + "@chakra-ui/icon": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/icon/-/icon-3.0.9.tgz", + "integrity": "sha512-P2Pwm/za6m1W1oqL2kGHH6XrrymsBjqYAFwOW2lB5Q6mI1e+RYe/iMxDoPSLHMYhqdfH7vyib/ffE3Vv3a5oTA==", + "requires": { + "@chakra-ui/shared-utils": "2.0.1" + } + } + } + }, + "@chakra-ui/react-children-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-children-utils/-/react-children-utils-2.0.1.tgz", + "integrity": "sha512-sEgpuh/vWSt2+W0F49EGYXXUyjmg0lbosjVg6qUKHv9sAyx5tbrOrZ6df/TaMUSAe9m3AUOMGqUIPLpxno0DjA==" + }, + "@chakra-ui/react-context": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-context/-/react-context-2.0.3.tgz", + "integrity": "sha512-KmPq6sb1y05WsOUqXZtBBC4LsNKZIFrp2thTsLBwcuH7lkXZwPMHmJGKa9K980P+SWEgfH2s2PY2z+QrIuqWGg==", + "requires": {} + }, + "@chakra-ui/react-env": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-env/-/react-env-2.0.9.tgz", + "integrity": "sha512-4AJHNUGBR19hzVyOILYpZZgq8jGrpEcbhvR++CppbvPH7vfPZpoz6L/cBtHxS07YwDtUeBL8yCNiLlTxctV//Q==", + "requires": {} + }, + "@chakra-ui/react-types": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-types/-/react-types-2.0.3.tgz", + "integrity": "sha512-1mJYOQldFTALE0Wr3j6tk/MYvgQIp6CKkJulNzZrI8QN+ox/bJOh8OVP4vhwqvfigdLTui0g0k8M9h+j2ub/Mw==", + "requires": {} + }, + "@chakra-ui/react-use-animation-state": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-animation-state/-/react-use-animation-state-2.0.3.tgz", + "integrity": "sha512-sjGgzMMmxurwKDSFhDLpLNn3SWUERI5iAZOOa0pYnyOLGVXMowgIjK6jpZxre1vc3A+unjJk5P4qeiyY+C4uwQ==", + "requires": { + "@chakra-ui/dom-utils": "2.0.1", + "@chakra-ui/react-use-event-listener": "2.0.3" + } + }, + "@chakra-ui/react-use-callback-ref": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-callback-ref/-/react-use-callback-ref-2.0.3.tgz", + "integrity": "sha512-kdYlhgnQKWWLNwl3WSv/Oq3+mlnu2p3y4Xc1AqKVHVcBOdQE9lpW3d7ZaOoK2aIXXWq1rocscOiXBUtM0Vqd2A==", + "requires": {} + }, + "@chakra-ui/react-use-controllable-state": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-controllable-state/-/react-use-controllable-state-2.0.3.tgz", + "integrity": "sha512-su8efwCWWnY2LQUU6PEnYwSGJX8kvPSO2KyUKuymx8q3fNWuyhzAZriG/TbeeCxESLp70+wuniUlSGRa4vxylQ==", + "requires": { + "@chakra-ui/react-use-callback-ref": "2.0.3" + } + }, + "@chakra-ui/react-use-disclosure": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-disclosure/-/react-use-disclosure-2.0.3.tgz", + "integrity": "sha512-3IdrzvQZcgjqSx5wTVffInOyhMU+d3ZlIE26JmqejMyN/B+qAs932iKfm0A1mTMPTz38ZnNtuaKazmzyfR1ePg==", + "requires": { + "@chakra-ui/react-use-callback-ref": "2.0.3" + } + }, + "@chakra-ui/react-use-event-listener": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-event-listener/-/react-use-event-listener-2.0.3.tgz", + "integrity": "sha512-m3ZdJjo3QQ1HcQGnehlBTgHaCVewz5fwIRTXVzbZTraVJr4k589Zf87eagW57tT4dyv656lSmdhaFGZ8p5Snww==", + "requires": { + "@chakra-ui/react-use-callback-ref": "2.0.3" + } + }, + "@chakra-ui/react-use-focus-effect": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-focus-effect/-/react-use-focus-effect-2.0.3.tgz", + "integrity": "sha512-N0rho7P+rH5cn13dbS8GUOye+6RYXAmXhmlS+WW/3lWidGH3HAbMoOVf56UiuSnE1+2or8/U7qRshUryj2H1nA==", + "requires": { + "@chakra-ui/dom-utils": "2.0.1", + "@chakra-ui/react-use-event-listener": "2.0.3", + "@chakra-ui/react-use-update-effect": "2.0.3" + } + }, + "@chakra-ui/react-use-focus-on-pointer-down": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-focus-on-pointer-down/-/react-use-focus-on-pointer-down-2.0.1.tgz", + "integrity": "sha512-f0qL2iWvajUo+0jwDZyJpUMJ6J6BH3WjDZE2Rp6cns4pgI6uYuv2gj+FqQ5jnoYdXkeER6lBI56a+aIW/1RYiA==", + "requires": { + "@chakra-ui/react-use-event-listener": "2.0.3" + } + }, + "@chakra-ui/react-use-interval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-interval/-/react-use-interval-2.0.1.tgz", + "integrity": "sha512-6ZLzKA7Ga894UZcXO3bbGYThlhviiau1oxZ1UcJG5pUXNM9Up7O/4Joq31sL+KcpteCN45vd1etomilsv/blxw==", + "requires": { + "@chakra-ui/react-use-callback-ref": "2.0.3" + } + }, + "@chakra-ui/react-use-merge-refs": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-merge-refs/-/react-use-merge-refs-2.0.3.tgz", + "integrity": "sha512-n35BmVbasy5Esa6qxznWmiV3NaRxGpqMpZH0n+X7aXt8VkGAJzRpAVjUmKCLNYyCLpqsQceCmAEK8a5SR6vxqw==", + "requires": {} + }, + "@chakra-ui/react-use-outside-click": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-outside-click/-/react-use-outside-click-2.0.3.tgz", + "integrity": "sha512-r5OohM8lOuZTz6e3vVHvfm/3sEkd06nUPBNU+r3rWh1I7bR9z5Gia/BOQD6GE4jUTanDkHcH76Pf9qJ45kpibQ==", + "requires": { + "@chakra-ui/react-use-callback-ref": "2.0.3" + } + }, + "@chakra-ui/react-use-pan-event": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-pan-event/-/react-use-pan-event-2.0.4.tgz", + "integrity": "sha512-lcEjngfCgIjE5qZeJiaDx+aJzZPLjbjUmbWumi8pIgWOnDL8Ffjh7AMKW4CddP5OgcRnDDb+7aqJbb55wraboA==", + "requires": { + "@chakra-ui/event-utils": "2.0.4", + "framesync": "5.3.0" + } + }, + "@chakra-ui/react-use-previous": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-previous/-/react-use-previous-2.0.1.tgz", + "integrity": "sha512-ROi+/puVd8D1QaxBSOcGlJNqV2x02ppSgmXzZZJhM8ryFLZjY9ojV3HhamB2IJ/7SIb1rMSSV1GPedFw7YMCwA==", + "requires": {} + }, + "@chakra-ui/react-use-safe-layout-effect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-safe-layout-effect/-/react-use-safe-layout-effect-2.0.1.tgz", + "integrity": "sha512-H+ZOjkPqv3KBPEoP68JKpQBNdLOI0mwzEiTT397UdvBVCCJ+1/ijWVUT+Ub/pYic60O6xUghy5ORaWqJHhnKDA==", + "requires": {} + }, + "@chakra-ui/react-use-size": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-size/-/react-use-size-2.0.3.tgz", + "integrity": "sha512-hr4hKepPUmM2paXseSZiOTK2y+ZqnSzYNusDEB01f+cDerFjdN1jSfNJKXpiKF0+hNESXfOPQb3Zt0eDusRdoA==", + "requires": { + "@zag-js/element-size": "0.1.0" + } + }, + "@chakra-ui/react-use-timeout": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-timeout/-/react-use-timeout-2.0.1.tgz", + "integrity": "sha512-zXh9RH+GciKr8hvaOADHOoHP72B7UZUEymA8CWCV4WEs/9s/PfQJH7X1bwvaj43CcOmfVQg4oODWqCYQM1lSsg==", + "requires": { + "@chakra-ui/react-use-callback-ref": "2.0.3" + } + }, + "@chakra-ui/react-use-update-effect": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-update-effect/-/react-use-update-effect-2.0.3.tgz", + "integrity": "sha512-8hkP1o/UUUA49w/R+XyAlPiCjxXTCWCNsHWUOEhAitjJfoCNUjgaNKOD52hT07kc5ACJEcJQHA5327LnwtiIlg==", + "requires": {} + }, + "@chakra-ui/react-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-utils/-/react-utils-2.0.6.tgz", + "integrity": "sha512-ZL0FPaolovXOxMzYRSLHgBYtvxIkA/c5GTSYpXL8DcC+TBLZnAmQ8BPTS2b6xys6xvwdQjkZRUeQ0cBNFaryJg==", + "requires": { + "@chakra-ui/utils": "2.0.9" + } + }, + "@chakra-ui/select": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@chakra-ui/select/-/select-2.0.10.tgz", + "integrity": "sha512-7AslBWwI/JyczjMMGtPuN34M/C38koVd+N/pb6swHoIP9TRkkdvDlonIakcmtO1oLEzlNIFKmt4FQ7bUp9ea5Q==", + "requires": { + "@chakra-ui/form-control": "2.0.9" + } + }, + "@chakra-ui/shared-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/shared-utils/-/shared-utils-2.0.1.tgz", + "integrity": "sha512-NXDBl/u4wrSNp0ON5R3r3evkRurrAz2yuO7neooaG+O5HEenVouGqm4CsXd6lUAPmjwiGzA0LQFNCt0Hj92dXg==" + }, + "@chakra-ui/skeleton": { + "version": "2.0.15", + "resolved": "https://registry.npmjs.org/@chakra-ui/skeleton/-/skeleton-2.0.15.tgz", + "integrity": "sha512-QVMkXwrH9jLfim8uJTZcjHeGjzoquNcHGXD5wapd7eDqp9BygvmMXAHBxFm8eEJLHuvIqLX94P6DLeiieYwX7Q==", + "requires": { + "@chakra-ui/media-query": "3.2.5", + "@chakra-ui/react-use-previous": "2.0.1" + } + }, + "@chakra-ui/slider": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@chakra-ui/slider/-/slider-2.0.10.tgz", + "integrity": "sha512-F0RGl2ruADbXO/GnoBUiTEl+przxhZo2e0tfw9VTtS+RsJZ22uHrTNVvVJHNmjK7/E3++kBfaLCacoJFz/io+g==", + "requires": { + "@chakra-ui/number-utils": "2.0.3", + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-types": "2.0.3", + "@chakra-ui/react-use-callback-ref": "2.0.3", + "@chakra-ui/react-use-controllable-state": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.3", + "@chakra-ui/react-use-pan-event": "2.0.4", + "@chakra-ui/react-use-size": "2.0.3", + "@chakra-ui/react-use-update-effect": "2.0.3" + } + }, + "@chakra-ui/spinner": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/spinner/-/spinner-2.0.9.tgz", + "integrity": "sha512-9ALl51fiVWptDu2J2xcv0TSfGf4buumpHrEXHvV2Qy+HZ6rYnUmSThBSb/VgoQS+rASG8bAbLUPlQTQ+v9ibFg==", + "requires": {} + }, + "@chakra-ui/stat": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/stat/-/stat-2.0.9.tgz", + "integrity": "sha512-C9cytqegWSGJ/hh3/qwsgGlerXLYHrU0iQcJQ+pKSRFJhshXsv3go5IR6kVL72Yf2s4Gs5c3GsMZrLM22ePpDg==", + "requires": { + "@chakra-ui/icon": "3.0.9", + "@chakra-ui/react-context": "2.0.3" + }, + "dependencies": { + "@chakra-ui/icon": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/icon/-/icon-3.0.9.tgz", + "integrity": "sha512-P2Pwm/za6m1W1oqL2kGHH6XrrymsBjqYAFwOW2lB5Q6mI1e+RYe/iMxDoPSLHMYhqdfH7vyib/ffE3Vv3a5oTA==", + "requires": { + "@chakra-ui/shared-utils": "2.0.1" + } + } + } + }, + "@chakra-ui/styled-system": { + "version": "2.3.4", + "peer": true, + "requires": { + "csstype": "^3.0.11", + "lodash.mergewith": "4.6.2" + } + }, + "@chakra-ui/switch": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@chakra-ui/switch/-/switch-2.0.11.tgz", + "integrity": "sha512-gY8OGBnoPosZpq7dDNVf432t67pTc/cz5VkGhbtER7bbjXSoXe0DAiAYL+HT2kD7mbTJQzzHK/y0St0WimR1Mw==", + "requires": { + "@chakra-ui/checkbox": "2.1.8" + } + }, + "@chakra-ui/system": { + "version": "2.2.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/system/-/system-2.2.9.tgz", + "integrity": "sha512-SyTeIGm+goyYK8vqX4dU6oeLhxUAeGI3Cl+mxA+aiKIX01YTALhTWhpbrsuMYBevV+l9EGK12egPUQE+Mo3WlQ==", + "requires": { + "@chakra-ui/color-mode": "2.1.7", + "@chakra-ui/react-utils": "2.0.6", + "@chakra-ui/styled-system": "2.3.1", + "@chakra-ui/utils": "2.0.9", + "react-fast-compare": "3.2.0" + }, + "dependencies": { + "@chakra-ui/styled-system": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/styled-system/-/styled-system-2.3.1.tgz", + "integrity": "sha512-jyR9s2yk5TEyq4HUfjrgUeaOzd9ZTZrbjK96UjtiTCZGO/q4j2RXtYvfheUjUyW1UnzI2A1ffHOJca8tBMDjpA==", + "requires": { + "csstype": "^3.0.11", + "lodash.mergewith": "4.6.2" + } + } + } + }, + "@chakra-ui/table": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/table/-/table-2.0.9.tgz", + "integrity": "sha512-XRz6+x4dMeQX3xyViyG2H/P1STI/2vwvgU2cjzzwS+5fZ2JdGaTgYzBb+IZoH9agEq1Ma3rlKMUPDrRCFb7kLQ==", + "requires": { + "@chakra-ui/react-context": "2.0.3" + } + }, + "@chakra-ui/tabs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/tabs/-/tabs-2.1.1.tgz", + "integrity": "sha512-xA+vwqpAHb0nBLrkiO5Lea2UDGROyAIBqsyp/8XXXEr6eKxtNe1I6WJPbDQy0aazB2ToAA0R6fT34HjLaXP8MQ==", + "requires": { + "@chakra-ui/clickable": "2.0.9", + "@chakra-ui/descendant": "3.0.9", + "@chakra-ui/lazy-utils": "2.0.1", + "@chakra-ui/react-children-utils": "2.0.1", + "@chakra-ui/react-context": "2.0.3", + "@chakra-ui/react-use-controllable-state": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.3", + "@chakra-ui/react-use-safe-layout-effect": "2.0.1" + } + }, + "@chakra-ui/tag": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/tag/-/tag-2.0.9.tgz", + "integrity": "sha512-NKARwhsZ04t2vkrdRhNcakEiVtg1q44yUUsDw2Jwdu4idAWQupZGGochQI2Ac4T2MI1b66zQUkaGnm3l1mhTtg==", + "requires": { + "@chakra-ui/icon": "3.0.9", + "@chakra-ui/react-context": "2.0.3" + }, + "dependencies": { + "@chakra-ui/icon": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/icon/-/icon-3.0.9.tgz", + "integrity": "sha512-P2Pwm/za6m1W1oqL2kGHH6XrrymsBjqYAFwOW2lB5Q6mI1e+RYe/iMxDoPSLHMYhqdfH7vyib/ffE3Vv3a5oTA==", + "requires": { + "@chakra-ui/shared-utils": "2.0.1" + } + } + } + }, + "@chakra-ui/textarea": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@chakra-ui/textarea/-/textarea-2.0.10.tgz", + "integrity": "sha512-HSo0EPsY8XKGA+Af6jTob1oe1T6NKZwgjLmX0binK3MMM9pDTXsUTw8GD0g971lxw9oktVMLK/O9QVAgVAm5mw==", + "requires": { + "@chakra-ui/form-control": "2.0.9" + } + }, + "@chakra-ui/theme": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/@chakra-ui/theme/-/theme-2.1.11.tgz", + "integrity": "sha512-gI0NLU6wO/5cRq8gbDHuy24Y/ZhJxN4D/2uucNN9is3h+d58/En5jV3fwzZW8PLiLKW/T2CmbYWEZWV2YkcUVA==", + "requires": { + "@chakra-ui/anatomy": "2.0.6", + "@chakra-ui/theme-tools": "2.0.11" + } + }, + "@chakra-ui/theme-tools": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@chakra-ui/theme-tools/-/theme-tools-2.0.11.tgz", + "integrity": "sha512-0Juf98bAyOgnBeQ39nMKWqRsOxZDw75BbAB8o0oVyjhYVS1wJh7tFX1ZRV8N/+AN6fuRXEznZPpyUh3J+ZTiRg==", + "requires": { + "@chakra-ui/anatomy": "2.0.6", + "@ctrl/tinycolor": "^3.4.0" + } + }, + "@chakra-ui/toast": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@chakra-ui/toast/-/toast-3.0.10.tgz", + "integrity": "sha512-i/oEtzmarO0hM6fxa55OmA8ZGkZv9b+vIC2xs5kQ/C0rJaC0ycibok8srq2Stjq9309fZNezyzThQp6e9acUYQ==", + "requires": { + "@chakra-ui/alert": "2.0.9", + "@chakra-ui/close-button": "2.0.9", + "@chakra-ui/portal": "2.0.9", + "@chakra-ui/react-use-timeout": "2.0.1", + "@chakra-ui/react-use-update-effect": "2.0.3", + "@chakra-ui/theme": "2.1.11" + } + }, + "@chakra-ui/tooltip": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@chakra-ui/tooltip/-/tooltip-2.0.10.tgz", + "integrity": "sha512-pBILBdZoux2K3EW9V6JuyZYUWz2/Y7oYCVO6AwNOesiEBGAONyzoDwFV728EzPEHe9e+YBcKOSZ9tEpDdrzHMA==", + "requires": { + "@chakra-ui/popper": "3.0.7", + "@chakra-ui/portal": "2.0.9", + "@chakra-ui/react-types": "2.0.3", + "@chakra-ui/react-use-disclosure": "2.0.3", + "@chakra-ui/react-use-event-listener": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.3" + } + }, + "@chakra-ui/transition": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/transition/-/transition-2.0.9.tgz", + "integrity": "sha512-cVfKdZl128AEj0LDS8M9dzXao4wmTVj3gRJBnm91Qcg243Pm8OlgIBNbHEwsq/Fps+PsN431BtEGfL4w79wQEA==", + "requires": {} + }, + "@chakra-ui/utils": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/utils/-/utils-2.0.9.tgz", + "integrity": "sha512-7ct5562Jw6pZdtj63XfUkEUXXsCCVqdqIXyLtQ9VgOKtRQWwDxzc8uPI5Zjdw9AleEITZFUH8TNKWn75nm54kQ==", + "requires": { + "@types/lodash.mergewith": "4.6.6", + "css-box-model": "1.2.1", + "framesync": "5.3.0", + "lodash.mergewith": "4.6.2" + } + }, + "@chakra-ui/visually-hidden": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/visually-hidden/-/visually-hidden-2.0.9.tgz", + "integrity": "sha512-PkNxrRGp9H3bdqEaoo8XGt/AL9UuGRTom0/9XJa+G/Dj8Cy1sDuamOWk3pN/ZQs46RokfK9Uh5LqPY5dwSDweg==", + "requires": {} + }, + "@ctrl/tinycolor": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.4.1.tgz", + "integrity": "sha512-ej5oVy6lykXsvieQtqZxCOaLT+xD4+QNarq78cIYISHmZXshCvROLudpQN3lfL8G0NL7plMSSK+zlyvCaIJ4Iw==" + }, + "@emotion/babel-plugin": { + "version": "11.10.2", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.2.tgz", + "integrity": "sha512-xNQ57njWTFVfPAc3cjfuaPdsgLp5QOSuRsj9MA6ndEhH/AzuZM86qIQzt6rq+aGBwj3n5/TkLmU5lhAfdRmogA==", + "requires": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/plugin-syntax-jsx": "^7.17.12", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.0", + "@emotion/memoize": "^0.8.0", + "@emotion/serialize": "^1.1.0", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.0.13" + } + }, + "@emotion/cache": { + "version": "11.10.3", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.3.tgz", + "integrity": "sha512-Psmp/7ovAa8appWh3g51goxu/z3iVms7JXOreq136D8Bbn6dYraPnmL6mdM8GThEx9vwSn92Fz+mGSjBzN8UPQ==", + "requires": { + "@emotion/memoize": "^0.8.0", + "@emotion/sheet": "^1.2.0", + "@emotion/utils": "^1.2.0", + "@emotion/weak-memoize": "^0.3.0", + "stylis": "4.0.13" + } + }, + "@emotion/hash": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz", + "integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ==" + }, + "@emotion/is-prop-valid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", + "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", + "requires": { + "@emotion/memoize": "^0.8.0" + } + }, + "@emotion/memoize": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", + "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" + }, + "@emotion/react": { + "version": "11.10.4", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.4.tgz", + "integrity": "sha512-j0AkMpr6BL8gldJZ6XQsQ8DnS9TxEQu1R+OGmDZiWjBAJtCcbt0tS3I/YffoqHXxH6MjgI7KdMbYKw3MEiU9eA==", + "requires": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.10.0", + "@emotion/cache": "^11.10.0", + "@emotion/serialize": "^1.1.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", + "@emotion/utils": "^1.2.0", + "@emotion/weak-memoize": "^0.3.0", + "hoist-non-react-statics": "^3.3.1" + } + }, + "@emotion/serialize": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.0.tgz", + "integrity": "sha512-F1ZZZW51T/fx+wKbVlwsfchr5q97iW8brAnXmsskz4d0hVB4O3M/SiA3SaeH06x02lSNzkkQv+n3AX3kCXKSFA==", + "requires": { + "@emotion/hash": "^0.9.0", + "@emotion/memoize": "^0.8.0", + "@emotion/unitless": "^0.8.0", + "@emotion/utils": "^1.2.0", + "csstype": "^3.0.2" + } + }, + "@emotion/sheet": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.0.tgz", + "integrity": "sha512-OiTkRgpxescko+M51tZsMq7Puu/KP55wMT8BgpcXVG2hqXc0Vo0mfymJ/Uj24Hp0i083ji/o0aLddh08UEjq8w==" + }, + "@emotion/styled": { + "version": "11.10.4", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.10.4.tgz", + "integrity": "sha512-pRl4R8Ez3UXvOPfc2bzIoV8u9P97UedgHS4FPX594ntwEuAMA114wlaHvOK24HB48uqfXiGlYIZYCxVJ1R1ttQ==", + "requires": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.10.0", + "@emotion/is-prop-valid": "^1.2.0", + "@emotion/serialize": "^1.1.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", + "@emotion/utils": "^1.2.0" + } + }, + "@emotion/unitless": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", + "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" + }, + "@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz", + "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==", + "requires": {} + }, + "@emotion/utils": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz", + "integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw==" + }, + "@emotion/weak-memoize": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz", + "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==" + }, + "@eslint/eslintrc": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.2.tgz", + "integrity": "sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "globals": { + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + } + } + }, + "@floating-ui/core": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-0.7.3.tgz", + "integrity": "sha512-buc8BXHmG9l82+OQXOFU3Kr2XQx9ys01U/Q9HMIrZ300iLc8HLMgh7dcCqgYzAzf4BkoQvDcXf5Y+CuEZ5JBYg==" + }, + "@floating-ui/dom": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-0.5.4.tgz", + "integrity": "sha512-419BMceRLq0RrmTSDxn8hf9R3VCJv2K9PUfugh5JyEFmdjzDo+e8U5EdR8nzKq8Yj1htzLm3b6eQEEam3/rrtg==", + "requires": { + "@floating-ui/core": "^0.7.3" + } + }, + "@floating-ui/react-dom": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-0.7.2.tgz", + "integrity": "sha512-1T0sJcpHgX/u4I1OzIEhlcrvkUN8ln39nz7fMoE/2HDHrPiMFoOGR7++GYyfUmIQHkkrTinaeQsO3XWubjSvGg==", + "requires": { + "@floating-ui/dom": "^0.5.3", + "use-isomorphic-layout-effect": "^1.1.1" + } + }, + "@humanwhocodes/config-array": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz", + "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/gitignore-to-minimatch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", + "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", + "dev": true + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "requires": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==" + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + }, + "@jridgewell/trace-mapping": { + "version": "0.3.15", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", + "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@motionone/animation": { + "version": "10.14.0", + "resolved": "https://registry.npmjs.org/@motionone/animation/-/animation-10.14.0.tgz", + "integrity": "sha512-h+1sdyBP8vbxEBW5gPFDnj+m2DCqdlAuf2g6Iafb1lcMnqjsRXWlPw1AXgvUMXmreyhqmPbJqoNfIKdytampRQ==", + "requires": { + "@motionone/easing": "^10.14.0", + "@motionone/types": "^10.14.0", + "@motionone/utils": "^10.14.0", + "tslib": "^2.3.1" + } + }, + "@motionone/dom": { + "version": "10.13.1", + "resolved": "https://registry.npmjs.org/@motionone/dom/-/dom-10.13.1.tgz", + "integrity": "sha512-zjfX+AGMIt/fIqd/SL1Lj93S6AiJsEA3oc5M9VkUr+Gz+juRmYN1vfvZd6MvEkSqEjwPQgcjN7rGZHrDB9APfQ==", + "requires": { + "@motionone/animation": "^10.13.1", + "@motionone/generators": "^10.13.1", + "@motionone/types": "^10.13.0", + "@motionone/utils": "^10.13.1", + "hey-listen": "^1.0.8", + "tslib": "^2.3.1" + } + }, + "@motionone/easing": { + "version": "10.14.0", + "resolved": "https://registry.npmjs.org/@motionone/easing/-/easing-10.14.0.tgz", + "integrity": "sha512-2vUBdH9uWTlRbuErhcsMmt1jvMTTqvGmn9fHq8FleFDXBlHFs5jZzHJT9iw+4kR1h6a4SZQuCf72b9ji92qNYA==", + "requires": { + "@motionone/utils": "^10.14.0", + "tslib": "^2.3.1" + } + }, + "@motionone/generators": { + "version": "10.14.0", + "resolved": "https://registry.npmjs.org/@motionone/generators/-/generators-10.14.0.tgz", + "integrity": "sha512-6kRHezoFfIjFN7pPpaxmkdZXD36tQNcyJe3nwVqwJ+ZfC0e3rFmszR8kp9DEVFs9QL/akWjuGPSLBI1tvz+Vjg==", + "requires": { + "@motionone/types": "^10.14.0", + "@motionone/utils": "^10.14.0", + "tslib": "^2.3.1" + } + }, + "@motionone/types": { + "version": "10.14.0", + "resolved": "https://registry.npmjs.org/@motionone/types/-/types-10.14.0.tgz", + "integrity": "sha512-3bNWyYBHtVd27KncnJLhksMFQ5o2MSdk1cA/IZqsHtA9DnRM1SYgN01CTcJ8Iw8pCXF5Ocp34tyAjY7WRpOJJQ==" + }, + "@motionone/utils": { + "version": "10.14.0", + "resolved": "https://registry.npmjs.org/@motionone/utils/-/utils-10.14.0.tgz", + "integrity": "sha512-sLWBLPzRqkxmOTRzSaD3LFQXCPHvDzyHJ1a3VP9PRzBxyVd2pv51/gMOsdAcxQ9n+MIeGJnxzXBYplUHKj4jkw==", + "requires": { + "@motionone/types": "^10.14.0", + "hey-listen": "^1.0.8", + "tslib": "^2.3.1" + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@popperjs/core": { + "version": "2.11.6", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz", + "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==" + }, + "@radix-ui/number": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.0.tgz", + "integrity": "sha512-Ofwh/1HX69ZfJRiRBMTy7rgjAzHmwe4kW9C9Y99HTRUcYLUuVT0KESFj15rPjRgKJs20GPq8Bm5aEDJ8DuA3vA==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/primitive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.0.tgz", + "integrity": "sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-arrow": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.0.1.tgz", + "integrity": "sha512-1yientwXqXcErDHEv8av9ZVNEBldH8L9scVR3is20lL+jOCfcJyMFZFEY5cgIrgexsq1qggSXqiEL/d/4f+QXA==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.1" + } + }, + "@radix-ui/react-collection": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.0.1.tgz", + "integrity": "sha512-uuiFbs+YCKjn3X1DTSx9G7BHApu4GHbi3kgiwsnFUbOKCrwejAJv4eE4Vc8C0Oaxt9T0aV4ox0WCOdx+39Xo+g==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-slot": "1.0.1" + } + }, + "@radix-ui/react-compose-refs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.0.tgz", + "integrity": "sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-context": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.0.tgz", + "integrity": "sha512-1pVM9RfOQ+n/N5PJK33kRSKsr1glNxomxONs5c49MliinBY6Yw2Q995qfBUUo0/Mbg05B/sGA0gkgPI7kmSHBg==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-context-menu": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context-menu/-/react-context-menu-2.0.1.tgz", + "integrity": "sha512-7DuhU4xDcUk3AMJUlb5tHHOvJZ1GF4+snDIpjtWGlTvO0VktNKgbvBuGLlirdkYoUSI0mJXwOUcUXQapgIyefw==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-menu": "2.0.1", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-use-callback-ref": "1.0.0", + "@radix-ui/react-use-controllable-state": "1.0.0" + } + }, + "@radix-ui/react-direction": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.0.tgz", + "integrity": "sha512-2HV05lGUgYcA6xgLQ4BKPDmtL+QbIZYH5fCOTAOOcJ5O0QbWS3i9lKaurLzliYUDhORI2Qr3pyjhJh44lKA3rQ==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-dismissable-layer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.2.tgz", + "integrity": "sha512-WjJzMrTWROozDqLB0uRWYvj4UuXsM/2L19EmQ3Au+IJWqwvwq9Bwd+P8ivo0Deg9JDPArR1I6MbWNi1CmXsskg==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-use-callback-ref": "1.0.0", + "@radix-ui/react-use-escape-keydown": "1.0.2" + } + }, + "@radix-ui/react-focus-guards": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.0.tgz", + "integrity": "sha512-UagjDk4ijOAnGu4WMUPj9ahi7/zJJqNZ9ZAiGPp7waUWJO0O1aWXi/udPphI0IUjvrhBsZJGSN66dR2dsueLWQ==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-focus-scope": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.1.tgz", + "integrity": "sha512-Ej2MQTit8IWJiS2uuujGUmxXjF/y5xZptIIQnyd2JHLwtV0R2j9NRVoRj/1j/gJ7e3REdaBw4Hjf4a1ImhkZcQ==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-use-callback-ref": "1.0.0" + } + }, + "@radix-ui/react-id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.0.tgz", + "integrity": "sha512-Q6iAB/U7Tq3NTolBBQbHTgclPmGWE3OlktGGqrClPozSw4vkQ1DfQAOtzgRPecKsMdJINE05iaoDUG8tRzCBjw==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-layout-effect": "1.0.0" + } + }, + "@radix-ui/react-menu": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.0.1.tgz", + "integrity": "sha512-I5FFZQxCl2fHoJ7R0m5/oWA9EX8/ttH4AbgneoCH7DAXQioFeb0XMAYnOVSp1GgJZ1Nx/mohxNQSeTMcaF1YPw==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-collection": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-direction": "1.0.0", + "@radix-ui/react-dismissable-layer": "1.0.2", + "@radix-ui/react-focus-guards": "1.0.0", + "@radix-ui/react-focus-scope": "1.0.1", + "@radix-ui/react-id": "1.0.0", + "@radix-ui/react-popper": "1.0.1", + "@radix-ui/react-portal": "1.0.1", + "@radix-ui/react-presence": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-roving-focus": "1.0.1", + "@radix-ui/react-slot": "1.0.1", + "@radix-ui/react-use-callback-ref": "1.0.0", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.5" + } + }, + "@radix-ui/react-popper": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.0.1.tgz", + "integrity": "sha512-J4Vj7k3k+EHNWgcKrE+BLlQfpewxA7Zd76h5I0bIa+/EqaIZ3DuwrbPj49O3wqN+STnXsBuxiHLiF0iU3yfovw==", + "requires": { + "@babel/runtime": "^7.13.10", + "@floating-ui/react-dom": "0.7.2", + "@radix-ui/react-arrow": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.0", + "@radix-ui/react-use-rect": "1.0.0", + "@radix-ui/react-use-size": "1.0.0", + "@radix-ui/rect": "1.0.0" + } + }, + "@radix-ui/react-portal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.1.tgz", + "integrity": "sha512-NY2vUWI5WENgAT1nfC6JS7RU5xRYBfjZVLq0HmgEN1Ezy3rk/UruMV4+Rd0F40PEaFC5SrLS1ixYvcYIQrb4Ig==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.1" + } + }, + "@radix-ui/react-presence": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.0.tgz", + "integrity": "sha512-A+6XEvN01NfVWiKu38ybawfHsBjWum42MRPnEuqPsBZ4eV7e/7K321B5VgYMPv3Xx5An6o1/l9ZuDBgmcmWK3w==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-use-layout-effect": "1.0.0" + } + }, + "@radix-ui/react-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.1.tgz", + "integrity": "sha512-fHbmislWVkZaIdeF6GZxF0A/NH/3BjrGIYj+Ae6eTmTCr7EB0RQAAVEiqsXK6p3/JcRqVSBQoceZroj30Jj3XA==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.1" + } + }, + "@radix-ui/react-roving-focus": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.1.tgz", + "integrity": "sha512-TB76u5TIxKpqMpUAuYH2VqMhHYKa+4Vs1NHygo/llLvlffN6mLVsFhz0AnSFlSBAvTBYVHYAkHAyEt7x1gPJOA==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-collection": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-direction": "1.0.0", + "@radix-ui/react-id": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-use-callback-ref": "1.0.0", + "@radix-ui/react-use-controllable-state": "1.0.0" + } + }, + "@radix-ui/react-slider": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.1.0.tgz", + "integrity": "sha512-5H/QB4xD3GF9UfoSCVLBx2JjlXamMcmTyL6gr4kkd/MiAGaYB0W7Exi4MQa0tJApBFJe+KmS5InKCI56p2kmjA==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/number": "1.0.0", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-collection": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-direction": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-use-controllable-state": "1.0.0", + "@radix-ui/react-use-layout-effect": "1.0.0", + "@radix-ui/react-use-previous": "1.0.0", + "@radix-ui/react-use-size": "1.0.0" + } + }, + "@radix-ui/react-slot": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.1.tgz", + "integrity": "sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0" + } + }, + "@radix-ui/react-tooltip": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.0.2.tgz", + "integrity": "sha512-11gUlok2rv5mu+KBtxniOKKNKjqC/uTbgFHWoQdbF46vMV+zjDaBvCtVDK9+MTddlpmlisGPGvvojX7Qm0yr+g==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-dismissable-layer": "1.0.2", + "@radix-ui/react-id": "1.0.0", + "@radix-ui/react-popper": "1.0.1", + "@radix-ui/react-portal": "1.0.1", + "@radix-ui/react-presence": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-slot": "1.0.1", + "@radix-ui/react-use-controllable-state": "1.0.0", + "@radix-ui/react-visually-hidden": "1.0.1" + } + }, + "@radix-ui/react-use-callback-ref": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.0.tgz", + "integrity": "sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-use-controllable-state": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.0.tgz", + "integrity": "sha512-FohDoZvk3mEXh9AWAVyRTYR4Sq7/gavuofglmiXB2g1aKyboUD4YtgWxKj8O5n+Uak52gXQ4wKz5IFST4vtJHg==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.0" + } + }, + "@radix-ui/react-use-escape-keydown": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.2.tgz", + "integrity": "sha512-DXGim3x74WgUv+iMNCF+cAo8xUHHeqvjx8zs7trKf+FkQKPQXLk2sX7Gx1ysH7Q76xCpZuxIJE7HLPxRE+Q+GA==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.0" + } + }, + "@radix-ui/react-use-layout-effect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.0.tgz", + "integrity": "sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-use-previous": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.0.0.tgz", + "integrity": "sha512-RG2K8z/K7InnOKpq6YLDmT49HGjNmrK+fr82UCVKT2sW0GYfVnYp4wZWBooT/EYfQ5faA9uIjvsuMMhH61rheg==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-use-rect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.0.0.tgz", + "integrity": "sha512-TB7pID8NRMEHxb/qQJpvSt3hQU4sqNPM1VCTjTRjEOa7cEop/QMuq8S6fb/5Tsz64kqSvB9WnwsDHtjnrM9qew==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/rect": "1.0.0" + } + }, + "@radix-ui/react-use-size": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.0.0.tgz", + "integrity": "sha512-imZ3aYcoYCKhhgNpkNDh/aTiU05qw9hX+HHI1QDBTyIlcFjgeFlKKySNGMwTp7nYFLQg/j0VA2FmCY4WPDDHMg==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-layout-effect": "1.0.0" + } + }, + "@radix-ui/react-visually-hidden": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.0.1.tgz", + "integrity": "sha512-K1hJcCMfWfiYUibRqf3V8r5Drpyf7rh44jnrwAbdvI5iCCijilBBeyQv9SKidYNZIopMdCyR9FnIjkHxHN0FcQ==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.1" + } + }, + "@radix-ui/rect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.0.0.tgz", + "integrity": "sha512-d0O68AYy/9oeEy1DdC07bz1/ZXX+DqCskRd3i4JzLSTXwefzaepQrKjXC7aNM8lTHjFLDO0pDgaEiQ7jEk+HVg==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@reduxjs/toolkit": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.8.5.tgz", + "integrity": "sha512-f4D5EXO7A7Xq35T0zRbWq5kJQyXzzscnHKmjnu2+37B3rwHU6mX9PYlbfXdnxcY6P/7zfmjhgan0Z+yuOfeBmA==", + "requires": { + "immer": "^9.0.7", + "redux": "^4.1.2", + "redux-thunk": "^2.4.1", + "reselect": "^4.1.5" + } + }, + "@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "dev": true, + "requires": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + } + }, + "@socket.io/component-emitter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" + }, + "@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" + }, + "@types/cors": { + "version": "2.8.12", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", + "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==" + }, + "@types/dateformat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/dateformat/-/dateformat-5.0.0.tgz", + "integrity": "sha512-SZg4JdHIWHQGEokbYGZSDvo5wA4TLYPXaqhigs/wH+REDOejcJzgH+qyY+HtEUtWOZxEUkbhbdYPqQDiEgrXeA==", + "dev": true + }, + "@types/eslint": { + "version": "8.4.6", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.6.tgz", + "integrity": "sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g==", + "dev": true, + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/estree": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", + "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==", + "dev": true + }, + "@types/hoist-non-react-statics": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", + "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", + "requires": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, + "@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, + "@types/lodash": { + "version": "4.14.185", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.185.tgz", + "integrity": "sha512-evMDG1bC4rgQg4ku9tKpuMh5iBNEwNa3tf9zRHdP1qlv+1WUg44xat4IxCE14gIpZRGUUWAx2VhItCZc25NfMA==" + }, + "@types/lodash.mergewith": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/@types/lodash.mergewith/-/lodash.mergewith-4.6.6.tgz", + "integrity": "sha512-RY/8IaVENjG19rxTZu9Nukqh0W2UrYgmBj5sdns4hWRZaV8PqR7wIKHFKzvOTjo4zVRV7sVI+yFhAJql12Kfqg==", + "requires": { + "@types/lodash": "*" + } + }, + "@types/node": { + "version": "18.8.3" + }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" + }, + "@types/prop-types": { + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + }, + "@types/react": { + "version": "18.0.20", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.20.tgz", + "integrity": "sha512-MWul1teSPxujEHVwZl4a5HxQ9vVNsjTchVA+xRqv/VYGCuKGAU6UhfrTdF5aBefwD1BHUD8i/zq+O/vyCm/FrA==", + "requires": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "@types/react-dom": { + "version": "18.0.6", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.6.tgz", + "integrity": "sha512-/5OFZgfIPSwy+YuIBP/FgJnQnsxhZhjjrnxudMddeblOouIodEQ75X14Rr4wGSG/bknL+Omy9iWlLo1u/9GzAA==", + "devOptional": true, + "requires": { + "@types/react": "*" + } + }, + "@types/react-reconciler": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.28.0.tgz", + "integrity": "sha512-5cjk9ottZAj7eaTsqzPUIlrVbh3hBAO2YaEL1rkjHKB3xNAId7oU8GhzvAX+gfmlfoxTwJnBjPxEHyxkEA1Ffg==", + "requires": { + "@types/react": "*" + } + }, + "@types/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, + "@types/scheduler": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" + }, + "@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" + }, + "@types/uuid": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==" + }, + "@typescript-eslint/eslint-plugin": { + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.37.0.tgz", + "integrity": "sha512-Fde6W0IafXktz1UlnhGkrrmnnGpAo1kyX7dnyHHVrmwJOn72Oqm3eYtddrpOwwel2W8PAK9F3pIL5S+lfoM0og==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.37.0", + "@typescript-eslint/type-utils": "5.37.0", + "@typescript-eslint/utils": "5.37.0", + "debug": "^4.3.4", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.2.0", + "regexpp": "^3.2.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "dependencies": { + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/parser": { + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.37.0.tgz", + "integrity": "sha512-01VzI/ipYKuaG5PkE5+qyJ6m02fVALmMPY3Qq5BHflDx3y4VobbLdHQkSMg9VPRS4KdNt4oYTMaomFoHonBGAw==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.37.0", + "@typescript-eslint/types": "5.37.0", + "@typescript-eslint/typescript-estree": "5.37.0", + "debug": "^4.3.4" + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.37.0.tgz", + "integrity": "sha512-F67MqrmSXGd/eZnujjtkPgBQzgespu/iCZ+54Ok9X5tALb9L2v3G+QBSoWkXG0p3lcTJsL+iXz5eLUEdSiJU9Q==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.37.0", + "@typescript-eslint/visitor-keys": "5.37.0" + } + }, + "@typescript-eslint/type-utils": { + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.37.0.tgz", + "integrity": "sha512-BSx/O0Z0SXOF5tY0bNTBcDEKz2Ec20GVYvq/H/XNKiUorUFilH7NPbFUuiiyzWaSdN3PA8JV0OvYx0gH/5aFAQ==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "5.37.0", + "@typescript-eslint/utils": "5.37.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/types": { + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.37.0.tgz", + "integrity": "sha512-3frIJiTa5+tCb2iqR/bf7XwU20lnU05r/sgPJnRpwvfZaqCJBrl8Q/mw9vr3NrNdB/XtVyMA0eppRMMBqdJ1bA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.37.0.tgz", + "integrity": "sha512-JkFoFIt/cx59iqEDSgIGnQpCTRv96MQnXCYvJi7QhBC24uyuzbD8wVbajMB1b9x4I0octYFJ3OwjAwNqk1AjDA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.37.0", + "@typescript-eslint/visitor-keys": "5.37.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "dependencies": { + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/utils": { + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.37.0.tgz", + "integrity": "sha512-jUEJoQrWbZhmikbcWSMDuUSxEE7ID2W/QCV/uz10WtQqfOuKZUqFGjqLJ+qhDd17rjgp+QJPqTdPIBWwoob2NQ==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.37.0", + "@typescript-eslint/types": "5.37.0", + "@typescript-eslint/typescript-estree": "5.37.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.37.0.tgz", + "integrity": "sha512-Hp7rT4cENBPIzMwrlehLW/28EVCOcE9U1Z1BQTc8EA8v5qpr7GRGuG+U58V5tTY48zvUOA3KHvw3rA8tY9fbdA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.37.0", + "eslint-visitor-keys": "^3.3.0" + } + }, + "@vitejs/plugin-react": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-2.1.0.tgz", + "integrity": "sha512-am6rPyyU3LzUYne3Gd9oj9c4Rzbq5hQnuGXSMT6Gujq45Il/+bunwq3lrB7wghLkiF45ygMwft37vgJ/NE8IAA==", + "dev": true, + "requires": { + "@babel/core": "^7.18.13", + "@babel/plugin-transform-react-jsx": "^7.18.10", + "@babel/plugin-transform-react-jsx-development": "^7.18.6", + "@babel/plugin-transform-react-jsx-self": "^7.18.6", + "@babel/plugin-transform-react-jsx-source": "^7.18.6", + "magic-string": "^0.26.2", + "react-refresh": "^0.14.0" + } + }, + "@zag-js/element-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@zag-js/element-size/-/element-size-0.1.0.tgz", + "integrity": "sha512-QF8wp0+V8++z+FHXiIw93+zudtubYszOtYbNgK39fg3pi+nCZtuSm4L1jC5QZMatNZ83MfOzyNCfgUubapagJQ==" + }, + "@zag-js/focus-visible": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@zag-js/focus-visible/-/focus-visible-0.1.0.tgz", + "integrity": "sha512-PeaBcTmdZWcFf7n1aM+oiOdZc+sy14qi0emPIeUuGMTjbP0xLGrZu43kdpHnWSXy7/r4Ubp/vlg50MCV8+9Isg==" + }, + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, + "acorn": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "requires": {} + }, + "add": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/add/-/add-2.0.6.tgz", + "integrity": "sha512-j5QzrmsokwWWp6kUcJQySpbG+xfOBqqKnup3OIk1pz+kB/80SLorZ9V8zHFLO92Lcd+hbvq8bT+zOGoPkmBV0Q==" + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "aria-hidden": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.1.tgz", + "integrity": "sha512-PN344VAf9j1EAi+jyVHOJ8XidQdPVssGco39eNcsGdM4wcsILtxrKLkbuiMfLWYROK1FjRQasMWCBttrhjnr6A==", + "requires": { + "tslib": "^2.0.0" + } + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "attr-accept": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz", + "integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==" + }, + "babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "requires": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browserslist": { + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "requires": { + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + }, + "caniuse-lite": { + "version": "1.0.30001402", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001402.tgz", + "integrity": "sha512-Mx4MlhXO5NwuvXGgVb+hg65HZ+bhUYsz8QtDGDo2QmaJS2GBX47Xfi2koL86lc8K+l+htXeTEB/Aeqvezoo6Ew==" + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + } + } + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "compute-scroll-into-view": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.14.tgz", + "integrity": "sha512-mKDjINe3tc6hGelUMNDzuhorIUZ7kS7BwyY0r2wQd2HOH2tRuJykiC06iSEX8y1TuhNzvz4GcJnK16mM2J1NMQ==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" + }, + "copy-to-clipboard": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz", + "integrity": "sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==", + "requires": { + "toggle-selection": "^1.0.6" + } + }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "cosmiconfig": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", + "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "css-box-model": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz", + "integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==", + "requires": { + "tiny-invariant": "^1.0.6" + } + }, + "csstype": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", + "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" + }, + "dateformat": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-5.0.3.tgz", + "integrity": "sha512-Kvr6HmPXUMerlLcLF+Pwq3K7apHpYmGDVqrxcDasBg86UcKeTSNWbEzU8bwdXnxnR44FtMhJAxI4Bov6Y/KUfA==" + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "requires": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true + }, + "electron-to-chromium": { + "version": "1.4.253", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.253.tgz", + "integrity": "sha512-1pezJ2E1UyBTGbA7fUlHdPSXQw1k+82VhTFLG5G0AUqLGvsZqFzleOblceqegZzxYX4kC7hGEEdzIQI9RZ1Cuw==" + }, + "engine.io": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.0.tgz", + "integrity": "sha512-4KzwW3F3bk+KlzSOY57fj/Jx6LyRQ1nbcyIadehl+AnXjKT7gDO0ORdRi/84ixvMKTym6ZKuxvbzN62HDDU1Lg==", + "requires": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.0.3", + "ws": "~8.2.3" + } + }, + "engine.io-client": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.2.2.tgz", + "integrity": "sha512-8ZQmx0LQGRTYkHuogVZuGSpDqYZtCM/nv8zQ68VZ+JkOpazJ7ICdsSpaO6iXwvaU30oFg5QJOJWj8zWqhbKjkQ==", + "requires": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.0.3", + "ws": "~8.2.3", + "xmlhttprequest-ssl": "~2.0.0" + } + }, + "engine.io-parser": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz", + "integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==" + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "esbuild": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.7.tgz", + "integrity": "sha512-7V8tzllIbAQV1M4QoE52ImKu8hT/NLGlGXkiDsbEU5PS6K8Mn09ZnYoS+dcmHxOS9CRsV4IRAMdT3I67IyUNXw==", + "dev": true, + "requires": { + "@esbuild/linux-loong64": "0.15.7", + "esbuild-android-64": "0.15.7", + "esbuild-android-arm64": "0.15.7", + "esbuild-darwin-64": "0.15.7", + "esbuild-darwin-arm64": "0.15.7", + "esbuild-freebsd-64": "0.15.7", + "esbuild-freebsd-arm64": "0.15.7", + "esbuild-linux-32": "0.15.7", + "esbuild-linux-64": "0.15.7", + "esbuild-linux-arm": "0.15.7", + "esbuild-linux-arm64": "0.15.7", + "esbuild-linux-mips64le": "0.15.7", + "esbuild-linux-ppc64le": "0.15.7", + "esbuild-linux-riscv64": "0.15.7", + "esbuild-linux-s390x": "0.15.7", + "esbuild-netbsd-64": "0.15.7", + "esbuild-openbsd-64": "0.15.7", + "esbuild-sunos-64": "0.15.7", + "esbuild-windows-32": "0.15.7", + "esbuild-windows-64": "0.15.7", + "esbuild-windows-arm64": "0.15.7" + } + }, + "esbuild-darwin-arm64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.7.tgz", + "integrity": "sha512-kBIHvtVqbSGajN88lYMnR3aIleH3ABZLLFLxwL2stiuIGAjGlQW741NxVTpUHQXUmPzxi6POqc9npkXa8AcSZQ==", + "dev": true, + "optional": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + }, + "eslint": { + "version": "8.23.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.1.tgz", + "integrity": "sha512-w7C1IXCc6fNqjpuYd0yPlcTKKmHlHHktRkzmBPZ+7cvNBQuiNjx0xaMTjAJGCafJhQkrFJooREv0CtrVzmHwqg==", + "dev": true, + "requires": { + "@eslint/eslintrc": "^1.3.2", + "@humanwhocodes/config-array": "^0.10.4", + "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@humanwhocodes/module-importer": "^1.0.1", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.1", + "globals": "^13.15.0", + "globby": "^11.1.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "globals": { + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "eslint-plugin-prettier": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", + "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-plugin-react-hooks": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "dev": true, + "requires": {} + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true + }, + "espree": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", + "dev": true, + "requires": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + } + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "event-stream": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", + "integrity": "sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==", + "dev": true, + "requires": { + "duplexer": "~0.1.1", + "from": "~0", + "map-stream": "~0.1.0", + "pause-stream": "0.0.11", + "split": "0.3", + "stream-combiner": "~0.0.4", + "through": "~2.3.1" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "file-selector": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.6.0.tgz", + "integrity": "sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==", + "requires": { + "tslib": "^2.4.0" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, + "focus-lock": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-0.11.2.tgz", + "integrity": "sha512-pZ2bO++NWLHhiKkgP1bEXHhR1/OjVcSvlCJ98aNJDFeb7H5OOQaO+SKOZle6041O9rv2tmbrO4JzClAvDUHf0g==", + "requires": { + "tslib": "^2.0.3" + } + }, + "framer-motion": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-7.3.5.tgz", + "integrity": "sha512-JrLLVCi59LMI3+ZvSSbxf/Z7SOIdYRZrgdkUvJkzyT2RXu34HtGy26n41jNrcD5K85boqlZhGTbfqnAIfMHRLQ==", + "requires": { + "@emotion/is-prop-valid": "^0.8.2", + "@motionone/dom": "10.13.1", + "framesync": "6.1.2", + "hey-listen": "^1.0.8", + "popmotion": "11.0.5", + "style-value-types": "5.1.2", + "tslib": "2.4.0" + }, + "dependencies": { + "@emotion/is-prop-valid": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", + "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", + "optional": true, + "requires": { + "@emotion/memoize": "0.7.4" + } + }, + "@emotion/memoize": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", + "optional": true + }, + "framesync": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/framesync/-/framesync-6.1.2.tgz", + "integrity": "sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g==", + "requires": { + "tslib": "2.4.0" + } + } + } + }, + "framesync": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/framesync/-/framesync-5.3.0.tgz", + "integrity": "sha512-oc5m68HDO/tuK2blj7ZcdEBRx3p1PjrgHazL8GYEpvULhrtGIFbQArN6cQS2QhW8mitffaB+VYzMjDqBxxQeoA==", + "requires": { + "tslib": "^2.1.0" + } + }, + "from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" + }, + "get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==" + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "hey-listen": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz", + "integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==" + }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + } + }, + "hotkeys-js": { + "version": "3.9.4", + "resolved": "https://registry.npmjs.org/hotkeys-js/-/hotkeys-js-3.9.4.tgz", + "integrity": "sha512-2zuLt85Ta+gIyvs4N88pCYskNrxf1TFv3LR9t5mdAZIX8BcgQQ48F2opUptvHa6m8zsy5v/a0i9mWzTrlNWU0Q==" + }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + }, + "immer": { + "version": "9.0.15", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.15.tgz", + "integrity": "sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ==" + }, + "immutable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", + "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "requires": { + "loose-envify": "^1.0.0" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "requires": { + "has": "^1.0.3" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "its-fine": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/its-fine/-/its-fine-1.0.6.tgz", + "integrity": "sha512-VZJZPwVT2kxe5KQv+TxCjojfLiUIut8zXDNLTxcM7gJ/xQ/bSPk5M0neZ+j3myy45KKkltY1mm1jyJgx3Fxsdg==", + "requires": { + "@types/react-reconciler": "^0.28.0" + } + }, + "js-sdsl": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz", + "integrity": "sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "json5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==" + }, + "konva": { + "version": "8.3.13", + "resolved": "https://registry.npmjs.org/konva/-/konva-8.3.13.tgz", + "integrity": "sha512-O5VxHfRfTj4PscTglQH1NimS8+CC5hQYLeB8YQstu8MN/i2L8GjA1T9d7xxzITF2TD5+xcIs5ei7en3cztbNXg==" + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==" + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "magic-string": { + "version": "0.26.3", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.3.tgz", + "integrity": "sha512-u1Po0NDyFcwdg2nzHT88wSK0+Rih0N1M+Ph1Sp08k8yvFFU3KR72wryS7e1qMPJypt99WB7fIFVCA92mQrMjrg==", + "dev": true, + "requires": { + "sourcemap-codec": "^1.4.8" + } + }, + "map-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", + "integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" + }, + "node-cleanup": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/node-cleanup/-/node-cleanup-2.1.2.tgz", + "integrity": "sha512-qN8v/s2PAJwGUtr1/hYTpNKlD6Y9rc4p8KSmJXyGdYGZsDGKXrGThikLFP9OCHFeLeEpQzPwiAtdIvBLqm//Hw==", + "dev": true + }, + "node-releases": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + }, + "pause-stream": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", + "dev": true, + "requires": { + "through": "~2.3" + } + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "popmotion": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/popmotion/-/popmotion-11.0.5.tgz", + "integrity": "sha512-la8gPM1WYeFznb/JqF4GiTkRRPZsfaj2+kCxqQgr2MJylMmIKUwBfWW8Wa5fml/8gmtlD5yI01MP1QCZPWmppA==", + "requires": { + "framesync": "6.1.2", + "hey-listen": "^1.0.8", + "style-value-types": "5.1.2", + "tslib": "2.4.0" + }, + "dependencies": { + "framesync": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/framesync/-/framesync-6.1.2.tgz", + "integrity": "sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g==", + "requires": { + "tslib": "2.4.0" + } + } + } + }, + "postcss": { + "version": "8.4.16", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz", + "integrity": "sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==", + "dev": true, + "requires": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "prettier": { + "version": "2.7.1", + "dev": true, + "peer": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, + "prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "ps-tree": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz", + "integrity": "sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==", + "dev": true, + "requires": { + "event-stream": "=3.3.4" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "re-resizable": { + "version": "6.9.9", + "resolved": "https://registry.npmjs.org/re-resizable/-/re-resizable-6.9.9.tgz", + "integrity": "sha512-l+MBlKZffv/SicxDySKEEh42hR6m5bAHfNu3Tvxks2c4Ah+ldnWjfnVRwxo/nxF27SsUsxDS0raAzFuJNKABXA==", + "requires": {} + }, + "react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "requires": { + "loose-envify": "^1.1.0" + } + }, + "react-clientside-effect": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/react-clientside-effect/-/react-clientside-effect-1.2.6.tgz", + "integrity": "sha512-XGGGRQAKY+q25Lz9a/4EPqom7WRjz3z9R2k4jhVKA/puQFH/5Nt27vFZYql4m4NVNdUvX8PS3O7r/Zzm7cjUlg==", + "requires": { + "@babel/runtime": "^7.12.13" + } + }, + "react-colorful": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/react-colorful/-/react-colorful-5.6.1.tgz", + "integrity": "sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==", + "requires": {} + }, + "react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "requires": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + } + }, + "react-dropzone": { + "version": "14.2.2", + "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.2.2.tgz", + "integrity": "sha512-5oyGN/B5rNhop2ggUnxztXBQ6q6zii+OMEftPzsxAR2hhpVWz0nAV+3Ktxo2h5bZzdcCKrpd8bfWAVsveIBM+w==", + "requires": { + "attr-accept": "^2.2.2", + "file-selector": "^0.6.0", + "prop-types": "^15.8.1" + } + }, + "react-fast-compare": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", + "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" + }, + "react-focus-lock": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.9.1.tgz", + "integrity": "sha512-pSWOQrUmiKLkffPO6BpMXN7SNKXMsuOakl652IBuALAu1esk+IcpJyM+ALcYzPTTFz1rD0R54aB9A4HuP5t1Wg==", + "requires": { + "@babel/runtime": "^7.0.0", + "focus-lock": "^0.11.2", + "prop-types": "^15.6.2", + "react-clientside-effect": "^1.2.6", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + } + }, + "react-hotkeys-hook": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/react-hotkeys-hook/-/react-hotkeys-hook-3.4.7.tgz", + "integrity": "sha512-+bbPmhPAl6ns9VkXkNNyxlmCAIyDAcWbB76O4I0ntr3uWCRuIQf/aRLartUahe9chVMPj+OEzzfk3CQSjclUEQ==", + "requires": { + "hotkeys-js": "3.9.4" + } + }, + "react-icons": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.4.0.tgz", + "integrity": "sha512-fSbvHeVYo/B5/L4VhB7sBA1i2tS8MkT0Hb9t2H1AVPkwGfVHLJCqyr2Py9dKMxsyM63Eng1GkdZfbWj+Fmv8Rg==", + "requires": {} + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "react-konva": { + "version": "18.2.3", + "resolved": "https://registry.npmjs.org/react-konva/-/react-konva-18.2.3.tgz", + "integrity": "sha512-OPxjBTgaEGU9pt/VJSVM7QNXYHEZ5CkulX+4fTTvbaH+Wh+vMLbXmH3yjWw4kT/5Qi6t0UQKHPPmirCv8/9sdg==", + "requires": { + "its-fine": "^1.0.6", + "react-reconciler": "~0.29.0", + "scheduler": "^0.23.0" + } + }, + "react-reconciler": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.29.0.tgz", + "integrity": "sha512-wa0fGj7Zht1EYMRhKWwoo1H9GApxYLBuhoAuXN0TlltESAjDssB+Apf0T/DngVqaMyPypDmabL37vw/2aRM98Q==", + "requires": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + } + }, + "react-redux": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.2.tgz", + "integrity": "sha512-nBwiscMw3NoP59NFCXFf02f8xdo+vSHT/uZ1ldDwF7XaTpzm+Phk97VT4urYBl5TYAPNVaFm12UHAEyzkpNzRA==", + "requires": { + "@babel/runtime": "^7.12.1", + "@types/hoist-non-react-statics": "^3.3.1", + "@types/use-sync-external-store": "^0.0.3", + "hoist-non-react-statics": "^3.3.2", + "react-is": "^18.0.0", + "use-sync-external-store": "^1.0.0" + }, + "dependencies": { + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } + } + }, + "react-refresh": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", + "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", + "dev": true + }, + "react-remove-scroll": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz", + "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==", + "requires": { + "react-remove-scroll-bar": "^2.3.3", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + } + }, + "react-remove-scroll-bar": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.3.tgz", + "integrity": "sha512-i9GMNWwpz8XpUpQ6QlevUtFjHGqnPG4Hxs+wlIJntu/xcsZVEpJcIV71K3ZkqNy2q3GfgvkD7y6t/Sv8ofYSbw==", + "requires": { + "react-style-singleton": "^2.2.1", + "tslib": "^2.0.0" + } + }, + "react-style-singleton": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", + "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", + "requires": { + "get-nonce": "^1.0.0", + "invariant": "^2.2.4", + "tslib": "^2.0.0" + } + }, + "react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "requires": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "redux": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.0.tgz", + "integrity": "sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA==", + "requires": { + "@babel/runtime": "^7.9.2" + } + }, + "redux-persist": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-6.0.0.tgz", + "integrity": "sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ==", + "requires": {} + }, + "redux-thunk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.1.tgz", + "integrity": "sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q==", + "requires": {} + }, + "regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, + "reselect": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.6.tgz", + "integrity": "sha512-ZovIuXqto7elwnxyXbBtCPo9YFEr3uJqj2rRbcOOog1bmu2Ag85M4hixSwFWyaBMKXNgvPaJ9OSu9SkBPIeJHQ==" + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "rollup": { + "version": "2.78.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.78.1.tgz", + "integrity": "sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg==", + "dev": true, + "requires": { + "fsevents": "~2.3.2" + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "sass": { + "version": "1.55.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.55.0.tgz", + "integrity": "sha512-Pk+PMy7OGLs9WaxZGJMn7S96dvlyVBwwtToX895WmCpAOr5YiJYEUJfiJidMuKb613z2xNWcXCHEuOvjZbqC6A==", + "dev": true, + "requires": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + } + }, + "scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "requires": { + "loose-envify": "^1.1.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "socket.io": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.2.tgz", + "integrity": "sha512-6fCnk4ARMPZN448+SQcnn1u8OHUC72puJcNtSgg2xS34Cu7br1gQ09YKkO1PFfDn/wyUE9ZgMAwosJed003+NQ==", + "requires": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "debug": "~4.3.2", + "engine.io": "~6.2.0", + "socket.io-adapter": "~2.4.0", + "socket.io-parser": "~4.2.0" + } + }, + "socket.io-adapter": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz", + "integrity": "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg==" + }, + "socket.io-client": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.5.2.tgz", + "integrity": "sha512-naqYfFu7CLDiQ1B7AlLhRXKX3gdeaIMfgigwavDzgJoIUYulc1qHH5+2XflTsXTPY7BlPH5rppJyUjhjrKQKLg==", + "requires": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.2.1", + "socket.io-parser": "~4.2.0" + } + }, + "socket.io-parser": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz", + "integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==", + "requires": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" + }, + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true + }, + "sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "dev": true + }, + "split": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", + "integrity": "sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==", + "dev": true, + "requires": { + "through": "2" + } + }, + "stream-combiner": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", + "integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==", + "dev": true, + "requires": { + "duplexer": "~0.1.1" + } + }, + "string-argv": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.1.2.tgz", + "integrity": "sha512-mBqPGEOMNJKXRo7z0keX0wlAhbBAjilUdPW13nN0PecVryZxdHIeM7TqbsSUA7VYuS00HGC6mojP7DlQzfa9ZA==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "style-value-types": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/style-value-types/-/style-value-types-5.1.2.tgz", + "integrity": "sha512-Vs9fNreYF9j6W2VvuDTP7kepALi7sk0xtk2Tu8Yxi9UoajJdEVpNpCov0HsLTqXvNGKX+Uv09pkozVITi1jf3Q==", + "requires": { + "hey-listen": "^1.0.8", + "tslib": "2.4.0" + } + }, + "stylis": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz", + "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "tiny-invariant": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.2.0.tgz", + "integrity": "sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg==" + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" + }, + "tsc-watch": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/tsc-watch/-/tsc-watch-5.0.3.tgz", + "integrity": "sha512-Hz2UawwELMSLOf0xHvAFc7anLeMw62cMVXr1flYmhRuOhOyOljwmb1l/O60ZwRyy1k7N1iC1mrn1QYM2zITfuw==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "node-cleanup": "^2.1.2", + "ps-tree": "^1.2.0", + "string-argv": "^0.1.1", + "strip-ansi": "^6.0.0" + } + }, + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } + } + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "typescript": { + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.3.tgz", + "integrity": "sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==", + "dev": true + }, + "update-browserslist-db": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz", + "integrity": "sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg==", + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "use-callback-ref": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.0.tgz", + "integrity": "sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==", + "requires": { + "tslib": "^2.0.0" + } + }, + "use-isomorphic-layout-effect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", + "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", + "requires": {} + }, + "use-sidecar": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", + "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", + "requires": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + } + }, + "use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "requires": {} + }, + "uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" + }, + "vite": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-3.1.1.tgz", + "integrity": "sha512-hgxQWev/AL7nWYrqByYo8nfcH9n97v6oFsta9+JX8h6cEkni7nHKP2kJleNYV2kcGhE8jsbaY1aStwPZXzPbgA==", + "dev": true, + "requires": { + "esbuild": "^0.15.6", + "fsevents": "~2.3.2", + "postcss": "^8.4.16", + "resolve": "^1.22.1", + "rollup": "~2.78.0" + } + }, + "vite-plugin-eslint": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/vite-plugin-eslint/-/vite-plugin-eslint-1.8.1.tgz", + "integrity": "sha512-PqdMf3Y2fLO9FsNPmMX+//2BF5SF8nEWspZdgl4kSt7UvHDRHVVfHvxsD7ULYzZrJDGRxR81Nq7TOFgwMnUang==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^4.2.1", + "@types/eslint": "^8.4.5", + "rollup": "^2.77.2" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "ws": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "requires": {} + }, + "xmlhttprequest-ssl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", + "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==" + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" + }, + "yarn": { + "version": "1.22.19", + "resolved": "https://registry.npmjs.org/yarn/-/yarn-1.22.19.tgz", + "integrity": "sha512-/0V5q0WbslqnwP91tirOvldvYISzaqhClxzyUKXYxs07yUILIs5jx/k6CFe8bvKSkds5w+eiOqta39Wk3WxdcQ==" + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + } + } +} diff --git a/frontend/package.json b/frontend/package.json new file mode 100644 index 0000000000..5d9b7d72f8 --- /dev/null +++ b/frontend/package.json @@ -0,0 +1,60 @@ +{ + "name": "invoke-ai-ui", + "private": true, + "version": "0.0.1", + "type": "module", + "scripts": { + "dev": "vite dev", + "build": "tsc && vite build", + "build-dev": "tsc && vite build -m development", + "preview": "vite preview" + }, + "dependencies": { + "@chakra-ui/icons": "^2.0.10", + "@chakra-ui/react": "^2.3.1", + "@emotion/react": "^11.10.4", + "@emotion/styled": "^11.10.4", + "@radix-ui/react-context-menu": "^2.0.1", + "@radix-ui/react-slider": "^1.1.0", + "@radix-ui/react-tooltip": "^1.0.2", + "@reduxjs/toolkit": "^1.8.5", + "@types/uuid": "^8.3.4", + "add": "^2.0.6", + "dateformat": "^5.0.3", + "framer-motion": "^7.2.1", + "konva": "^8.3.13", + "lodash": "^4.17.21", + "re-resizable": "^6.9.9", + "react": "^18.2.0", + "react-colorful": "^5.6.1", + "react-dom": "^18.2.0", + "react-dropzone": "^14.2.2", + "react-hotkeys-hook": "^3.4.7", + "react-icons": "^4.4.0", + "react-konva": "^18.2.3", + "react-redux": "^8.0.2", + "react-transition-group": "^4.4.5", + "redux-persist": "^6.0.0", + "socket.io": "^4.5.2", + "socket.io-client": "^4.5.2", + "uuid": "^9.0.0", + "yarn": "^1.22.19" + }, + "devDependencies": { + "@types/dateformat": "^5.0.0", + "@types/react": "^18.0.17", + "@types/react-dom": "^18.0.6", + "@types/react-transition-group": "^4.4.5", + "@typescript-eslint/eslint-plugin": "^5.36.2", + "@typescript-eslint/parser": "^5.36.2", + "@vitejs/plugin-react": "^2.0.1", + "eslint": "^8.23.0", + "eslint-plugin-prettier": "^4.2.1", + "eslint-plugin-react-hooks": "^4.6.0", + "sass": "^1.55.0", + "tsc-watch": "^5.0.3", + "typescript": "^4.6.4", + "vite": "^3.0.7", + "vite-plugin-eslint": "^1.8.1" + } +} diff --git a/frontend/src/Loading.tsx b/frontend/src/Loading.tsx new file mode 100644 index 0000000000..83dba59fc4 --- /dev/null +++ b/frontend/src/Loading.tsx @@ -0,0 +1,22 @@ +import { Flex, Spinner } from '@chakra-ui/react'; + +const Loading = () => { + return ( + + + + ); +}; + +export default Loading; diff --git a/frontend/src/app/App.scss b/frontend/src/app/App.scss new file mode 100644 index 0000000000..84c76fd065 --- /dev/null +++ b/frontend/src/app/App.scss @@ -0,0 +1,17 @@ +@use '../styles/Mixins/' as *; + +.App { + display: grid; + width: 100vw; + height: 100vh; + background-color: var(--background-color); +} + +.app-content { + display: grid; + row-gap: 1rem; + padding: $app-padding; + grid-auto-rows: min-content auto; + width: $app-width; + height: $app-height; +} diff --git a/frontend/src/app/App.tsx b/frontend/src/app/App.tsx new file mode 100644 index 0000000000..71b001e9b0 --- /dev/null +++ b/frontend/src/app/App.tsx @@ -0,0 +1,106 @@ +import { useEffect } from 'react'; +import ProgressBar from '../features/system/ProgressBar'; +import SiteHeader from '../features/system/SiteHeader'; +import Console from '../features/system/Console'; +import { useAppDispatch } from './store'; +import { requestSystemConfig } from './socketio/actions'; +import { keepGUIAlive } from './utils'; +import InvokeTabs from '../features/tabs/InvokeTabs'; +import ImageUploader from '../common/components/ImageUploader'; +import { RootState, useAppSelector } from '../app/store'; + +import FloatingGalleryButton from '../features/tabs/FloatingGalleryButton'; +import FloatingOptionsPanelButtons from '../features/tabs/FloatingOptionsPanelButtons'; +import { createSelector } from '@reduxjs/toolkit'; +import { GalleryState } from '../features/gallery/gallerySlice'; +import { OptionsState } from '../features/options/optionsSlice'; +import { activeTabNameSelector } from '../features/options/optionsSelectors'; +import { SystemState } from '../features/system/systemSlice'; +import _ from 'lodash'; +import { Model } from './invokeai'; + +keepGUIAlive(); + +const appSelector = createSelector( + [ + (state: RootState) => state.gallery, + (state: RootState) => state.options, + (state: RootState) => state.system, + activeTabNameSelector, + ], + ( + gallery: GalleryState, + options: OptionsState, + system: SystemState, + activeTabName + ) => { + const { shouldShowGallery, shouldHoldGalleryOpen, shouldPinGallery } = + gallery; + const { + shouldShowOptionsPanel, + shouldHoldOptionsPanelOpen, + shouldPinOptionsPanel, + } = options; + + const modelStatusText = _.reduce( + system.model_list, + (acc: string, cur: Model, key: string) => { + if (cur.status === 'active') acc = key; + return acc; + }, + '' + ); + + const shouldShowGalleryButton = !( + shouldShowGallery || + (shouldHoldGalleryOpen && !shouldPinGallery) + ); + + const shouldShowOptionsPanelButton = + !( + shouldShowOptionsPanel || + (shouldHoldOptionsPanelOpen && !shouldPinOptionsPanel) + ) && ['txt2img', 'img2img', 'inpainting'].includes(activeTabName); + + return { + modelStatusText, + shouldShowGalleryButton, + shouldShowOptionsPanelButton, + }; + }, + { + memoizeOptions: { + resultEqualityCheck: _.isEqual, + }, + } +); + +const App = () => { + const dispatch = useAppDispatch(); + + const { shouldShowGalleryButton, shouldShowOptionsPanelButton } = + useAppSelector(appSelector); + + useEffect(() => { + dispatch(requestSystemConfig()); + }, [dispatch]); + + return ( +
+ + +
+ + +
+
+ +
+ {shouldShowGalleryButton && } + {shouldShowOptionsPanelButton && } +
+
+ ); +}; + +export default App; diff --git a/frontend/src/app/constants.ts b/frontend/src/app/constants.ts new file mode 100644 index 0000000000..bd457dc7fb --- /dev/null +++ b/frontend/src/app/constants.ts @@ -0,0 +1,50 @@ +// TODO: use Enums? + +import { InProgressImageType } from '../features/system/systemSlice'; + +// Valid samplers +export const SAMPLERS: Array = [ + 'ddim', + 'plms', + 'k_lms', + 'k_dpm_2', + 'k_dpm_2_a', + 'k_euler', + 'k_euler_a', + 'k_heun', +]; + +// Valid image widths +export const WIDTHS: Array = [ + 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, + 1856, 1920, 1984, 2048, +]; + +// Valid image heights +export const HEIGHTS: Array = [ + 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, + 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, + 1856, 1920, 1984, 2048, +]; + +// Valid upscaling levels +export const UPSCALING_LEVELS: Array<{ key: string; value: number }> = [ + { key: '2x', value: 2 }, + { key: '4x', value: 4 }, +]; + +export const NUMPY_RAND_MIN = 0; + +export const NUMPY_RAND_MAX = 4294967295; + +export const FACETOOL_TYPES = ['gfpgan', 'codeformer'] as const; + +export const IN_PROGRESS_IMAGE_TYPES: Array<{ + key: string; + value: InProgressImageType; +}> = [ + { key: 'None', value: 'none' }, + { key: 'Fast', value: 'latents' }, + { key: 'Accurate', value: 'full-res' }, +]; diff --git a/frontend/src/app/contexts/ImageUploaderTriggerContext.ts b/frontend/src/app/contexts/ImageUploaderTriggerContext.ts new file mode 100644 index 0000000000..804e124625 --- /dev/null +++ b/frontend/src/app/contexts/ImageUploaderTriggerContext.ts @@ -0,0 +1,8 @@ +import { createContext } from 'react'; + +type VoidFunc = () => void; + +type ImageUploaderTriggerContextType = VoidFunc | null; + +export const ImageUploaderTriggerContext = + createContext(null); diff --git a/frontend/src/app/features.ts b/frontend/src/app/features.ts new file mode 100644 index 0000000000..361c8356dc --- /dev/null +++ b/frontend/src/app/features.ts @@ -0,0 +1,62 @@ +type FeatureHelpInfo = { + text: string; + href: string; + guideImage: string; +}; + +export enum Feature { + PROMPT, + GALLERY, + OTHER, + SEED, + VARIATIONS, + UPSCALE, + FACE_CORRECTION, + IMAGE_TO_IMAGE, +} +/** For each tooltip in the UI, the below feature definitions & props will pull relevant information into the tooltip. + * + * To-do: href & GuideImages are placeholders, and are not currently utilized, but will be updated (along with the tooltip UI) as feature and UI development and we get a better idea on where things "forever homes" will be . + */ +export const FEATURES: Record = { + [Feature.PROMPT]: { + text: 'This field will take all prompt text, including both content and stylistic terms. While weights can be included in the prompt, standard CLI Commands/parameters will not work.', + href: 'link/to/docs/feature3.html', + guideImage: 'asset/path.gif', + }, + [Feature.GALLERY]: { + text: 'As new invocations are generated, files from the output directory will be displayed here. Generations have additional options to configure new generations.', + href: 'link/to/docs/feature3.html', + guideImage: 'asset/path.gif', + }, + [Feature.OTHER]: { + text: 'These options will enable alternative processing modes for Invoke. Seamless tiling will work to generate repeating patterns in the output. High Resolution Optimization performs a two-step generation cycle, and should be used at higher resolutions when you desire a more coherent image/composition. ', + href: 'link/to/docs/feature3.html', + guideImage: 'asset/path.gif', + }, + [Feature.SEED]: { + text: 'Seed values provide an initial set of noise which guide the denoising process, and can be randomized or populated with a seed from a previous invocation. The Threshold feature can be used to mitigate undesirable outcomes at higher CFG values (try between 0-10), and Perlin can be used to add Perlin noise into the denoising process - Both serve to add variation to your outputs. ', + href: 'link/to/docs/feature3.html', + guideImage: 'asset/path.gif', + }, + [Feature.VARIATIONS]: { + text: 'Try a variation with an amount of between 0 and 1 to change the output image for the set seed - Interesting variations on the seed are found between 0.1 and 0.3.', + href: 'link/to/docs/feature3.html', + guideImage: 'asset/path.gif', + }, + [Feature.UPSCALE]: { + text: 'Using ESRGAN you can increase the output resolution without requiring a higher width/height in the initial generation.', + href: 'link/to/docs/feature1.html', + guideImage: 'asset/path.gif', + }, + [Feature.FACE_CORRECTION]: { + text: 'Using GFPGAN or Codeformer, Face Correction will attempt to identify faces in outputs, and correct any defects/abnormalities. Higher strength values will apply a stronger corrective pressure on outputs, resulting in more appealing faces. With Codeformer, a higher fidelity will attempt to preserve the original image, at the expense of face correction strength.', + href: 'link/to/docs/feature3.html', + guideImage: 'asset/path.gif', + }, + [Feature.IMAGE_TO_IMAGE]: { + text: 'ImageToImage allows the upload of an initial image, which InvokeAI will use to guide the generation process, along with a prompt. A lower value for this setting will more closely resemble the original image. Values between 0-1 are accepted, and a range of .25-.75 is recommended ', + href: 'link/to/docs/feature3.html', + guideImage: 'asset/path.gif', + }, +}; diff --git a/frontend/src/app/invokeai.d.ts b/frontend/src/app/invokeai.d.ts new file mode 100644 index 0000000000..0a263e2799 --- /dev/null +++ b/frontend/src/app/invokeai.d.ts @@ -0,0 +1,206 @@ +/** + * Types for images, the things they are made of, and the things + * they make up. + * + * Generated images are txt2img and img2img images. They may have + * had additional postprocessing done on them when they were first + * generated. + * + * Postprocessed images are images which were not generated here + * but only postprocessed by the app. They only get postprocessing + * metadata and have a different image type, e.g. 'esrgan' or + * 'gfpgan'. + */ + +import { Category as GalleryCategory } from '../features/gallery/gallerySlice'; + +/** + * TODO: + * Once an image has been generated, if it is postprocessed again, + * additional postprocessing steps are added to its postprocessing + * array. + * + * TODO: Better documentation of types. + */ + +export declare type PromptItem = { + prompt: string; + weight: number; +}; + +export declare type Prompt = Array; + +export declare type SeedWeightPair = { + seed: number; + weight: number; +}; + +export declare type SeedWeights = Array; + +// All generated images contain these metadata. +export declare type CommonGeneratedImageMetadata = { + postprocessing: null | Array; + sampler: + | 'ddim' + | 'k_dpm_2_a' + | 'k_dpm_2' + | 'k_euler_a' + | 'k_euler' + | 'k_heun' + | 'k_lms' + | 'plms'; + prompt: Prompt; + seed: number; + variations: SeedWeights; + steps: number; + cfg_scale: number; + width: number; + height: number; + seamless: boolean; + hires_fix: boolean; + extra: null | Record; // Pending development of RFC #266 +}; + +// txt2img and img2img images have some unique attributes. +export declare type Txt2ImgMetadata = GeneratedImageMetadata & { + type: 'txt2img'; +}; + +export declare type Img2ImgMetadata = GeneratedImageMetadata & { + type: 'img2img'; + orig_hash: string; + strength: number; + fit: boolean; + init_image_path: string; + mask_image_path?: string; +}; + +// Superset of generated image metadata types. +export declare type GeneratedImageMetadata = Txt2ImgMetadata | Img2ImgMetadata; + +// All post processed images contain these metadata. +export declare type CommonPostProcessedImageMetadata = { + orig_path: string; + orig_hash: string; +}; + +// esrgan and gfpgan images have some unique attributes. +export declare type ESRGANMetadata = CommonPostProcessedImageMetadata & { + type: 'esrgan'; + scale: 2 | 4; + strength: number; +}; + +export declare type FacetoolMetadata = CommonPostProcessedImageMetadata & { + type: 'gfpgan' | 'codeformer'; + strength: number; + fidelity?: number; +}; + +// Superset of all postprocessed image metadata types.. +export declare type PostProcessedImageMetadata = + | ESRGANMetadata + | FacetoolMetadata; + +// Metadata includes the system config and image metadata. +export declare type Metadata = SystemConfig & { + image: GeneratedImageMetadata | PostProcessedImageMetadata; +}; + +// An Image has a UUID, url, modified timestamp, width, height and maybe metadata +export declare type Image = { + uuid: string; + url: string; + mtime: number; + metadata?: Metadata; + width: number; + height: number; + category: GalleryCategory; + isBase64: boolean; +}; + +// GalleryImages is an array of Image. +export declare type GalleryImages = { + images: Array; +}; + +/** + * Types related to the system status. + */ + +// This represents the processing status of the backend. +export declare type SystemStatus = { + isProcessing: boolean; + currentStep: number; + totalSteps: number; + currentIteration: number; + totalIterations: number; + currentStatus: string; + currentStatusHasSteps: boolean; + hasError: boolean; +}; + +export declare type SystemConfig = { + model: string; + model_id: string; + model_hash: string; + app_id: string; + app_version: string; + model_list: ModelList; +}; + +export declare type ModelStatus = 'active' | 'cached' | 'not loaded'; + +export declare type Model = { + status: ModelStatus; + description: string; +}; + +export declare type ModelList = Record; + +/** + * These types type data received from the server via socketio. + */ + +export declare type ModelChangeResponse = { + model_name: string; + model_list: ModelList; +}; + +export declare type SystemStatusResponse = SystemStatus; + +export declare type SystemConfigResponse = SystemConfig; + +export declare type ImageResultResponse = Omit; + +export declare type ImageUploadResponse = Omit & { + destination: 'img2img' | 'inpainting'; +}; + +export declare type ErrorResponse = { + message: string; + additionalData?: string; +}; + +export declare type GalleryImagesResponse = { + images: Array>; + areMoreImagesAvailable: boolean; + category: GalleryCategory; +}; + +export declare type ImageDeletedResponse = { + uuid: string; + url: string; + category: GalleryCategory; +}; + +export declare type ImageUrlResponse = { + url: string; +}; + +export declare type ImageUploadDestination = 'img2img' | 'inpainting'; + +export declare type UploadImagePayload = { + file: File; + destination?: ImageUploadDestination; +}; diff --git a/frontend/src/app/selectors/readinessSelector.ts b/frontend/src/app/selectors/readinessSelector.ts new file mode 100644 index 0000000000..702f45c473 --- /dev/null +++ b/frontend/src/app/selectors/readinessSelector.ts @@ -0,0 +1,96 @@ +import { createSelector } from '@reduxjs/toolkit'; +import _ from 'lodash'; +import { RootState } from '../store'; +import { activeTabNameSelector } from '../../features/options/optionsSelectors'; +import { OptionsState } from '../../features/options/optionsSlice'; + +import { SystemState } from '../../features/system/systemSlice'; +import { InpaintingState } from '../../features/tabs/Inpainting/inpaintingSlice'; +import { validateSeedWeights } from '../../common/util/seedWeightPairs'; + +export const readinessSelector = createSelector( + [ + (state: RootState) => state.options, + (state: RootState) => state.system, + (state: RootState) => state.inpainting, + activeTabNameSelector, + ], + ( + options: OptionsState, + system: SystemState, + inpainting: InpaintingState, + activeTabName + ) => { + const { + prompt, + shouldGenerateVariations, + seedWeights, + // maskPath, + initialImage, + seed, + } = options; + + const { isProcessing, isConnected } = system; + + const { imageToInpaint } = inpainting; + + let isReady = true; + const reasonsWhyNotReady: string[] = []; + + // Cannot generate without a prompt + if (!prompt || Boolean(prompt.match(/^[\s\r\n]+$/))) { + isReady = false; + reasonsWhyNotReady.push('Missing prompt'); + } + + if (activeTabName === 'img2img' && !initialImage) { + isReady = false; + reasonsWhyNotReady.push('No initial image selected'); + } + + if (activeTabName === 'inpainting' && !imageToInpaint) { + isReady = false; + reasonsWhyNotReady.push('No inpainting image selected'); + } + + // // We don't use mask paths now. + // // Cannot generate with a mask without img2img + // if (maskPath && !initialImage) { + // isReady = false; + // reasonsWhyNotReady.push( + // 'On ImageToImage tab, but no mask is provided.' + // ); + // } + + // TODO: job queue + // Cannot generate if already processing an image + if (isProcessing) { + isReady = false; + reasonsWhyNotReady.push('System Busy'); + } + + // Cannot generate if not connected + if (!isConnected) { + isReady = false; + reasonsWhyNotReady.push('System Disconnected'); + } + + // Cannot generate variations without valid seed weights + if ( + shouldGenerateVariations && + (!(validateSeedWeights(seedWeights) || seedWeights === '') || seed === -1) + ) { + isReady = false; + reasonsWhyNotReady.push('Seed-Weights badly formatted.'); + } + + // All good + return { isReady, reasonsWhyNotReady }; + }, + { + memoizeOptions: { + equalityCheck: _.isEqual, + resultEqualityCheck: _.isEqual, + }, + } +); diff --git a/frontend/src/app/socketio/actions.ts b/frontend/src/app/socketio/actions.ts new file mode 100644 index 0000000000..05e0eb92b8 --- /dev/null +++ b/frontend/src/app/socketio/actions.ts @@ -0,0 +1,38 @@ +import { createAction } from '@reduxjs/toolkit'; +import { GalleryCategory } from '../../features/gallery/gallerySlice'; +import { InvokeTabName } from '../../features/tabs/InvokeTabs'; +import * as InvokeAI from '../invokeai'; + + +/** + * We can't use redux-toolkit's createSlice() to make these actions, + * because they have no associated reducer. They only exist to dispatch + * requests to the server via socketio. These actions will be handled + * by the middleware. + */ + +export const generateImage = createAction( + 'socketio/generateImage' +); +export const runESRGAN = createAction('socketio/runESRGAN'); +export const runFacetool = createAction('socketio/runFacetool'); +export const deleteImage = createAction('socketio/deleteImage'); +export const requestImages = createAction( + 'socketio/requestImages' +); +export const requestNewImages = createAction( + 'socketio/requestNewImages' +); +export const cancelProcessing = createAction( + 'socketio/cancelProcessing' +); +export const uploadImage = createAction('socketio/uploadImage'); +export const uploadMaskImage = createAction('socketio/uploadMaskImage'); + +export const requestSystemConfig = createAction( + 'socketio/requestSystemConfig' +); + +export const requestModelChange = createAction( + 'socketio/requestModelChange' +); diff --git a/frontend/src/app/socketio/emitters.ts b/frontend/src/app/socketio/emitters.ts new file mode 100644 index 0000000000..3f1740b027 --- /dev/null +++ b/frontend/src/app/socketio/emitters.ts @@ -0,0 +1,199 @@ +import { AnyAction, Dispatch, MiddlewareAPI } from '@reduxjs/toolkit'; +import dateFormat from 'dateformat'; +import { Socket } from 'socket.io-client'; +import { + frontendToBackendParameters, + FrontendToBackendParametersConfig, +} from '../../common/util/parameterTranslation'; +import { + GalleryCategory, + GalleryState, + removeImage, +} from '../../features/gallery/gallerySlice'; +import { OptionsState } from '../../features/options/optionsSlice'; +import { + addLogEntry, + errorOccurred, + modelChangeRequested, + setIsProcessing, +} from '../../features/system/systemSlice'; +import { inpaintingImageElementRef } from '../../features/tabs/Inpainting/InpaintingCanvas'; +import { InvokeTabName } from '../../features/tabs/InvokeTabs'; +import * as InvokeAI from '../invokeai'; +import { RootState } from '../store'; + +/** + * Returns an object containing all functions which use `socketio.emit()`. + * i.e. those which make server requests. + */ +const makeSocketIOEmitters = ( + store: MiddlewareAPI, any>, + socketio: Socket +) => { + // We need to dispatch actions to redux and get pieces of state from the store. + const { dispatch, getState } = store; + + return { + emitGenerateImage: (generationMode: InvokeTabName) => { + dispatch(setIsProcessing(true)); + + const state: RootState = getState(); + + const { + options: optionsState, + system: systemState, + inpainting: inpaintingState, + gallery: galleryState, + } = state; + + const frontendToBackendParametersConfig: FrontendToBackendParametersConfig = + { + generationMode, + optionsState, + inpaintingState, + systemState, + }; + + if (generationMode === 'inpainting') { + if ( + !inpaintingImageElementRef.current || + !inpaintingState.imageToInpaint?.url + ) { + dispatch( + addLogEntry({ + timestamp: dateFormat(new Date(), 'isoDateTime'), + message: 'Inpainting image not loaded, cannot generate image.', + level: 'error', + }) + ); + dispatch(errorOccurred()); + return; + } + + frontendToBackendParametersConfig.imageToProcessUrl = + inpaintingState.imageToInpaint.url; + + frontendToBackendParametersConfig.maskImageElement = + inpaintingImageElementRef.current; + } else if (!['txt2img', 'img2img'].includes(generationMode)) { + if (!galleryState.currentImage?.url) return; + + frontendToBackendParametersConfig.imageToProcessUrl = + galleryState.currentImage.url; + } + + const { generationParameters, esrganParameters, facetoolParameters } = + frontendToBackendParameters(frontendToBackendParametersConfig); + + socketio.emit( + 'generateImage', + generationParameters, + esrganParameters, + facetoolParameters + ); + + // we need to truncate the init_mask base64 else it takes up the whole log + // TODO: handle maintaining masks for reproducibility in future + if (generationParameters.init_mask) { + generationParameters.init_mask = generationParameters.init_mask + .substr(0, 20) + .concat('...'); + } + + dispatch( + addLogEntry({ + timestamp: dateFormat(new Date(), 'isoDateTime'), + message: `Image generation requested: ${JSON.stringify({ + ...generationParameters, + ...esrganParameters, + ...facetoolParameters, + })}`, + }) + ); + }, + emitRunESRGAN: (imageToProcess: InvokeAI.Image) => { + dispatch(setIsProcessing(true)); + const options: OptionsState = getState().options; + const { upscalingLevel, upscalingStrength } = options; + const esrganParameters = { + upscale: [upscalingLevel, upscalingStrength], + }; + socketio.emit('runPostprocessing', imageToProcess, { + type: 'esrgan', + ...esrganParameters, + }); + dispatch( + addLogEntry({ + timestamp: dateFormat(new Date(), 'isoDateTime'), + message: `ESRGAN upscale requested: ${JSON.stringify({ + file: imageToProcess.url, + ...esrganParameters, + })}`, + }) + ); + }, + emitRunFacetool: (imageToProcess: InvokeAI.Image) => { + dispatch(setIsProcessing(true)); + const options: OptionsState = getState().options; + const { facetoolType, facetoolStrength, codeformerFidelity } = options; + + const facetoolParameters: Record = { + facetool_strength: facetoolStrength, + }; + + if (facetoolType === 'codeformer') { + facetoolParameters.codeformer_fidelity = codeformerFidelity; + } + + socketio.emit('runPostprocessing', imageToProcess, { + type: facetoolType, + ...facetoolParameters, + }); + dispatch( + addLogEntry({ + timestamp: dateFormat(new Date(), 'isoDateTime'), + message: `Face restoration (${facetoolType}) requested: ${JSON.stringify( + { + file: imageToProcess.url, + ...facetoolParameters, + } + )}`, + }) + ); + }, + emitDeleteImage: (imageToDelete: InvokeAI.Image) => { + const { url, uuid, category } = imageToDelete; + dispatch(removeImage(imageToDelete)); + socketio.emit('deleteImage', url, uuid, category); + }, + emitRequestImages: (category: GalleryCategory) => { + const gallery: GalleryState = getState().gallery; + const { earliest_mtime } = gallery.categories[category]; + socketio.emit('requestImages', category, earliest_mtime); + }, + emitRequestNewImages: (category: GalleryCategory) => { + const gallery: GalleryState = getState().gallery; + const { latest_mtime } = gallery.categories[category]; + socketio.emit('requestLatestImages', category, latest_mtime); + }, + emitCancelProcessing: () => { + socketio.emit('cancel'); + }, + emitUploadImage: (payload: InvokeAI.UploadImagePayload) => { + const { file, destination } = payload; + socketio.emit('uploadImage', file, file.name, destination); + }, + emitUploadMaskImage: (file: File) => { + socketio.emit('uploadMaskImage', file, file.name); + }, + emitRequestSystemConfig: () => { + socketio.emit('requestSystemConfig'); + }, + emitRequestModelChange: (modelName: string) => { + dispatch(modelChangeRequested()); + socketio.emit('requestModelChange', modelName); + }, + }; +}; + +export default makeSocketIOEmitters; diff --git a/frontend/src/app/socketio/listeners.ts b/frontend/src/app/socketio/listeners.ts new file mode 100644 index 0000000000..e27d79f55c --- /dev/null +++ b/frontend/src/app/socketio/listeners.ts @@ -0,0 +1,405 @@ +import { AnyAction, MiddlewareAPI, Dispatch } from '@reduxjs/toolkit'; +import { v4 as uuidv4 } from 'uuid'; +import dateFormat from 'dateformat'; + +import * as InvokeAI from '../invokeai'; + +import { + addLogEntry, + setIsConnected, + setIsProcessing, + setSystemStatus, + setCurrentStatus, + setSystemConfig, + processingCanceled, + errorOccurred, + setModelList, + setIsCancelable, +} from '../../features/system/systemSlice'; + +import { + addGalleryImages, + addImage, + clearIntermediateImage, + GalleryState, + removeImage, + setCurrentImage, + setIntermediateImage, +} from '../../features/gallery/gallerySlice'; + +import { + clearInitialImage, + setInitialImage, + setMaskPath, +} from '../../features/options/optionsSlice'; +import { requestImages, requestNewImages } from './actions'; +import { + clearImageToInpaint, + setImageToInpaint, +} from '../../features/tabs/Inpainting/inpaintingSlice'; +import { tabMap } from '../../features/tabs/InvokeTabs'; + +/** + * Returns an object containing listener callbacks for socketio events. + * TODO: This file is large, but simple. Should it be split up further? + */ +const makeSocketIOListeners = ( + store: MiddlewareAPI, any> +) => { + const { dispatch, getState } = store; + + return { + /** + * Callback to run when we receive a 'connect' event. + */ + onConnect: () => { + try { + dispatch(setIsConnected(true)); + dispatch(setCurrentStatus('Connected')); + const gallery: GalleryState = getState().gallery; + + if (gallery.categories.user.latest_mtime) { + dispatch(requestNewImages('user')); + } else { + dispatch(requestImages('user')); + } + + if (gallery.categories.result.latest_mtime) { + dispatch(requestNewImages('result')); + } else { + dispatch(requestImages('result')); + } + } catch (e) { + console.error(e); + } + }, + /** + * Callback to run when we receive a 'disconnect' event. + */ + onDisconnect: () => { + try { + dispatch(setIsConnected(false)); + dispatch(setCurrentStatus('Disconnected')); + + dispatch( + addLogEntry({ + timestamp: dateFormat(new Date(), 'isoDateTime'), + message: `Disconnected from server`, + level: 'warning', + }) + ); + } catch (e) { + console.error(e); + } + }, + /** + * Callback to run when we receive a 'generationResult' event. + */ + onGenerationResult: (data: InvokeAI.ImageResultResponse) => { + try { + const { shouldLoopback, activeTab } = getState().options; + const newImage = { + uuid: uuidv4(), + ...data, + category: 'result', + }; + + dispatch( + addImage({ + category: 'result', + image: newImage, + }) + ); + + if (shouldLoopback) { + const activeTabName = tabMap[activeTab]; + switch (activeTabName) { + case 'img2img': { + dispatch(setInitialImage(newImage)); + break; + } + case 'inpainting': { + dispatch(setImageToInpaint(newImage)); + break; + } + } + } + + dispatch( + addLogEntry({ + timestamp: dateFormat(new Date(), 'isoDateTime'), + message: `Image generated: ${data.url}`, + }) + ); + } catch (e) { + console.error(e); + } + }, + /** + * Callback to run when we receive a 'intermediateResult' event. + */ + onIntermediateResult: (data: InvokeAI.ImageResultResponse) => { + try { + dispatch( + setIntermediateImage({ + uuid: uuidv4(), + ...data, + }) + ); + if (!data.isBase64) { + dispatch( + addLogEntry({ + timestamp: dateFormat(new Date(), 'isoDateTime'), + message: `Intermediate image generated: ${data.url}`, + }) + ); + } + } catch (e) { + console.error(e); + } + }, + /** + * Callback to run when we receive an 'esrganResult' event. + */ + onPostprocessingResult: (data: InvokeAI.ImageResultResponse) => { + try { + dispatch( + addImage({ + category: 'result', + image: { + uuid: uuidv4(), + ...data, + category: 'result', + }, + }) + ); + + dispatch( + addLogEntry({ + timestamp: dateFormat(new Date(), 'isoDateTime'), + message: `Postprocessed: ${data.url}`, + }) + ); + } catch (e) { + console.error(e); + } + }, + /** + * Callback to run when we receive a 'progressUpdate' event. + * TODO: Add additional progress phases + */ + onProgressUpdate: (data: InvokeAI.SystemStatus) => { + try { + dispatch(setIsProcessing(true)); + dispatch(setSystemStatus(data)); + } catch (e) { + console.error(e); + } + }, + /** + * Callback to run when we receive a 'progressUpdate' event. + */ + onError: (data: InvokeAI.ErrorResponse) => { + const { message, additionalData } = data; + + if (additionalData) { + // TODO: handle more data than short message + } + + try { + dispatch( + addLogEntry({ + timestamp: dateFormat(new Date(), 'isoDateTime'), + message: `Server error: ${message}`, + level: 'error', + }) + ); + dispatch(errorOccurred()); + dispatch(clearIntermediateImage()); + } catch (e) { + console.error(e); + } + }, + /** + * Callback to run when we receive a 'galleryImages' event. + */ + onGalleryImages: (data: InvokeAI.GalleryImagesResponse) => { + const { images, areMoreImagesAvailable, category } = data; + + /** + * the logic here ideally would be in the reducer but we have a side effect: + * generating a uuid. so the logic needs to be here, outside redux. + */ + + // Generate a UUID for each image + const preparedImages = images.map((image): InvokeAI.Image => { + return { + uuid: uuidv4(), + ...image, + }; + }); + + dispatch( + addGalleryImages({ + images: preparedImages, + areMoreImagesAvailable, + category, + }) + ); + + dispatch( + addLogEntry({ + timestamp: dateFormat(new Date(), 'isoDateTime'), + message: `Loaded ${images.length} images`, + }) + ); + }, + /** + * Callback to run when we receive a 'processingCanceled' event. + */ + onProcessingCanceled: () => { + dispatch(processingCanceled()); + + const { intermediateImage } = getState().gallery; + + if (intermediateImage) { + if (!intermediateImage.isBase64) { + dispatch( + addImage({ + category: 'result', + image: intermediateImage, + }) + ); + dispatch( + addLogEntry({ + timestamp: dateFormat(new Date(), 'isoDateTime'), + message: `Intermediate image saved: ${intermediateImage.url}`, + }) + ); + } + dispatch(clearIntermediateImage()); + } + + dispatch( + addLogEntry({ + timestamp: dateFormat(new Date(), 'isoDateTime'), + message: `Processing canceled`, + level: 'warning', + }) + ); + }, + /** + * Callback to run when we receive a 'imageDeleted' event. + */ + onImageDeleted: (data: InvokeAI.ImageDeletedResponse) => { + const { url } = data; + + // remove image from gallery + dispatch(removeImage(data)); + + // remove references to image in options + const { initialImage, maskPath } = getState().options; + const { imageToInpaint } = getState().inpainting; + + if (initialImage?.url === url || initialImage === url) { + dispatch(clearInitialImage()); + } + + if (imageToInpaint?.url === url) { + dispatch(clearImageToInpaint()); + } + + if (maskPath === url) { + dispatch(setMaskPath('')); + } + + dispatch( + addLogEntry({ + timestamp: dateFormat(new Date(), 'isoDateTime'), + message: `Image deleted: ${url}`, + }) + ); + }, + onImageUploaded: (data: InvokeAI.ImageUploadResponse) => { + const { destination, ...rest } = data; + const image = { + uuid: uuidv4(), + ...rest, + }; + + try { + dispatch(addImage({ image, category: 'user' })); + + switch (destination) { + case 'img2img': { + dispatch(setInitialImage(image)); + break; + } + case 'inpainting': { + dispatch(setImageToInpaint(image)); + break; + } + default: { + dispatch(setCurrentImage(image)); + break; + } + } + + dispatch( + addLogEntry({ + timestamp: dateFormat(new Date(), 'isoDateTime'), + message: `Image uploaded: ${data.url}`, + }) + ); + } catch (e) { + console.error(e); + } + }, + /** + * Callback to run when we receive a 'maskImageUploaded' event. + */ + onMaskImageUploaded: (data: InvokeAI.ImageUrlResponse) => { + const { url } = data; + dispatch(setMaskPath(url)); + dispatch( + addLogEntry({ + timestamp: dateFormat(new Date(), 'isoDateTime'), + message: `Mask image uploaded: ${url}`, + }) + ); + }, + onSystemConfig: (data: InvokeAI.SystemConfig) => { + dispatch(setSystemConfig(data)); + }, + onModelChanged: (data: InvokeAI.ModelChangeResponse) => { + const { model_name, model_list } = data; + dispatch(setModelList(model_list)); + dispatch(setCurrentStatus('Model Changed')); + dispatch(setIsProcessing(false)); + dispatch(setIsCancelable(true)); + dispatch( + addLogEntry({ + timestamp: dateFormat(new Date(), 'isoDateTime'), + message: `Model changed: ${model_name}`, + level: 'info', + }) + ); + }, + onModelChangeFailed: (data: InvokeAI.ModelChangeResponse) => { + const { model_name, model_list } = data; + dispatch(setModelList(model_list)); + dispatch(setIsProcessing(false)); + dispatch(setIsCancelable(true)); + dispatch(errorOccurred()); + dispatch( + addLogEntry({ + timestamp: dateFormat(new Date(), 'isoDateTime'), + message: `Model change failed: ${model_name}`, + level: 'error', + }) + ); + }, + }; +}; + +export default makeSocketIOListeners; diff --git a/frontend/src/app/socketio/middleware.ts b/frontend/src/app/socketio/middleware.ts new file mode 100644 index 0000000000..854e245c4f --- /dev/null +++ b/frontend/src/app/socketio/middleware.ts @@ -0,0 +1,197 @@ +import { Middleware } from '@reduxjs/toolkit'; +import { io } from 'socket.io-client'; + +import makeSocketIOListeners from './listeners'; +import makeSocketIOEmitters from './emitters'; + +import * as InvokeAI from '../invokeai'; + +/** + * Creates a socketio middleware to handle communication with server. + * + * Special `socketio/actionName` actions are created in actions.ts and + * exported for use by the application, which treats them like any old + * action, using `dispatch` to dispatch them. + * + * These actions are intercepted here, where `socketio.emit()` calls are + * made on their behalf - see `emitters.ts`. The emitter functions + * are the outbound communication to the server. + * + * Listeners are also established here - see `listeners.ts`. The listener + * functions receive communication from the server and usually dispatch + * some new action to handle whatever data was sent from the server. + */ +export const socketioMiddleware = () => { + const { origin } = new URL(window.location.href); + + const socketio = io(origin, { + timeout: 60000, + path: window.location.pathname + 'socket.io', + }); + + let areListenersSet = false; + + const middleware: Middleware = (store) => (next) => (action) => { + const { + onConnect, + onDisconnect, + onError, + onPostprocessingResult, + onGenerationResult, + onIntermediateResult, + onProgressUpdate, + onGalleryImages, + onProcessingCanceled, + onImageDeleted, + onImageUploaded, + onMaskImageUploaded, + onSystemConfig, + onModelChanged, + onModelChangeFailed, + } = makeSocketIOListeners(store); + + const { + emitGenerateImage, + emitRunESRGAN, + emitRunFacetool, + emitDeleteImage, + emitRequestImages, + emitRequestNewImages, + emitCancelProcessing, + emitUploadImage, + emitUploadMaskImage, + emitRequestSystemConfig, + emitRequestModelChange, + } = makeSocketIOEmitters(store, socketio); + + /** + * If this is the first time the middleware has been called (e.g. during store setup), + * initialize all our socket.io listeners. + */ + if (!areListenersSet) { + socketio.on('connect', () => onConnect()); + + socketio.on('disconnect', () => onDisconnect()); + + socketio.on('error', (data: InvokeAI.ErrorResponse) => onError(data)); + + socketio.on('generationResult', (data: InvokeAI.ImageResultResponse) => + onGenerationResult(data) + ); + + socketio.on( + 'postprocessingResult', + (data: InvokeAI.ImageResultResponse) => onPostprocessingResult(data) + ); + + socketio.on('intermediateResult', (data: InvokeAI.ImageResultResponse) => + onIntermediateResult(data) + ); + + socketio.on('progressUpdate', (data: InvokeAI.SystemStatus) => + onProgressUpdate(data) + ); + + socketio.on('galleryImages', (data: InvokeAI.GalleryImagesResponse) => + onGalleryImages(data) + ); + + socketio.on('processingCanceled', () => { + onProcessingCanceled(); + }); + + socketio.on('imageDeleted', (data: InvokeAI.ImageDeletedResponse) => { + onImageDeleted(data); + }); + + socketio.on( + 'imageUploaded', + (data: InvokeAI.ImageUploadResponse) => { + onImageUploaded(data); + } + ); + + socketio.on('maskImageUploaded', (data: InvokeAI.ImageUrlResponse) => { + onMaskImageUploaded(data); + }); + + socketio.on('systemConfig', (data: InvokeAI.SystemConfig) => { + onSystemConfig(data); + }); + + socketio.on('modelChanged', (data: InvokeAI.ModelChangeResponse) => { + onModelChanged(data); + }); + + socketio.on('modelChangeFailed', (data: InvokeAI.ModelChangeResponse) => { + onModelChangeFailed(data); + }); + + areListenersSet = true; + } + + /** + * Handle redux actions caught by middleware. + */ + switch (action.type) { + case 'socketio/generateImage': { + emitGenerateImage(action.payload); + break; + } + + case 'socketio/runESRGAN': { + emitRunESRGAN(action.payload); + break; + } + + case 'socketio/runFacetool': { + emitRunFacetool(action.payload); + break; + } + + case 'socketio/deleteImage': { + emitDeleteImage(action.payload); + break; + } + + case 'socketio/requestImages': { + emitRequestImages(action.payload); + break; + } + + case 'socketio/requestNewImages': { + emitRequestNewImages(action.payload); + break; + } + + case 'socketio/cancelProcessing': { + emitCancelProcessing(); + break; + } + + case 'socketio/uploadImage': { + emitUploadImage(action.payload); + break; + } + + case 'socketio/uploadMaskImage': { + emitUploadMaskImage(action.payload); + break; + } + + case 'socketio/requestSystemConfig': { + emitRequestSystemConfig(); + break; + } + + case 'socketio/requestModelChange': { + emitRequestModelChange(action.payload); + break; + } + } + + next(action); + }; + + return middleware; +}; diff --git a/frontend/src/app/store.ts b/frontend/src/app/store.ts new file mode 100644 index 0000000000..76ccc09bfe --- /dev/null +++ b/frontend/src/app/store.ts @@ -0,0 +1,117 @@ +import { combineReducers, configureStore } from '@reduxjs/toolkit'; +import { useDispatch, useSelector } from 'react-redux'; +import type { TypedUseSelectorHook } from 'react-redux'; + +import { persistReducer } from 'redux-persist'; +import storage from 'redux-persist/lib/storage'; // defaults to localStorage for web + +import optionsReducer, { OptionsState } from '../features/options/optionsSlice'; +import galleryReducer, { GalleryState } from '../features/gallery/gallerySlice'; +import inpaintingReducer, { + InpaintingState, +} from '../features/tabs/Inpainting/inpaintingSlice'; + +import systemReducer, { SystemState } from '../features/system/systemSlice'; +import { socketioMiddleware } from './socketio/middleware'; +import autoMergeLevel2 from 'redux-persist/es/stateReconciler/autoMergeLevel2'; +import { PersistPartial } from 'redux-persist/es/persistReducer'; + +/** + * redux-persist provides an easy and reliable way to persist state across reloads. + * + * While we definitely want generation parameters to be persisted, there are a number + * of things we do *not* want to be persisted across reloads: + * - Gallery/selected image (user may add/delete images from disk between page loads) + * - Connection/processing status + * - Availability of external libraries like ESRGAN/GFPGAN + * + * These can be blacklisted in redux-persist. + * + * The necesssary nested persistors with blacklists are configured below. + * + * TODO: Do we blacklist initialImagePath? If the image is deleted from disk we get an + * ugly 404. But if we blacklist it, then this is a valuable parameter that is lost + * on reload. Need to figure out a good way to handle this. + */ + +const rootPersistConfig = { + key: 'root', + storage, + stateReconciler: autoMergeLevel2, + blacklist: ['gallery', 'system', 'inpainting'], +}; + +const systemPersistConfig = { + key: 'system', + storage, + stateReconciler: autoMergeLevel2, + blacklist: [ + 'isCancelable', + 'isConnected', + 'isProcessing', + 'currentStep', + 'socketId', + 'isESRGANAvailable', + 'isGFPGANAvailable', + 'currentStep', + 'totalSteps', + 'currentIteration', + 'totalIterations', + 'currentStatus', + ], +}; + +const galleryPersistConfig = { + key: 'gallery', + storage, + stateReconciler: autoMergeLevel2, + whitelist: [ + 'galleryWidth', + 'shouldPinGallery', + 'shouldShowGallery', + 'galleryScrollPosition', + 'galleryImageMinimumWidth', + 'galleryImageObjectFit', + ], +}; + +const inpaintingPersistConfig = { + key: 'inpainting', + storage, + stateReconciler: autoMergeLevel2, + blacklist: ['pastLines', 'futuresLines', 'cursorPosition'], +}; + +const reducers = combineReducers({ + options: optionsReducer, + gallery: persistReducer(galleryPersistConfig, galleryReducer), + system: persistReducer(systemPersistConfig, systemReducer), + inpainting: persistReducer( + inpaintingPersistConfig, + inpaintingReducer + ), +}); + +const persistedReducer = persistReducer<{ + options: OptionsState; + gallery: GalleryState & PersistPartial; + system: SystemState & PersistPartial; + inpainting: InpaintingState & PersistPartial; +}>(rootPersistConfig, reducers); + +// Continue with store setup +export const store = configureStore({ + reducer: persistedReducer, + middleware: (getDefaultMiddleware) => + getDefaultMiddleware({ + // redux-persist sometimes needs to temporarily put a function in redux state, need to disable this check + serializableCheck: false, + }).concat(socketioMiddleware()), +}); + +export type RootState = ReturnType; +export type AppDispatch = typeof store.dispatch; + +// Use throughout your app instead of plain `useDispatch` and `useSelector` +export const useAppDispatch: () => AppDispatch = useDispatch; +export const useAppSelector: TypedUseSelectorHook = useSelector; diff --git a/frontend/src/app/theme.ts b/frontend/src/app/theme.ts new file mode 100644 index 0000000000..06b28a66ac --- /dev/null +++ b/frontend/src/app/theme.ts @@ -0,0 +1,52 @@ +import { extendTheme } from '@chakra-ui/react'; +import type { StyleFunctionProps } from '@chakra-ui/styled-system'; + +export const theme = extendTheme({ + config: { + initialColorMode: 'dark', + useSystemColorMode: false, + }, + components: { + Tooltip: { + baseStyle: (props: StyleFunctionProps) => ({ + textColor: props.colorMode === 'dark' ? 'gray.800' : 'gray.100', + }), + }, + Accordion: { + baseStyle: (props: StyleFunctionProps) => ({ + button: { + fontWeight: 'bold', + _hover: { + bgColor: + props.colorMode === 'dark' + ? 'rgba(255,255,255,0.05)' + : 'rgba(0,0,0,0.05)', + }, + }, + panel: { + paddingBottom: 2, + }, + }), + }, + FormLabel: { + baseStyle: { + fontWeight: 'light', + }, + }, + Button: { + variants: { + imageHoverIconButton: (props: StyleFunctionProps) => ({ + bg: props.colorMode === 'dark' ? 'blackAlpha.700' : 'whiteAlpha.800', + color: + props.colorMode === 'dark' ? 'whiteAlpha.700' : 'blackAlpha.700', + _hover: { + bg: + props.colorMode === 'dark' ? 'blackAlpha.800' : 'whiteAlpha.800', + color: + props.colorMode === 'dark' ? 'whiteAlpha.900' : 'blackAlpha.900', + }, + }), + }, + }, + }, +}); diff --git a/frontend/src/app/utils.ts b/frontend/src/app/utils.ts new file mode 100644 index 0000000000..6bc959f2f7 --- /dev/null +++ b/frontend/src/app/utils.ts @@ -0,0 +1,25 @@ +export function keepGUIAlive() { + async function getRequest(url = '') { + const response = await fetch(url, { + method: 'GET', + cache: 'no-cache', + }); + return response; + } + + const keepAliveServer = () => { + const url = document.location; + const route = '/flaskwebgui-keep-server-alive'; + getRequest(url + route).then((data) => { + return data; + }); + }; + + if (!import.meta.env.NODE_ENV || import.meta.env.NODE_ENV === 'production') { + document.addEventListener('DOMContentLoaded', () => { + const intervalRequest = 3 * 1000; + keepAliveServer(); + setInterval(keepAliveServer, intervalRequest); + }); + } +} diff --git a/frontend/src/assets/fonts/Inter/Inter-Bold.ttf b/frontend/src/assets/fonts/Inter/Inter-Bold.ttf new file mode 100644 index 0000000000..8e82c70d10 Binary files /dev/null and b/frontend/src/assets/fonts/Inter/Inter-Bold.ttf differ diff --git a/frontend/src/assets/fonts/Inter/Inter.ttf b/frontend/src/assets/fonts/Inter/Inter.ttf new file mode 100644 index 0000000000..ec3164efa8 Binary files /dev/null and b/frontend/src/assets/fonts/Inter/Inter.ttf differ diff --git a/frontend/src/assets/images/image2img.png b/frontend/src/assets/images/image2img.png new file mode 100644 index 0000000000..bacc938ea6 Binary files /dev/null and b/frontend/src/assets/images/image2img.png differ diff --git a/frontend/src/assets/images/logo.png b/frontend/src/assets/images/logo.png new file mode 100644 index 0000000000..54f8ed8a8f Binary files /dev/null and b/frontend/src/assets/images/logo.png differ diff --git a/frontend/src/common/components/GuideIcon.tsx b/frontend/src/common/components/GuideIcon.tsx new file mode 100644 index 0000000000..2f4312ae76 --- /dev/null +++ b/frontend/src/common/components/GuideIcon.tsx @@ -0,0 +1,22 @@ +import { Box, forwardRef, Icon } from '@chakra-ui/react'; +import { IconType } from 'react-icons'; +import { MdHelp } from 'react-icons/md'; +import { Feature } from '../../app/features'; +import GuidePopover from './GuidePopover'; + +type GuideIconProps = { + feature: Feature; + icon?: IconType; +}; + +const GuideIcon = forwardRef( + ({ feature, icon = MdHelp }: GuideIconProps, ref) => ( + + + + + + ) +); + +export default GuideIcon; diff --git a/frontend/src/common/components/GuidePopover.scss b/frontend/src/common/components/GuidePopover.scss new file mode 100644 index 0000000000..faa31212bb --- /dev/null +++ b/frontend/src/common/components/GuidePopover.scss @@ -0,0 +1,20 @@ +.guide-popover-arrow { + background-color: var(--tab-panel-bg) !important; + box-shadow: none !important; +} + +.guide-popover-content { + background-color: var(--background-color-secondary) !important; + border: none !important; +} + +.guide-popover-guide-content { + background: var(--tab-panel-bg); + border: 2px solid var(--tab-hover-color); + border-radius: 0.4rem; + padding: 0.75rem 1rem 0.75rem 1rem; + display: grid; + grid-template-rows: repeat(auto-fill, 1fr); + grid-row-gap: 0.5rem; + justify-content: space-between; +} diff --git a/frontend/src/common/components/GuidePopover.tsx b/frontend/src/common/components/GuidePopover.tsx new file mode 100644 index 0000000000..b5893629c0 --- /dev/null +++ b/frontend/src/common/components/GuidePopover.tsx @@ -0,0 +1,49 @@ +import { + Popover, + PopoverArrow, + PopoverContent, + PopoverTrigger, + Box, +} from '@chakra-ui/react'; +import { SystemState } from '../../features/system/systemSlice'; +import { useAppSelector } from '../../app/store'; +import { RootState } from '../../app/store'; +import { createSelector } from '@reduxjs/toolkit'; +import { ReactElement } from 'react'; +import { Feature, FEATURES } from '../../app/features'; + +type GuideProps = { + children: ReactElement; + feature: Feature; +}; + +const systemSelector = createSelector( + (state: RootState) => state.system, + (system: SystemState) => system.shouldDisplayGuides +); + +const GuidePopover = ({ children, feature }: GuideProps) => { + const shouldDisplayGuides = useAppSelector(systemSelector); + const { text } = FEATURES[feature]; + + if (!shouldDisplayGuides) return null; + + return ( + + + {children} + + e.preventDefault()} + cursor={'initial'} + > + +
{text}
+
+
+ ); +}; + +export default GuidePopover; diff --git a/frontend/src/common/components/IAIButton.scss b/frontend/src/common/components/IAIButton.scss new file mode 100644 index 0000000000..1ac41cf0d7 --- /dev/null +++ b/frontend/src/common/components/IAIButton.scss @@ -0,0 +1,3 @@ +.invokeai__button { + justify-content: space-between; +} diff --git a/frontend/src/common/components/IAIButton.tsx b/frontend/src/common/components/IAIButton.tsx new file mode 100644 index 0000000000..d25e9decae --- /dev/null +++ b/frontend/src/common/components/IAIButton.tsx @@ -0,0 +1,32 @@ +import { + Button, + ButtonProps, + forwardRef, + Tooltip, + TooltipProps, +} from '@chakra-ui/react'; +import { ReactNode } from 'react'; + +export interface IAIButtonProps extends ButtonProps { + tooltip?: string; + tooltipProps?: Omit; + styleClass?: string; + children: ReactNode; +} + +const IAIButton = forwardRef((props: IAIButtonProps, forwardedRef) => { + const { children, tooltip = '', tooltipProps, styleClass, ...rest } = props; + return ( + + + + ); +}); + +export default IAIButton; diff --git a/frontend/src/common/components/IAICheckbox.scss b/frontend/src/common/components/IAICheckbox.scss new file mode 100644 index 0000000000..c0118e25e1 --- /dev/null +++ b/frontend/src/common/components/IAICheckbox.scss @@ -0,0 +1,26 @@ +.invokeai__checkbox { + .chakra-checkbox__label { + margin-top: 1px; + color: var(--text-color-secondary); + font-size: 0.9rem; + } + + .chakra-checkbox__control { + width: 1rem; + height: 1rem; + border: none; + border-radius: 0.2rem; + background-color: var(--input-checkbox-bg); + + svg { + width: 0.6rem; + height: 0.6rem; + stroke-width: 3px !important; + } + + &[data-checked] { + color: var(--text-color); + background-color: var(--input-checkbox-checked-bg); + } + } +} diff --git a/frontend/src/common/components/IAICheckbox.tsx b/frontend/src/common/components/IAICheckbox.tsx new file mode 100644 index 0000000000..fa9ab20ea2 --- /dev/null +++ b/frontend/src/common/components/IAICheckbox.tsx @@ -0,0 +1,17 @@ +import { Checkbox, CheckboxProps } from '@chakra-ui/react'; + +type IAICheckboxProps = CheckboxProps & { + label: string; + styleClass?: string; +}; + +const IAICheckbox = (props: IAICheckboxProps) => { + const { label, styleClass, ...rest } = props; + return ( + + {label} + + ); +}; + +export default IAICheckbox; diff --git a/frontend/src/common/components/IAIColorPicker.scss b/frontend/src/common/components/IAIColorPicker.scss new file mode 100644 index 0000000000..4b6e29483b --- /dev/null +++ b/frontend/src/common/components/IAIColorPicker.scss @@ -0,0 +1,8 @@ +.invokeai__color-picker { + .react-colorful__hue-pointer, + .react-colorful__saturation-pointer { + width: 1.5rem; + height: 1.5rem; + border-color: var(--white); + } +} diff --git a/frontend/src/common/components/IAIColorPicker.tsx b/frontend/src/common/components/IAIColorPicker.tsx new file mode 100644 index 0000000000..619c5758e6 --- /dev/null +++ b/frontend/src/common/components/IAIColorPicker.tsx @@ -0,0 +1,19 @@ +import { RgbaColorPicker } from 'react-colorful'; +import { ColorPickerBaseProps, RgbaColor } from 'react-colorful/dist/types'; + +type IAIColorPickerProps = ColorPickerBaseProps & { + styleClass?: string; +}; + +const IAIColorPicker = (props: IAIColorPickerProps) => { + const { styleClass, ...rest } = props; + + return ( + + ); +}; + +export default IAIColorPicker; diff --git a/frontend/src/common/components/IAIIconButton.scss b/frontend/src/common/components/IAIIconButton.scss new file mode 100644 index 0000000000..7bed75c3fc --- /dev/null +++ b/frontend/src/common/components/IAIIconButton.scss @@ -0,0 +1,75 @@ +@use '../../styles/Mixins/' as *; + +.invokeai__icon-button { + background-color: var(--btn-grey); + cursor: pointer; + + &:hover { + background-color: var(--btn-grey-hover); + } + + &[data-selected='true'] { + background-color: var(--accent-color); + &:hover { + background-color: var(--accent-color-hover); + } + } + + &[disabled] { + cursor: not-allowed; + } + + &[data-variant='link'] { + background: none !important; + &:hover { + background: none !important; + } + } + + &[data-selected='true'] { + border-color: var(--accent-color); + &:hover { + border-color: var(--accent-color-hover); + } + } + + &[data-alert='true'] { + animation-name: pulseColor; + animation-duration: 1s; + animation-timing-function: ease-in-out; + animation-iteration-count: infinite; + &:hover { + animation: none; + background-color: var(--accent-color-hover); + } + } + + &[data-as-checkbox='true'] { + background-color: var(--btn-grey); + border: 3px solid var(--btn-grey); + + svg { + fill: var(--text-color); + } + + &:hover { + background-color: var(--btn-grey); + border-color: var(--btn-checkbox-border-hover); + svg { + fill: var(--text-color); + } + } + } +} + +@keyframes pulseColor { + 0% { + background-color: var(--accent-color); + } + 50% { + background-color: var(--accent-color-dim); + } + 100% { + background-color: var(--accent-color); + } +} diff --git a/frontend/src/common/components/IAIIconButton.tsx b/frontend/src/common/components/IAIIconButton.tsx new file mode 100644 index 0000000000..3cc76c09f0 --- /dev/null +++ b/frontend/src/common/components/IAIIconButton.tsx @@ -0,0 +1,41 @@ +import { + IconButtonProps, + IconButton, + Tooltip, + TooltipProps, + forwardRef, +} from '@chakra-ui/react'; + +export type IAIIconButtonProps = IconButtonProps & { + styleClass?: string; + tooltip?: string; + tooltipProps?: Omit; + asCheckbox?: boolean; + isChecked?: boolean; +}; + +const IAIIconButton = forwardRef((props: IAIIconButtonProps, forwardedRef) => { + const { + tooltip = '', + styleClass, + tooltipProps, + asCheckbox, + isChecked, + ...rest + } = props; + + return ( + + + + ); +}); + +export default IAIIconButton; diff --git a/frontend/src/common/components/IAIInput.scss b/frontend/src/common/components/IAIInput.scss new file mode 100644 index 0000000000..a028d8ecda --- /dev/null +++ b/frontend/src/common/components/IAIInput.scss @@ -0,0 +1,34 @@ +.input { + display: grid; + grid-template-columns: max-content auto; + column-gap: 1rem; + align-items: center; + + .input-label { + color: var(--text-color-secondary); + margin-right: 0; + } + + .input-entry { + background-color: var(--background-color-secondary); + border: 2px solid var(--border-color); + border-radius: 0.2rem; + font-weight: bold; + + &:focus { + outline: none; + border: 2px solid var(--input-border-color); + box-shadow: 0 0 10px 0 var(--input-box-shadow-color); + } + + &:disabled { + opacity: 0.2; + } + + &[aria-invalid='true'] { + outline: none; + border: 2px solid var(--border-color-invalid); + box-shadow: 0 0 10px 0 var(--box-shadow-color-invalid); + } + } +} diff --git a/frontend/src/common/components/IAIInput.tsx b/frontend/src/common/components/IAIInput.tsx new file mode 100644 index 0000000000..20272d9274 --- /dev/null +++ b/frontend/src/common/components/IAIInput.tsx @@ -0,0 +1,41 @@ +import { FormControl, FormLabel, Input, InputProps } from '@chakra-ui/react'; +import { ChangeEvent } from 'react'; + +interface IAIInputProps extends InputProps { + styleClass?: string; + label?: string; + width?: string | number; + value: string; + onChange: (e: ChangeEvent) => void; +} + +export default function IAIInput(props: IAIInputProps) { + const { + label, + styleClass, + isDisabled = false, + fontSize = '1rem', + width, + isInvalid, + ...rest + } = props; + + return ( + + + {label} + + + + ); +} diff --git a/frontend/src/common/components/IAINumberInput.scss b/frontend/src/common/components/IAINumberInput.scss new file mode 100644 index 0000000000..c7de72dd9a --- /dev/null +++ b/frontend/src/common/components/IAINumberInput.scss @@ -0,0 +1,74 @@ +.invokeai__number-input-form-control { + display: grid; + grid-template-columns: max-content auto; + align-items: center; + + .invokeai__number-input-form-label { + color: var(--text-color-secondary); + margin-right: 0; + font-size: 1rem; + margin-bottom: 0; + flex-grow: 2; + white-space: nowrap; + padding-right: 1rem; + + &[data-focus] + .invokeai__number-input-root { + outline: none; + border: 2px solid var(--input-border-color); + box-shadow: 0 0 10px 0 var(--input-box-shadow-color); + } + + &[aria-invalid='true'] + .invokeai__number-input-root { + outline: none; + border: 2px solid var(--border-color-invalid); + box-shadow: 0 0 10px 0 var(--box-shadow-color-invalid); + } + } + + .invokeai__number-input-root { + height: 2rem; + display: grid; + grid-template-columns: auto max-content; + column-gap: 0.5rem; + align-items: center; + background-color: var(--background-color-secondary); + border: 2px solid var(--border-color); + border-radius: 0.2rem; + } + + .invokeai__number-input-field { + border: none; + font-weight: bold; + width: 100%; + height: auto; + padding: 0; + font-size: 0.9rem; + padding-left: 0.5rem; + padding-right: 0.5rem; + + &:focus { + outline: none; + box-shadow: none; + } + + &:disabled { + opacity: 0.2; + } + } + .invokeai__number-input-stepper { + display: grid; + padding-right: 0.5rem; + + .invokeai__number-input-stepper-button { + border: none; + // expand arrow hitbox + padding: 0 0.5rem; + margin: 0 -0.5rem; + + svg { + width: 10px; + height: 10px; + } + } + } +} diff --git a/frontend/src/common/components/IAINumberInput.tsx b/frontend/src/common/components/IAINumberInput.tsx new file mode 100644 index 0000000000..b538092909 --- /dev/null +++ b/frontend/src/common/components/IAINumberInput.tsx @@ -0,0 +1,168 @@ +import { + FormControl, + NumberInput, + NumberInputField, + NumberIncrementStepper, + NumberDecrementStepper, + NumberInputProps, + FormLabel, + NumberInputFieldProps, + NumberInputStepperProps, + FormControlProps, + FormLabelProps, + TooltipProps, + Tooltip, +} from '@chakra-ui/react'; +import _ from 'lodash'; +import { FocusEvent, useEffect, useState } from 'react'; + +const numberStringRegex = /^-?(0\.)?\.?$/; + +interface Props extends Omit { + styleClass?: string; + label?: string; + width?: string | number; + showStepper?: boolean; + value: number; + onChange: (v: number) => void; + min: number; + max: number; + clamp?: boolean; + isInteger?: boolean; + formControlProps?: FormControlProps; + formLabelProps?: FormLabelProps; + numberInputProps?: NumberInputProps; + numberInputFieldProps?: NumberInputFieldProps; + numberInputStepperProps?: NumberInputStepperProps; + tooltipProps?: Omit; +} + +/** + * Customized Chakra FormControl + NumberInput multi-part component. + */ +const IAINumberInput = (props: Props) => { + const { + label, + styleClass, + isDisabled = false, + showStepper = true, + width, + textAlign, + isInvalid, + value, + onChange, + min, + max, + isInteger = true, + formControlProps, + formLabelProps, + numberInputFieldProps, + numberInputStepperProps, + tooltipProps, + ...rest + } = props; + + /** + * Using a controlled input with a value that accepts decimals needs special + * handling. If the user starts to type in "1.5", by the time they press the + * 5, the value has been parsed from "1." to "1" and they end up with "15". + * + * To resolve this, this component keeps a the value as a string internally, + * and the UI component uses that. When a change is made, that string is parsed + * as a number and given to the `onChange` function. + */ + + const [valueAsString, setValueAsString] = useState(String(value)); + + /** + * When `value` changes (e.g. from a diff source than this component), we need + * to update the internal `valueAsString`, but only if the actual value is different + * from the current value. + */ + useEffect(() => { + if ( + !valueAsString.match(numberStringRegex) && + value !== Number(valueAsString) + ) { + setValueAsString(String(value)); + } + }, [value, valueAsString]); + + const handleOnChange = (v: string) => { + setValueAsString(v); + // This allows negatives and decimals e.g. '-123', `.5`, `-0.2`, etc. + if (!v.match(numberStringRegex)) { + // Cast the value to number. Floor it if it should be an integer. + onChange(isInteger ? Math.floor(Number(v)) : Number(v)); + } + }; + + /** + * Clicking the steppers allows the value to go outside bounds; we need to + * clamp it on blur and floor it if needed. + */ + const handleBlur = (e: FocusEvent) => { + const clamped = _.clamp( + isInteger ? Math.floor(Number(e.target.value)) : Number(e.target.value), + min, + max + ); + setValueAsString(String(clamped)); + onChange(clamped); + }; + + return ( + + + {label && ( + + {label} + + )} + + + {showStepper && ( +
+ + +
+ )} +
+
+
+ ); +}; + +export default IAINumberInput; diff --git a/frontend/src/common/components/IAIPopover.scss b/frontend/src/common/components/IAIPopover.scss new file mode 100644 index 0000000000..73fab8cfb5 --- /dev/null +++ b/frontend/src/common/components/IAIPopover.scss @@ -0,0 +1,12 @@ +.invokeai__popover-content { + min-width: unset; + width: unset !important; + padding: 1rem; + border-radius: 0.5rem !important; + background-color: var(--background-color) !important; + border: 2px solid var(--border-color) !important; + + .invokeai__popover-arrow { + background-color: var(--background-color) !important; + } +} diff --git a/frontend/src/common/components/IAIPopover.tsx b/frontend/src/common/components/IAIPopover.tsx new file mode 100644 index 0000000000..ff18d96ddd --- /dev/null +++ b/frontend/src/common/components/IAIPopover.tsx @@ -0,0 +1,39 @@ +import { + Popover, + PopoverArrow, + PopoverContent, + PopoverTrigger, + BoxProps, +} from '@chakra-ui/react'; +import { PopoverProps } from '@chakra-ui/react'; +import { ReactNode } from 'react'; + +type IAIPopoverProps = PopoverProps & { + triggerComponent: ReactNode; + triggerContainerProps?: BoxProps; + children: ReactNode; + styleClass?: string; + hasArrow?: boolean; +}; + +const IAIPopover = (props: IAIPopoverProps) => { + const { + triggerComponent, + children, + styleClass, + hasArrow = true, + ...rest + } = props; + + return ( + + {triggerComponent} + + {hasArrow && } + {children} + + + ); +}; + +export default IAIPopover; diff --git a/frontend/src/common/components/IAISelect.scss b/frontend/src/common/components/IAISelect.scss new file mode 100644 index 0000000000..d0b9e54037 --- /dev/null +++ b/frontend/src/common/components/IAISelect.scss @@ -0,0 +1,31 @@ +@use '../../styles/Mixins/' as *; + +.invokeai__select { + display: flex; + column-gap: 1rem; + align-items: center; + width: max-content; + + .invokeai__select-label { + color: var(--text-color-secondary); + margin-right: 0; + } + + .invokeai__select-picker { + border: 2px solid var(--border-color); + background-color: var(--background-color-secondary); + font-weight: bold; + height: 2rem; + border-radius: 0.2rem; + + &:focus { + outline: none; + border: 2px solid var(--input-border-color); + box-shadow: 0 0 10px 0 var(--input-box-shadow-color); + } + } + + .invokeai__select-option { + background-color: var(--background-color-secondary); + } +} diff --git a/frontend/src/common/components/IAISelect.tsx b/frontend/src/common/components/IAISelect.tsx new file mode 100644 index 0000000000..cfec3ff18d --- /dev/null +++ b/frontend/src/common/components/IAISelect.tsx @@ -0,0 +1,70 @@ +import { FormControl, FormLabel, Select, SelectProps } from '@chakra-ui/react'; +import { MouseEvent } from 'react'; + +type IAISelectProps = SelectProps & { + label: string; + styleClass?: string; + validValues: + | Array + | Array<{ key: string; value: string | number }>; +}; +/** + * Customized Chakra FormControl + Select multi-part component. + */ +const IAISelect = (props: IAISelectProps) => { + const { + label, + isDisabled, + validValues, + size = 'sm', + fontSize = 'md', + styleClass, + ...rest + } = props; + return ( + ) => { + e.stopPropagation(); + e.nativeEvent.stopImmediatePropagation(); + e.nativeEvent.stopPropagation(); + e.nativeEvent.cancelBubble = true; + }} + > + + {label} + + + + ); +}; + +export default IAISelect; diff --git a/frontend/src/common/components/IAISlider.scss b/frontend/src/common/components/IAISlider.scss new file mode 100644 index 0000000000..ef7681c42f --- /dev/null +++ b/frontend/src/common/components/IAISlider.scss @@ -0,0 +1,40 @@ +@use '../../styles/Mixins/' as *; + +.invokeai__slider-form-control { + display: flex; + column-gap: 1rem; + justify-content: space-between; + align-items: center; + width: max-content; + padding-right: 0.25rem; + + .invokeai__slider-inner-container { + display: flex; + column-gap: 0.5rem; + + .invokeai__slider-form-label { + color: var(--text-color-secondary); + margin: 0; + margin-right: 0.5rem; + margin-bottom: 0.1rem; + } + + .invokeai__slider-root { + .invokeai__slider-filled-track { + background-color: var(--accent-color-hover); + } + + .invokeai__slider-track { + background-color: var(--text-color-secondary); + height: 5px; + border-radius: 9999px; + } + + .invokeai__slider-thumb { + } + } + } +} + +.invokeai__slider-thumb-tooltip { +} diff --git a/frontend/src/common/components/IAISlider.tsx b/frontend/src/common/components/IAISlider.tsx new file mode 100644 index 0000000000..9b7156c5ad --- /dev/null +++ b/frontend/src/common/components/IAISlider.tsx @@ -0,0 +1,87 @@ +import { + Slider, + SliderTrack, + SliderFilledTrack, + SliderThumb, + FormControl, + FormLabel, + Tooltip, + SliderProps, + FormControlProps, + FormLabelProps, + SliderTrackProps, + SliderThumbProps, + TooltipProps, + SliderInnerTrackProps, +} from '@chakra-ui/react'; + +type IAISliderProps = SliderProps & { + label?: string; + styleClass?: string; + formControlProps?: FormControlProps; + formLabelProps?: FormLabelProps; + sliderTrackProps?: SliderTrackProps; + sliderInnerTrackProps?: SliderInnerTrackProps; + sliderThumbProps?: SliderThumbProps; + sliderThumbTooltipProps?: Omit; +}; + +const IAISlider = (props: IAISliderProps) => { + const { + label, + styleClass, + formControlProps, + formLabelProps, + sliderTrackProps, + sliderInnerTrackProps, + sliderThumbProps, + sliderThumbTooltipProps, + ...rest + } = props; + return ( + +
+ + {label} + + + + + + + + + + + +
+
+ ); +}; + +export default IAISlider; diff --git a/frontend/src/common/components/IAISwitch.scss b/frontend/src/common/components/IAISwitch.scss new file mode 100644 index 0000000000..af278dd2d0 --- /dev/null +++ b/frontend/src/common/components/IAISwitch.scss @@ -0,0 +1,33 @@ +.invokeai__switch-form-control { + .invokeai__switch-form-label { + display: flex; + column-gap: 1rem; + justify-content: space-between; + align-items: center; + color: var(--text-color-secondary); + font-size: 1rem; + margin-right: 0; + margin-bottom: 0.1rem; + white-space: nowrap; + width: auto; + + .invokeai__switch-root { + span { + background-color: var(--switch-bg-color); + span { + background-color: var(--white); + } + } + + &[data-checked] { + span { + background: var(--switch-bg-active-color); + + span { + background-color: var(--white); + } + } + } + } + } +} diff --git a/frontend/src/common/components/IAISwitch.tsx b/frontend/src/common/components/IAISwitch.tsx new file mode 100644 index 0000000000..26387ea472 --- /dev/null +++ b/frontend/src/common/components/IAISwitch.tsx @@ -0,0 +1,50 @@ +import { + FormControl, + FormControlProps, + FormLabel, + FormLabelProps, + Switch, + SwitchProps, +} from '@chakra-ui/react'; + +interface Props extends SwitchProps { + label?: string; + width?: string | number; + styleClass?: string; + formControlProps?: FormControlProps; + formLabelProps?: FormLabelProps; +} + +/** + * Customized Chakra FormControl + Switch multi-part component. + */ +const IAISwitch = (props: Props) => { + const { + label, + isDisabled = false, + width = 'auto', + formControlProps, + formLabelProps, + styleClass, + ...rest + } = props; + return ( + + + {label} + + + + ); +}; + +export default IAISwitch; diff --git a/frontend/src/common/components/ImageUploadOverlay.tsx b/frontend/src/common/components/ImageUploadOverlay.tsx new file mode 100644 index 0000000000..85da3253e1 --- /dev/null +++ b/frontend/src/common/components/ImageUploadOverlay.tsx @@ -0,0 +1,39 @@ +import { Heading } from '@chakra-ui/react'; +import { useHotkeys } from 'react-hotkeys-hook'; + +type ImageUploadOverlayProps = { + isDragAccept: boolean; + isDragReject: boolean; + overlaySecondaryText: string; + setIsHandlingUpload: (isHandlingUpload: boolean) => void; +}; + +const ImageUploadOverlay = (props: ImageUploadOverlayProps) => { + const { + isDragAccept, + isDragReject, + overlaySecondaryText, + setIsHandlingUpload, + } = props; + + useHotkeys('esc', () => { + setIsHandlingUpload(false); + }); + + return ( +
+ {isDragAccept && ( +
+ Upload Image{overlaySecondaryText} +
+ )} + {isDragReject && ( +
+ Invalid Upload + Must be single JPEG or PNG image +
+ )} +
+ ); +}; +export default ImageUploadOverlay; diff --git a/frontend/src/common/components/ImageUploader.scss b/frontend/src/common/components/ImageUploader.scss new file mode 100644 index 0000000000..5d0f6774bb --- /dev/null +++ b/frontend/src/common/components/ImageUploader.scss @@ -0,0 +1,75 @@ +.dropzone-container { + position: absolute; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + z-index: 999; + backdrop-filter: blur(20px); + + .dropzone-overlay { + opacity: 0.5; + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + row-gap: 1rem; + align-items: center; + justify-content: center; + background-color: var(--background-color); + + &.is-drag-accept { + box-shadow: inset 0 0 20rem 1rem var(--accent-color); + } + + &.is-drag-reject { + box-shadow: inset 0 0 20rem 1rem var(--status-bad-color); + } + + &.is-handling-upload { + box-shadow: inset 0 0 20rem 1rem var(--status-working-color); + } + } +} + +.image-uploader-button-outer { + min-width: 20rem; + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + border-radius: 0.5rem; + color: var(--tab-list-text-inactive); + background-color: var(--btn-grey); + + &:hover { + background-color: var(--btn-grey-hover); + } +} + +.image-upload-button-inner { + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; +} + +.image-upload-button { + display: flex; + flex-direction: column; + row-gap: 2rem; + align-items: center; + justify-content: center; + text-align: center; + + svg { + width: 4rem !important; + height: 4rem !important; + } + h2 { + font-size: 1.2rem !important; + } +} diff --git a/frontend/src/common/components/ImageUploader.tsx b/frontend/src/common/components/ImageUploader.tsx new file mode 100644 index 0000000000..d79bbbee8e --- /dev/null +++ b/frontend/src/common/components/ImageUploader.tsx @@ -0,0 +1,156 @@ +import { useCallback, ReactNode, useState, useEffect } from 'react'; +import { useAppDispatch, useAppSelector } from '../../app/store'; +import { FileRejection, useDropzone } from 'react-dropzone'; +import { useToast } from '@chakra-ui/react'; +import { uploadImage } from '../../app/socketio/actions'; +import { ImageUploadDestination, UploadImagePayload } from '../../app/invokeai'; +import { ImageUploaderTriggerContext } from '../../app/contexts/ImageUploaderTriggerContext'; +import { activeTabNameSelector } from '../../features/options/optionsSelectors'; +import { tabDict } from '../../features/tabs/InvokeTabs'; +import ImageUploadOverlay from './ImageUploadOverlay'; + +type ImageUploaderProps = { + children: ReactNode; +}; + +const ImageUploader = (props: ImageUploaderProps) => { + const { children } = props; + const dispatch = useAppDispatch(); + const activeTabName = useAppSelector(activeTabNameSelector); + const toast = useToast({}); + const [isHandlingUpload, setIsHandlingUpload] = useState(false); + + const fileRejectionCallback = useCallback( + (rejection: FileRejection) => { + setIsHandlingUpload(true); + const msg = rejection.errors.reduce( + (acc: string, cur: { message: string }) => acc + '\n' + cur.message, + '' + ); + toast({ + title: 'Upload failed', + description: msg, + status: 'error', + isClosable: true, + }); + }, + [toast] + ); + + const fileAcceptedCallback = useCallback( + (file: File) => { + setIsHandlingUpload(true); + const payload: UploadImagePayload = { file }; + if (['img2img', 'inpainting'].includes(activeTabName)) { + payload.destination = activeTabName as ImageUploadDestination; + } + dispatch(uploadImage(payload)); + }, + [dispatch, activeTabName] + ); + + const onDrop = useCallback( + (acceptedFiles: Array, fileRejections: Array) => { + fileRejections.forEach((rejection: FileRejection) => { + fileRejectionCallback(rejection); + }); + + acceptedFiles.forEach((file: File) => { + fileAcceptedCallback(file); + }); + }, + [fileAcceptedCallback, fileRejectionCallback] + ); + + const { + getRootProps, + getInputProps, + isDragAccept, + isDragReject, + isDragActive, + open, + } = useDropzone({ + accept: { 'image/png': ['.png'], 'image/jpeg': ['.jpg', '.jpeg', '.png'] }, + noClick: true, + onDrop, + onDragOver: () => setIsHandlingUpload(true), + maxFiles: 1, + }); + + useEffect(() => { + const pasteImageListener = (e: ClipboardEvent) => { + const dataTransferItemList = e.clipboardData?.items; + if (!dataTransferItemList) return; + + const imageItems: Array = []; + + for (const item of dataTransferItemList) { + if ( + item.kind === 'file' && + ['image/png', 'image/jpg'].includes(item.type) + ) { + imageItems.push(item); + } + } + + if (!imageItems.length) return; + + e.stopImmediatePropagation(); + + if (imageItems.length > 1) { + toast({ + description: + 'Multiple images pasted, may only upload one image at a time', + status: 'error', + isClosable: true, + }); + return; + } + + const file = imageItems[0].getAsFile(); + + if (!file) { + toast({ + description: 'Unable to load file', + status: 'error', + isClosable: true, + }); + return; + } + + const payload: UploadImagePayload = { file }; + if (['img2img', 'inpainting'].includes(activeTabName)) { + payload.destination = activeTabName as ImageUploadDestination; + } + + dispatch(uploadImage(payload)); + }; + document.addEventListener('paste', pasteImageListener); + return () => { + document.removeEventListener('paste', pasteImageListener); + }; + }, [dispatch, toast, activeTabName]); + + const overlaySecondaryText = ['img2img', 'inpainting'].includes(activeTabName) + ? ` to ${tabDict[activeTabName as keyof typeof tabDict].tooltip}` + : ``; + + return ( + +
+ + {children} + {isDragActive && isHandlingUpload && ( + + )} +
+
+ ); +}; + +export default ImageUploader; diff --git a/frontend/src/common/components/ImageUploaderButton.tsx b/frontend/src/common/components/ImageUploaderButton.tsx new file mode 100644 index 0000000000..373ab7ad21 --- /dev/null +++ b/frontend/src/common/components/ImageUploaderButton.tsx @@ -0,0 +1,31 @@ +import { Heading } from '@chakra-ui/react'; +import { useContext } from 'react'; +import { FaUpload } from 'react-icons/fa'; +import { ImageUploaderTriggerContext } from '../../app/contexts/ImageUploaderTriggerContext'; + +type ImageUploaderButtonProps = { + styleClass?: string; +}; + +const ImageUploaderButton = (props: ImageUploaderButtonProps) => { + const { styleClass } = props; + const open = useContext(ImageUploaderTriggerContext); + + const handleClickUpload = () => { + open && open(); + }; + + return ( +
+
+ + Click or Drag and Drop +
+
+ ); +}; + +export default ImageUploaderButton; diff --git a/frontend/src/common/components/ImageUploaderIconButton.tsx b/frontend/src/common/components/ImageUploaderIconButton.tsx new file mode 100644 index 0000000000..214e7b7b7c --- /dev/null +++ b/frontend/src/common/components/ImageUploaderIconButton.tsx @@ -0,0 +1,19 @@ +import { useContext } from 'react'; +import { FaUpload } from 'react-icons/fa'; +import { ImageUploaderTriggerContext } from '../../app/contexts/ImageUploaderTriggerContext'; +import IAIIconButton from './IAIIconButton'; + +const ImageUploaderIconButton = () => { + const openImageUploader = useContext(ImageUploaderTriggerContext); + + return ( + } + onClick={openImageUploader || undefined} + /> + ); +}; + +export default ImageUploaderIconButton; diff --git a/frontend/src/common/components/WorkInProgress/ImageToImageWIP.tsx b/frontend/src/common/components/WorkInProgress/ImageToImageWIP.tsx new file mode 100644 index 0000000000..20686087a0 --- /dev/null +++ b/frontend/src/common/components/WorkInProgress/ImageToImageWIP.tsx @@ -0,0 +1,16 @@ +import React from 'react'; +import Img2ImgPlaceHolder from '../../../assets/images/image2img.png'; + +export const ImageToImageWIP = () => { + return ( +
+ img2img_placeholder +

Image To Image

+

+ Image to Image is already available in the WebUI. You can access it from + the Text to Image - Advanced Options menu. A dedicated UI for Image To + Image will be released soon. +

+
+ ); +}; diff --git a/frontend/src/common/components/WorkInProgress/InpaintingWIP.tsx b/frontend/src/common/components/WorkInProgress/InpaintingWIP.tsx new file mode 100644 index 0000000000..1c029aa829 --- /dev/null +++ b/frontend/src/common/components/WorkInProgress/InpaintingWIP.tsx @@ -0,0 +1,14 @@ +import React from 'react'; + +export default function InpaintingWIP() { + return ( +
+

Inpainting

+

+ Inpainting is available as a part of the Invoke AI Command Line + Interface. A dedicated WebUI interface will be released in the near + future. +

+
+ ); +} diff --git a/frontend/src/common/components/WorkInProgress/NodesWIP.tsx b/frontend/src/common/components/WorkInProgress/NodesWIP.tsx new file mode 100644 index 0000000000..a09d3ccf22 --- /dev/null +++ b/frontend/src/common/components/WorkInProgress/NodesWIP.tsx @@ -0,0 +1,13 @@ +import React from 'react'; + +export default function NodesWIP() { + return ( +
+

Nodes

+

+ A node based system for the generation of images is under development + currently. Stay tuned for updates about this amazing feature. +

+
+ ); +} diff --git a/frontend/src/common/components/WorkInProgress/OutpaintingWIP.tsx b/frontend/src/common/components/WorkInProgress/OutpaintingWIP.tsx new file mode 100644 index 0000000000..fb913a40f7 --- /dev/null +++ b/frontend/src/common/components/WorkInProgress/OutpaintingWIP.tsx @@ -0,0 +1,14 @@ +import React from 'react'; + +export default function OutpaintingWIP() { + return ( +
+

Outpainting

+

+ Outpainting is available as a part of the Invoke AI Command Line + Interface. A dedicated WebUI interface will be released in the near + future. +

+
+ ); +} diff --git a/frontend/src/common/components/WorkInProgress/PostProcessingWIP.tsx b/frontend/src/common/components/WorkInProgress/PostProcessingWIP.tsx new file mode 100644 index 0000000000..5d270696b2 --- /dev/null +++ b/frontend/src/common/components/WorkInProgress/PostProcessingWIP.tsx @@ -0,0 +1,24 @@ +import React from 'react'; + +export const PostProcessingWIP = () => { + return ( +
+

Post Processing

+

+ Invoke AI offers a wide variety of post processing features. Image + Upscaling and Face Restoration are already available in the WebUI. You + can access them from the Advanced Options menu of the Text To Image and + Image To Image tabs. You can also process images directly, using the + image action buttons above the main image display. +

+

+ A dedicated UI will be released soon to facilitate more advanced post + processing workflows. +

+

+ The Invoke AI Command Line Interface offers various other features + including Embiggen. +

+
+ ); +}; diff --git a/frontend/src/common/components/WorkInProgress/WorkInProgress.scss b/frontend/src/common/components/WorkInProgress/WorkInProgress.scss new file mode 100644 index 0000000000..2a17c7bd0a --- /dev/null +++ b/frontend/src/common/components/WorkInProgress/WorkInProgress.scss @@ -0,0 +1,24 @@ +@use '../../../styles/Mixins/' as *; + +.work-in-progress { + display: grid; + width: 100%; + height: $app-content-height; + grid-auto-rows: max-content; + background-color: var(--background-color-secondary); + border-radius: 0.4rem; + place-content: center; + place-items: center; + row-gap: 1rem; + + h1 { + font-size: 2rem; + font-weight: bold; + } + + p { + text-align: center; + max-width: 50rem; + color: var(--subtext-color-bright); + } +} diff --git a/frontend/src/common/components/radix-ui/IAISlider.scss b/frontend/src/common/components/radix-ui/IAISlider.scss new file mode 100644 index 0000000000..4a1418392e --- /dev/null +++ b/frontend/src/common/components/radix-ui/IAISlider.scss @@ -0,0 +1,62 @@ +.invokeai__slider-root { + position: relative; + display: flex; + align-items: center; + user-select: none; + touch-action: none; + width: 200px; + + &[data-orientation='horizontal'] { + height: 20px; + } + + &[data-orientation='vertical'] { + width: 20px; + height: 200px; + } + + .invokeai__slider-track { + background-color: black; + position: relative; + flex-grow: 1; + border-radius: 9999px; + + &[data-orientation='horizontal'] { + height: 0.25rem; + } + + &[data-orientation='vertical'] { + width: 0.25rem; + } + + .invokeai__slider-range { + position: absolute; + background-color: white; + border-radius: 9999px; + height: 100%; + } + } + + .invokeai__slider-thumb { + display: flex; + align-items: center; + + .invokeai__slider-thumb-div { + all: unset; + display: block; + width: 1rem; + height: 1rem; + background-color: white; + box-shadow: 0 2px 10px rgba(0, 2, 10, 0.3); + border-radius: 100%; + + &:hover { + background-color: violet; + } + + &:focus { + box-shadow: 0 0 0 5px rgba(0, 2, 10, 0.3); + } + } + } +} diff --git a/frontend/src/common/components/radix-ui/IAISlider.tsx b/frontend/src/common/components/radix-ui/IAISlider.tsx new file mode 100644 index 0000000000..7ad1a21df5 --- /dev/null +++ b/frontend/src/common/components/radix-ui/IAISlider.tsx @@ -0,0 +1,46 @@ +import { Tooltip } from '@chakra-ui/react'; +import * as Slider from '@radix-ui/react-slider'; +import React from 'react'; +import IAITooltip from './IAITooltip'; + +type IAISliderProps = Slider.SliderProps & { + value: number[]; + tooltipLabel?: string; + orientation?: 'horizontal' | 'vertial'; + trackProps?: Slider.SliderTrackProps; + rangeProps?: Slider.SliderRangeProps; + thumbProps?: Slider.SliderThumbProps; +}; + +const _IAISlider = (props: IAISliderProps) => { + const { + value, + tooltipLabel, + orientation, + trackProps, + rangeProps, + thumbProps, + ...rest + } = props; + return ( + + + + + + +
+ {/*}> + {value && value[0]} + */} + + + + ); +}; + +export default _IAISlider; diff --git a/frontend/src/common/components/radix-ui/IAITooltip.scss b/frontend/src/common/components/radix-ui/IAITooltip.scss new file mode 100644 index 0000000000..7d0ca8455c --- /dev/null +++ b/frontend/src/common/components/radix-ui/IAITooltip.scss @@ -0,0 +1,8 @@ +.invokeai__tooltip-content { + padding: 0.5rem; + background-color: grey; + border-radius: 0.25rem; + .invokeai__tooltip-arrow { + background-color: grey; + } +} diff --git a/frontend/src/common/components/radix-ui/IAITooltip.tsx b/frontend/src/common/components/radix-ui/IAITooltip.tsx new file mode 100644 index 0000000000..18fd908a93 --- /dev/null +++ b/frontend/src/common/components/radix-ui/IAITooltip.tsx @@ -0,0 +1,35 @@ +import * as Tooltip from '@radix-ui/react-tooltip'; +import { ReactNode } from 'react'; + +type IAITooltipProps = Tooltip.TooltipProps & { + trigger: ReactNode; + children: ReactNode; + triggerProps?: Tooltip.TooltipTriggerProps; + contentProps?: Tooltip.TooltipContentProps; + arrowProps?: Tooltip.TooltipArrowProps; +}; + +const IAITooltip = (props: IAITooltipProps) => { + const { trigger, children, triggerProps, contentProps, arrowProps, ...rest } = + props; + + return ( + + + {trigger} + + {e.preventDefault()}} + className="invokeai__tooltip-content" + > + + {children} + + + + + ); +}; + +export default IAITooltip; diff --git a/frontend/src/common/hooks/useClickOutsideWatcher.ts b/frontend/src/common/hooks/useClickOutsideWatcher.ts new file mode 100644 index 0000000000..88a5a23585 --- /dev/null +++ b/frontend/src/common/hooks/useClickOutsideWatcher.ts @@ -0,0 +1,25 @@ +import { RefObject, useEffect } from 'react'; + +const useClickOutsideWatcher = ( + ref: RefObject, + callback: () => void, + req = true +) => { + useEffect(() => { + function handleClickOutside(e: MouseEvent) { + if (ref.current && !ref.current.contains(e.target as Node)) { + callback(); + } + } + if (req) { + document.addEventListener('mousedown', handleClickOutside); + } + return () => { + if (req) { + document.removeEventListener('mousedown', handleClickOutside); + } + }; + }, [ref, req, callback]); +}; + +export default useClickOutsideWatcher; diff --git a/frontend/src/common/icons/ImageToImageIcon.tsx b/frontend/src/common/icons/ImageToImageIcon.tsx new file mode 100644 index 0000000000..3c4ad0892a --- /dev/null +++ b/frontend/src/common/icons/ImageToImageIcon.tsx @@ -0,0 +1,17 @@ +import { createIcon } from "@chakra-ui/react"; + +const ImageToImageIcon = createIcon({ + displayName: 'ImageToImageIcon', + viewBox: '0 0 3543 3543', + path: ( + + + + ), +}); +export default ImageToImageIcon; diff --git a/frontend/src/common/icons/InpaintIcon.tsx b/frontend/src/common/icons/InpaintIcon.tsx new file mode 100644 index 0000000000..4f412e96bb --- /dev/null +++ b/frontend/src/common/icons/InpaintIcon.tsx @@ -0,0 +1,16 @@ +import { createIcon } from '@chakra-ui/react'; + +const InpaintIcon = createIcon({ + displayName: 'InpaintIcon', + viewBox: '0 0 3543 3543', + path: ( + + ), +}); + +export default InpaintIcon; diff --git a/frontend/src/common/icons/NodesIcon.tsx b/frontend/src/common/icons/NodesIcon.tsx new file mode 100644 index 0000000000..95a8b4102b --- /dev/null +++ b/frontend/src/common/icons/NodesIcon.tsx @@ -0,0 +1,16 @@ +import { createIcon } from "@chakra-ui/react"; + +const NodesIcon = createIcon({ + displayName: 'NodesIcon', + viewBox: '0 0 3543 3543', + path: ( + + ), +}); + +export default NodesIcon; diff --git a/frontend/src/common/icons/OutpaintIcon.tsx b/frontend/src/common/icons/OutpaintIcon.tsx new file mode 100644 index 0000000000..c01a61c932 --- /dev/null +++ b/frontend/src/common/icons/OutpaintIcon.tsx @@ -0,0 +1,16 @@ +import { createIcon } from "@chakra-ui/react"; + +const OutpaintIcon = createIcon({ + displayName: 'OutpaintIcon', + viewBox: '0 0 3543 3543', + path: ( + + ), +}); + +export default OutpaintIcon; diff --git a/frontend/src/common/icons/PostprocessingIcon.tsx b/frontend/src/common/icons/PostprocessingIcon.tsx new file mode 100644 index 0000000000..29f474b079 --- /dev/null +++ b/frontend/src/common/icons/PostprocessingIcon.tsx @@ -0,0 +1,16 @@ +import { createIcon } from '@chakra-ui/react'; + +const PostprocessingIcon = createIcon({ + displayName: 'PostprocessingIcon', + viewBox: '0 0 3543 3543', + path: ( + + ), +}); + +export default PostprocessingIcon; diff --git a/frontend/src/common/icons/TextToImageIcon.tsx b/frontend/src/common/icons/TextToImageIcon.tsx new file mode 100644 index 0000000000..97e84fdf19 --- /dev/null +++ b/frontend/src/common/icons/TextToImageIcon.tsx @@ -0,0 +1,18 @@ +import { createIcon } from "@chakra-ui/react"; + +const TextToImageIcon = createIcon({ + displayName: 'TextToImageIcon', + viewBox: '0 0 3543 3543', + path: ( + + + + ), +}); + +export default TextToImageIcon; diff --git a/frontend/src/common/icons/design_files/BaseImage.afdesign b/frontend/src/common/icons/design_files/BaseImage.afdesign new file mode 100644 index 0000000000..5c1ff31286 Binary files /dev/null and b/frontend/src/common/icons/design_files/BaseImage.afdesign differ diff --git a/frontend/src/common/icons/design_files/ImageToImage.afdesign b/frontend/src/common/icons/design_files/ImageToImage.afdesign new file mode 100644 index 0000000000..c744eeab3c Binary files /dev/null and b/frontend/src/common/icons/design_files/ImageToImage.afdesign differ diff --git a/frontend/src/common/icons/design_files/ImageToImage.svg b/frontend/src/common/icons/design_files/ImageToImage.svg new file mode 100644 index 0000000000..14842fabbe --- /dev/null +++ b/frontend/src/common/icons/design_files/ImageToImage.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/frontend/src/common/icons/design_files/Inpaint.afdesign b/frontend/src/common/icons/design_files/Inpaint.afdesign new file mode 100644 index 0000000000..8447c567e1 Binary files /dev/null and b/frontend/src/common/icons/design_files/Inpaint.afdesign differ diff --git a/frontend/src/common/icons/design_files/Inpaint.svg b/frontend/src/common/icons/design_files/Inpaint.svg new file mode 100644 index 0000000000..d5bc25a777 --- /dev/null +++ b/frontend/src/common/icons/design_files/Inpaint.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/frontend/src/common/icons/design_files/Nodes.afdesign b/frontend/src/common/icons/design_files/Nodes.afdesign new file mode 100644 index 0000000000..7972051171 Binary files /dev/null and b/frontend/src/common/icons/design_files/Nodes.afdesign differ diff --git a/frontend/src/common/icons/design_files/Nodes.svg b/frontend/src/common/icons/design_files/Nodes.svg new file mode 100644 index 0000000000..51785024e1 --- /dev/null +++ b/frontend/src/common/icons/design_files/Nodes.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/src/common/icons/design_files/Outpaint.afdesign b/frontend/src/common/icons/design_files/Outpaint.afdesign new file mode 100644 index 0000000000..d9dccfb34b Binary files /dev/null and b/frontend/src/common/icons/design_files/Outpaint.afdesign differ diff --git a/frontend/src/common/icons/design_files/Outpaint.svg b/frontend/src/common/icons/design_files/Outpaint.svg new file mode 100644 index 0000000000..042b89864e --- /dev/null +++ b/frontend/src/common/icons/design_files/Outpaint.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/src/common/icons/design_files/Postprocessing.afdesign b/frontend/src/common/icons/design_files/Postprocessing.afdesign new file mode 100644 index 0000000000..ca28156d0e Binary files /dev/null and b/frontend/src/common/icons/design_files/Postprocessing.afdesign differ diff --git a/frontend/src/common/icons/design_files/Postprocessing.svg b/frontend/src/common/icons/design_files/Postprocessing.svg new file mode 100644 index 0000000000..f45b81e6b1 --- /dev/null +++ b/frontend/src/common/icons/design_files/Postprocessing.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/src/common/icons/design_files/TextToImage.afdesign b/frontend/src/common/icons/design_files/TextToImage.afdesign new file mode 100644 index 0000000000..f88d56034e Binary files /dev/null and b/frontend/src/common/icons/design_files/TextToImage.afdesign differ diff --git a/frontend/src/common/icons/design_files/TextToImage.svg b/frontend/src/common/icons/design_files/TextToImage.svg new file mode 100644 index 0000000000..3584538485 --- /dev/null +++ b/frontend/src/common/icons/design_files/TextToImage.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/frontend/src/common/util/parameterTranslation.ts b/frontend/src/common/util/parameterTranslation.ts new file mode 100644 index 0000000000..d1f52cd9ac --- /dev/null +++ b/frontend/src/common/util/parameterTranslation.ts @@ -0,0 +1,179 @@ +import { NUMPY_RAND_MAX, NUMPY_RAND_MIN } from '../../app/constants'; +import { OptionsState } from '../../features/options/optionsSlice'; +import { SystemState } from '../../features/system/systemSlice'; + +import { stringToSeedWeightsArray } from './seedWeightPairs'; +import randomInt from './randomInt'; +import { InvokeTabName } from '../../features/tabs/InvokeTabs'; +import { InpaintingState } from '../../features/tabs/Inpainting/inpaintingSlice'; +import generateMask from '../../features/tabs/Inpainting/util/generateMask'; + +export type FrontendToBackendParametersConfig = { + generationMode: InvokeTabName; + optionsState: OptionsState; + inpaintingState: InpaintingState; + systemState: SystemState; + imageToProcessUrl?: string; + maskImageElement?: HTMLImageElement; +}; + +/** + * Translates/formats frontend state into parameters suitable + * for consumption by the API. + */ +export const frontendToBackendParameters = ( + config: FrontendToBackendParametersConfig +): { [key: string]: any } => { + const { + generationMode, + optionsState, + inpaintingState, + systemState, + imageToProcessUrl, + maskImageElement, + } = config; + + const { + prompt, + iterations, + steps, + cfgScale, + threshold, + perlin, + height, + width, + sampler, + seed, + seamless, + hiresFix, + img2imgStrength, + initialImage, + shouldFitToWidthHeight, + shouldGenerateVariations, + variationAmount, + seedWeights, + shouldRunESRGAN, + upscalingLevel, + upscalingStrength, + shouldRunFacetool, + facetoolStrength, + codeformerFidelity, + facetoolType, + shouldRandomizeSeed, + } = optionsState; + + const { shouldDisplayInProgressType, saveIntermediatesInterval } = + systemState; + + const generationParameters: { [k: string]: any } = { + prompt, + iterations: + shouldRandomizeSeed || shouldGenerateVariations ? iterations : 1, + steps, + cfg_scale: cfgScale, + threshold, + perlin, + height, + width, + sampler_name: sampler, + seed, + progress_images: shouldDisplayInProgressType === 'full-res', + progress_latents: shouldDisplayInProgressType === 'latents', + save_intermediates: saveIntermediatesInterval, + }; + + generationParameters.seed = shouldRandomizeSeed + ? randomInt(NUMPY_RAND_MIN, NUMPY_RAND_MAX) + : seed; + + // parameters common to txt2img and img2img + if (['txt2img', 'img2img'].includes(generationMode)) { + generationParameters.seamless = seamless; + generationParameters.hires_fix = hiresFix; + } + + // img2img exclusive parameters + if (generationMode === 'img2img' && initialImage) { + generationParameters.init_img = + typeof initialImage === 'string' ? initialImage : initialImage.url; + generationParameters.strength = img2imgStrength; + generationParameters.fit = shouldFitToWidthHeight; + } + + // inpainting exclusive parameters + if (generationMode === 'inpainting' && maskImageElement) { + const { + lines, + boundingBoxCoordinate, + boundingBoxDimensions, + inpaintReplace, + shouldUseInpaintReplace, + } = inpaintingState; + + const boundingBox = { + ...boundingBoxCoordinate, + ...boundingBoxDimensions, + }; + + generationParameters.init_img = imageToProcessUrl; + generationParameters.strength = img2imgStrength; + generationParameters.fit = false; + + const { maskDataURL, isMaskEmpty } = generateMask( + maskImageElement, + lines, + boundingBox + ); + + generationParameters.is_mask_empty = isMaskEmpty; + + generationParameters.init_mask = maskDataURL.split( + 'data:image/png;base64,' + )[1]; + + if (shouldUseInpaintReplace) { + generationParameters.inpaint_replace = inpaintReplace; + } + + generationParameters.bounding_box = boundingBox; + + // TODO: The server metadata generation needs to be changed to fix this. + generationParameters.progress_images = false; + } + + if (shouldGenerateVariations) { + generationParameters.variation_amount = variationAmount; + if (seedWeights) { + generationParameters.with_variations = + stringToSeedWeightsArray(seedWeights); + } + } else { + generationParameters.variation_amount = 0; + } + + let esrganParameters: false | { [k: string]: any } = false; + let facetoolParameters: false | { [k: string]: any } = false; + + if (shouldRunESRGAN) { + esrganParameters = { + level: upscalingLevel, + strength: upscalingStrength, + }; + } + + if (shouldRunFacetool) { + facetoolParameters = { + type: facetoolType, + strength: facetoolStrength, + }; + if (facetoolType === 'codeformer') { + facetoolParameters.codeformer_fidelity = codeformerFidelity; + } + } + + return { + generationParameters, + esrganParameters, + facetoolParameters, + }; +}; diff --git a/frontend/src/common/util/promptToString.ts b/frontend/src/common/util/promptToString.ts new file mode 100644 index 0000000000..d84a24acf8 --- /dev/null +++ b/frontend/src/common/util/promptToString.ts @@ -0,0 +1,16 @@ +import * as InvokeAI from '../../app/invokeai'; + +const promptToString = (prompt: InvokeAI.Prompt): string => { + if (prompt.length === 1) { + return prompt[0].prompt; + } + + return prompt + .map( + (promptItem: InvokeAI.PromptItem): string => + `${promptItem.prompt}:${promptItem.weight}` + ) + .join(' '); +}; + +export default promptToString; diff --git a/frontend/src/common/util/randomInt.ts b/frontend/src/common/util/randomInt.ts new file mode 100644 index 0000000000..078186f3da --- /dev/null +++ b/frontend/src/common/util/randomInt.ts @@ -0,0 +1,5 @@ +const randomInt = (min: number, max: number): number => { + return Math.floor(Math.random() * (max - min + 1) + min); +}; + +export default randomInt; diff --git a/frontend/src/common/util/roundDownToMultiple.ts b/frontend/src/common/util/roundDownToMultiple.ts new file mode 100644 index 0000000000..850b235629 --- /dev/null +++ b/frontend/src/common/util/roundDownToMultiple.ts @@ -0,0 +1,7 @@ +export const roundDownToMultiple = (num: number, multiple: number): number => { + return Math.floor(num / multiple) * multiple; +}; + +export const roundToMultiple = (num: number, multiple: number): number => { + return Math.round(num / multiple) * multiple; +}; diff --git a/frontend/src/common/util/seedWeightPairs.ts b/frontend/src/common/util/seedWeightPairs.ts new file mode 100644 index 0000000000..9c024e1e1a --- /dev/null +++ b/frontend/src/common/util/seedWeightPairs.ts @@ -0,0 +1,68 @@ +import * as InvokeAI from '../../app/invokeai'; + +export const stringToSeedWeights = ( + string: string +): InvokeAI.SeedWeights | boolean => { + const stringPairs = string.split(','); + const arrPairs = stringPairs.map((p) => p.split(':')); + const pairs = arrPairs.map((p: Array): InvokeAI.SeedWeightPair => { + return { seed: Number(p[0]), weight: Number(p[1]) }; + }); + + if (!validateSeedWeights(pairs)) { + return false; + } + + return pairs; +}; + +export const validateSeedWeights = ( + seedWeights: InvokeAI.SeedWeights | string +): boolean => { + return typeof seedWeights === 'string' + ? Boolean(stringToSeedWeights(seedWeights)) + : Boolean( + seedWeights.length && + !seedWeights.some((pair: InvokeAI.SeedWeightPair) => { + const { seed, weight } = pair; + const isSeedValid = !isNaN(parseInt(seed.toString(), 10)); + const isWeightValid = + !isNaN(parseInt(weight.toString(), 10)) && + weight >= 0 && + weight <= 1; + return !(isSeedValid && isWeightValid); + }) + ); +}; + +export const seedWeightsToString = ( + seedWeights: InvokeAI.SeedWeights +): string => { + return seedWeights.reduce((acc, pair, i, arr) => { + const { seed, weight } = pair; + acc += `${seed}:${weight}`; + if (i !== arr.length - 1) { + acc += ','; + } + return acc; + }, ''); +}; + +export const seedWeightsToArray = ( + seedWeights: InvokeAI.SeedWeights +): Array> => { + return seedWeights.map((pair: InvokeAI.SeedWeightPair) => [ + pair.seed, + pair.weight, + ]); +}; + +export const stringToSeedWeightsArray = ( + string: string +): Array> => { + const stringPairs = string.split(','); + const arrPairs = stringPairs.map((p) => p.split(':')); + return arrPairs.map( + (p: Array): Array => [parseInt(p[0]), parseFloat(p[1])] + ); +}; diff --git a/frontend/src/features/gallery/CurrentImageButtons.scss b/frontend/src/features/gallery/CurrentImageButtons.scss new file mode 100644 index 0000000000..982fcc4867 --- /dev/null +++ b/frontend/src/features/gallery/CurrentImageButtons.scss @@ -0,0 +1,25 @@ +.current-image-options { + width: 100%; + display: flex; + justify-content: center; + align-items: center; + column-gap: 0.5em; + + .current-image-send-to-popover, + .current-image-postprocessing-popover { + display: flex; + flex-direction: column; + row-gap: 0.5rem; + max-width: 25rem; + } + + .chakra-popover__popper { + z-index: 11; + } + + .delete-image-btn { + svg { + fill: var(--btn-delete-image); + } + } +} diff --git a/frontend/src/features/gallery/CurrentImageButtons.tsx b/frontend/src/features/gallery/CurrentImageButtons.tsx new file mode 100644 index 0000000000..b95e16dda9 --- /dev/null +++ b/frontend/src/features/gallery/CurrentImageButtons.tsx @@ -0,0 +1,480 @@ +import { createSelector } from '@reduxjs/toolkit'; +import { isEqual } from 'lodash'; + +import { useAppDispatch, useAppSelector } from '../../app/store'; +import { RootState } from '../../app/store'; +import { + OptionsState, + setActiveTab, + setAllParameters, + setInitialImage, + setPrompt, + setSeed, + setShouldShowImageDetails, +} from '../options/optionsSlice'; +import DeleteImageModal from './DeleteImageModal'; +import { SystemState } from '../system/systemSlice'; +import IAIButton from '../../common/components/IAIButton'; +import { runESRGAN, runFacetool } from '../../app/socketio/actions'; +import IAIIconButton from '../../common/components/IAIIconButton'; +import UpscaleOptions from '../options/AdvancedOptions/Upscale/UpscaleOptions'; +import FaceRestoreOptions from '../options/AdvancedOptions/FaceRestore/FaceRestoreOptions'; +import { useHotkeys } from 'react-hotkeys-hook'; +import { ButtonGroup, Link, useClipboard, useToast } from '@chakra-ui/react'; +import { + FaAsterisk, + FaCode, + FaCopy, + FaDownload, + FaExpandArrowsAlt, + FaGrinStars, + FaQuoteRight, + FaSeedling, + FaShare, + FaShareAlt, + FaTrash, +} from 'react-icons/fa'; +import { + setImageToInpaint, + setNeedsCache, +} from '../tabs/Inpainting/inpaintingSlice'; +import { GalleryState } from './gallerySlice'; +import { activeTabNameSelector } from '../options/optionsSelectors'; +import IAIPopover from '../../common/components/IAIPopover'; + +const systemSelector = createSelector( + [ + (state: RootState) => state.system, + (state: RootState) => state.options, + (state: RootState) => state.gallery, + activeTabNameSelector, + ], + ( + system: SystemState, + options: OptionsState, + gallery: GalleryState, + activeTabName + ) => { + const { isProcessing, isConnected, isGFPGANAvailable, isESRGANAvailable } = + system; + + const { upscalingLevel, facetoolStrength, shouldShowImageDetails } = + options; + + const { intermediateImage, currentImage } = gallery; + + return { + isProcessing, + isConnected, + isGFPGANAvailable, + isESRGANAvailable, + upscalingLevel, + facetoolStrength, + shouldDisableToolbarButtons: Boolean(intermediateImage) || !currentImage, + currentImage, + shouldShowImageDetails, + activeTabName, + }; + }, + { + memoizeOptions: { + resultEqualityCheck: isEqual, + }, + } +); + +/** + * Row of buttons for common actions: + * Use as init image, use all params, use seed, upscale, fix faces, details, delete. + */ +const CurrentImageButtons = () => { + const dispatch = useAppDispatch(); + const { + isProcessing, + isConnected, + isGFPGANAvailable, + isESRGANAvailable, + upscalingLevel, + facetoolStrength, + shouldDisableToolbarButtons, + shouldShowImageDetails, + currentImage, + } = useAppSelector(systemSelector); + + const { onCopy } = useClipboard( + currentImage ? window.location.toString() + currentImage.url : '' + ); + + const toast = useToast(); + + const handleClickUseAsInitialImage = () => { + if (!currentImage) return; + dispatch(setInitialImage(currentImage)); + dispatch(setActiveTab('img2img')); + }; + + const handleCopyImageLink = () => { + onCopy(); + toast({ + title: 'Image Link Copied', + status: 'success', + duration: 2500, + isClosable: true, + }); + }; + + useHotkeys( + 'shift+i', + () => { + if (currentImage) { + handleClickUseAsInitialImage(); + toast({ + title: 'Sent To Image To Image', + status: 'success', + duration: 2500, + isClosable: true, + }); + } else { + toast({ + title: 'No Image Loaded', + description: 'No image found to send to image to image module.', + status: 'error', + duration: 2500, + isClosable: true, + }); + } + }, + [currentImage] + ); + + const handleClickUseAllParameters = () => { + if (!currentImage) return; + currentImage.metadata && dispatch(setAllParameters(currentImage.metadata)); + }; + + useHotkeys( + 'a', + () => { + if ( + ['txt2img', 'img2img'].includes(currentImage?.metadata?.image?.type) + ) { + handleClickUseAllParameters(); + toast({ + title: 'Parameters Set', + status: 'success', + duration: 2500, + isClosable: true, + }); + } else { + toast({ + title: 'Parameters Not Set', + description: 'No metadata found for this image.', + status: 'error', + duration: 2500, + isClosable: true, + }); + } + }, + [currentImage] + ); + + const handleClickUseSeed = () => { + currentImage?.metadata && + dispatch(setSeed(currentImage.metadata.image.seed)); + }; + + useHotkeys( + 's', + () => { + if (currentImage?.metadata?.image?.seed) { + handleClickUseSeed(); + toast({ + title: 'Seed Set', + status: 'success', + duration: 2500, + isClosable: true, + }); + } else { + toast({ + title: 'Seed Not Set', + description: 'Could not find seed for this image.', + status: 'error', + duration: 2500, + isClosable: true, + }); + } + }, + [currentImage] + ); + + const handleClickUsePrompt = () => + currentImage?.metadata?.image?.prompt && + dispatch(setPrompt(currentImage.metadata.image.prompt)); + + useHotkeys( + 'p', + () => { + if (currentImage?.metadata?.image?.prompt) { + handleClickUsePrompt(); + toast({ + title: 'Prompt Set', + status: 'success', + duration: 2500, + isClosable: true, + }); + } else { + toast({ + title: 'Prompt Not Set', + description: 'Could not find prompt for this image.', + status: 'error', + duration: 2500, + isClosable: true, + }); + } + }, + [currentImage] + ); + + const handleClickUpscale = () => { + currentImage && dispatch(runESRGAN(currentImage)); + }; + + useHotkeys( + 'u', + () => { + if ( + isESRGANAvailable && + !shouldDisableToolbarButtons && + isConnected && + !isProcessing && + upscalingLevel + ) { + handleClickUpscale(); + } else { + toast({ + title: 'Upscaling Failed', + status: 'error', + duration: 2500, + isClosable: true, + }); + } + }, + [ + currentImage, + isESRGANAvailable, + shouldDisableToolbarButtons, + isConnected, + isProcessing, + upscalingLevel, + ] + ); + + const handleClickFixFaces = () => { + currentImage && dispatch(runFacetool(currentImage)); + }; + + useHotkeys( + 'r', + () => { + if ( + isGFPGANAvailable && + !shouldDisableToolbarButtons && + isConnected && + !isProcessing && + facetoolStrength + ) { + handleClickFixFaces(); + } else { + toast({ + title: 'Face Restoration Failed', + status: 'error', + duration: 2500, + isClosable: true, + }); + } + }, + [ + currentImage, + isGFPGANAvailable, + shouldDisableToolbarButtons, + isConnected, + isProcessing, + facetoolStrength, + ] + ); + + const handleClickShowImageDetails = () => + dispatch(setShouldShowImageDetails(!shouldShowImageDetails)); + + const handleSendToInpainting = () => { + if (!currentImage) return; + + dispatch(setImageToInpaint(currentImage)); + + dispatch(setActiveTab('inpainting')); + dispatch(setNeedsCache(true)); + + toast({ + title: 'Sent to Inpainting', + status: 'success', + duration: 2500, + isClosable: true, + }); + }; + + useHotkeys( + 'i', + () => { + if (currentImage) { + handleClickShowImageDetails(); + } else { + toast({ + title: 'Failed to load metadata', + status: 'error', + duration: 2500, + isClosable: true, + }); + } + }, + [currentImage, shouldShowImageDetails] + ); + + return ( +
+ + } /> + } + > +
+ } + > + Send to Image to Image + + } + > + Send to Inpainting + + } + > + Copy Link to Image + + + } size={'sm'}> + + Download Image + + +
+
+
+ + + } + tooltip="Use Prompt" + aria-label="Use Prompt" + isDisabled={!currentImage?.metadata?.image?.prompt} + onClick={handleClickUsePrompt} + /> + + } + tooltip="Use Seed" + aria-label="Use Seed" + isDisabled={!currentImage?.metadata?.image?.seed} + onClick={handleClickUseSeed} + /> + + } + tooltip="Use All" + aria-label="Use All" + isDisabled={ + !['txt2img', 'img2img'].includes( + currentImage?.metadata?.image?.type + ) + } + onClick={handleClickUseAllParameters} + /> + + + + } aria-label="Restore Faces" /> + } + > +
+ + + Restore Faces + +
+
+ + } aria-label="Upscale" /> + } + > +
+ + + Upscale Image + +
+
+
+ + } + tooltip="Details" + aria-label="Details" + data-selected={shouldShowImageDetails} + onClick={handleClickShowImageDetails} + /> + + + } + tooltip="Delete Image" + aria-label="Delete Image" + isDisabled={!currentImage || !isConnected || isProcessing} + className="delete-image-btn" + /> + +
+ ); +}; + +export default CurrentImageButtons; diff --git a/frontend/src/features/gallery/CurrentImageDisplay.scss b/frontend/src/features/gallery/CurrentImageDisplay.scss new file mode 100644 index 0000000000..7999ebe06b --- /dev/null +++ b/frontend/src/features/gallery/CurrentImageDisplay.scss @@ -0,0 +1,84 @@ +@use '../../styles/Mixins/' as *; + +.current-image-area { + display: flex; + flex-direction: column; + height: 100%; + row-gap: 1rem; + background-color: var(--background-color-secondary); + border-radius: 0.5rem; +} + +.current-image-preview { + position: relative; + justify-content: center; + align-items: center; + display: flex; + width: 100%; + height: 100%; + + img { + background-color: var(--img2img-img-bg-color); + border-radius: 0.5rem; + object-fit: contain; + max-width: 100%; + max-height: 100%; + height: auto; + position: absolute; + } +} + +.current-image-metadata { + grid-area: current-image-preview; +} + +.current-image-next-prev-buttons { + grid-area: current-image-content; + display: flex; + justify-content: space-between; + z-index: 1; + height: 100%; + width: 100%; + pointer-events: none; +} + +.next-prev-button-trigger-area { + width: 7rem; + height: 100%; + width: 15%; + display: grid; + align-items: center; + pointer-events: auto; + + &.prev-button-trigger-area { + justify-content: flex-start; + } + + &.next-button-trigger-area { + justify-content: flex-end; + } +} + +.next-prev-button { + font-size: 4rem; + fill: var(--white); + filter: drop-shadow(0 0 1rem var(--text-color-secondary)); + opacity: 70%; +} + +.current-image-display-placeholder { + background-color: var(--background-color-secondary); + display: grid; + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + border-radius: 0.5rem; + + svg { + width: 10rem; + height: 10rem; + color: var(--svg-color); + } +} diff --git a/frontend/src/features/gallery/CurrentImageDisplay.tsx b/frontend/src/features/gallery/CurrentImageDisplay.tsx new file mode 100644 index 0000000000..d784096f7c --- /dev/null +++ b/frontend/src/features/gallery/CurrentImageDisplay.tsx @@ -0,0 +1,58 @@ +import { RootState, useAppSelector } from '../../app/store'; +import CurrentImageButtons from './CurrentImageButtons'; +import { MdPhoto } from 'react-icons/md'; +import CurrentImagePreview from './CurrentImagePreview'; +import { GalleryState } from './gallerySlice'; +import { OptionsState } from '../options/optionsSlice'; +import _ from 'lodash'; +import { createSelector } from '@reduxjs/toolkit'; +import { activeTabNameSelector } from '../options/optionsSelectors'; + +export const currentImageDisplaySelector = createSelector( + [ + (state: RootState) => state.gallery, + (state: RootState) => state.options, + activeTabNameSelector, + ], + (gallery: GalleryState, options: OptionsState, activeTabName) => { + const { currentImage, intermediateImage } = gallery; + const { shouldShowImageDetails } = options; + + return { + activeTabName, + shouldShowImageDetails, + hasAnImageToDisplay: currentImage || intermediateImage, + }; + }, + { + memoizeOptions: { + resultEqualityCheck: _.isEqual, + }, + } +); + +/** + * Displays the current image if there is one, plus associated actions. + */ +const CurrentImageDisplay = () => { + const { hasAnImageToDisplay, activeTabName } = useAppSelector( + currentImageDisplaySelector + ); + + return ( +
+ {hasAnImageToDisplay ? ( + <> + + + + ) : ( +
+ +
+ )} +
+ ); +}; + +export default CurrentImageDisplay; diff --git a/frontend/src/features/gallery/CurrentImagePreview.tsx b/frontend/src/features/gallery/CurrentImagePreview.tsx new file mode 100644 index 0000000000..708361ca7f --- /dev/null +++ b/frontend/src/features/gallery/CurrentImagePreview.tsx @@ -0,0 +1,130 @@ +import { IconButton, Image } from '@chakra-ui/react'; +import { useState } from 'react'; +import { FaAngleLeft, FaAngleRight } from 'react-icons/fa'; +import { RootState, useAppDispatch, useAppSelector } from '../../app/store'; +import { + GalleryCategory, + GalleryState, + selectNextImage, + selectPrevImage, +} from './gallerySlice'; +import { createSelector } from '@reduxjs/toolkit'; +import _ from 'lodash'; +import { OptionsState } from '../options/optionsSlice'; +import ImageMetadataViewer from './ImageMetaDataViewer/ImageMetadataViewer'; + +export const imagesSelector = createSelector( + [(state: RootState) => state.gallery, (state: RootState) => state.options], + (gallery: GalleryState, options: OptionsState) => { + const { currentCategory, currentImage, intermediateImage } = gallery; + const { shouldShowImageDetails } = options; + + const tempImages = + gallery.categories[ + currentImage ? (currentImage.category as GalleryCategory) : 'result' + ].images; + const currentImageIndex = tempImages.findIndex( + (i) => i.uuid === gallery?.currentImage?.uuid + ); + const imagesLength = tempImages.length; + + return { + imageToDisplay: intermediateImage ? intermediateImage : currentImage, + isIntermediate: intermediateImage, + currentCategory, + isOnFirstImage: currentImageIndex === 0, + isOnLastImage: + !isNaN(currentImageIndex) && currentImageIndex === imagesLength - 1, + shouldShowImageDetails, + shouldShowPrevImageButton: currentImageIndex === 0, + shouldShowNextImageButton: + !isNaN(currentImageIndex) && currentImageIndex === imagesLength - 1, + }; + }, + { + memoizeOptions: { + resultEqualityCheck: _.isEqual, + }, + } +); + +export default function CurrentImagePreview() { + const dispatch = useAppDispatch(); + + const { + isOnFirstImage, + isOnLastImage, + shouldShowImageDetails, + imageToDisplay, + isIntermediate, + } = useAppSelector(imagesSelector); + + const [shouldShowNextPrevButtons, setShouldShowNextPrevButtons] = + useState(false); + + const handleCurrentImagePreviewMouseOver = () => { + setShouldShowNextPrevButtons(true); + }; + + const handleCurrentImagePreviewMouseOut = () => { + setShouldShowNextPrevButtons(false); + }; + + const handleClickPrevButton = () => { + dispatch(selectPrevImage()); + }; + + const handleClickNextButton = () => { + dispatch(selectNextImage()); + }; + + return ( +
+ {imageToDisplay && ( + + )} + {!shouldShowImageDetails && ( +
+
+ {shouldShowNextPrevButtons && !isOnFirstImage && ( + } + variant="unstyled" + onClick={handleClickPrevButton} + /> + )} +
+
+ {shouldShowNextPrevButtons && !isOnLastImage && ( + } + variant="unstyled" + onClick={handleClickNextButton} + /> + )} +
+
+ )} + {shouldShowImageDetails && imageToDisplay && ( + + )} +
+ ); +} diff --git a/frontend/src/features/gallery/DeleteImageModal.tsx b/frontend/src/features/gallery/DeleteImageModal.tsx new file mode 100644 index 0000000000..417aa2d393 --- /dev/null +++ b/frontend/src/features/gallery/DeleteImageModal.tsx @@ -0,0 +1,145 @@ +import { + Text, + AlertDialog, + AlertDialogBody, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogContent, + AlertDialogOverlay, + useDisclosure, + Button, + Switch, + FormControl, + FormLabel, + Flex, +} from '@chakra-ui/react'; +import { createSelector } from '@reduxjs/toolkit'; +import { + ChangeEvent, + cloneElement, + forwardRef, + ReactElement, + SyntheticEvent, + useRef, +} from 'react'; +import { useAppDispatch, useAppSelector } from '../../app/store'; +import { deleteImage } from '../../app/socketio/actions'; +import { RootState } from '../../app/store'; +import { setShouldConfirmOnDelete, SystemState } from '../system/systemSlice'; +import * as InvokeAI from '../../app/invokeai'; +import { useHotkeys } from 'react-hotkeys-hook'; +import _ from 'lodash'; + +const systemSelector = createSelector( + (state: RootState) => state.system, + (system: SystemState) => { + const { shouldConfirmOnDelete, isConnected, isProcessing } = system; + return { shouldConfirmOnDelete, isConnected, isProcessing }; + }, + { + memoizeOptions: { + resultEqualityCheck: _.isEqual, + }, + } +); +interface DeleteImageModalProps { + /** + * Component which, on click, should delete the image/open the modal. + */ + children: ReactElement; + /** + * The image to delete. + */ + image?: InvokeAI.Image; +} + +/** + * Needs a child, which will act as the button to delete an image. + * If system.shouldConfirmOnDelete is true, a confirmation modal is displayed. + * If it is false, the image is deleted immediately. + * The confirmation modal has a "Don't ask me again" switch to set the boolean. + */ +const DeleteImageModal = forwardRef( + ({ image, children }: DeleteImageModalProps, ref) => { + const { isOpen, onOpen, onClose } = useDisclosure(); + const dispatch = useAppDispatch(); + const { shouldConfirmOnDelete, isConnected, isProcessing } = + useAppSelector(systemSelector); + const cancelRef = useRef(null); + + const handleClickDelete = (e: SyntheticEvent) => { + e.stopPropagation(); + shouldConfirmOnDelete ? onOpen() : handleDelete(); + }; + + const handleDelete = () => { + if (isConnected && !isProcessing && image) { + dispatch(deleteImage(image)); + } + onClose(); + }; + + useHotkeys( + 'del', + () => { + shouldConfirmOnDelete ? onOpen() : handleDelete(); + }, + [image, shouldConfirmOnDelete] + ); + + const handleChangeShouldConfirmOnDelete = ( + e: ChangeEvent + ) => dispatch(setShouldConfirmOnDelete(!e.target.checked)); + + return ( + <> + {cloneElement(children, { + // TODO: This feels wrong. + onClick: image ? handleClickDelete : undefined, + ref: ref, + })} + + + + + + Delete image + + + + + + Are you sure? You can't undo this action afterwards. + + + + Don't ask me again + + + + + + + + + + + + + + ); + } +); + +export default DeleteImageModal; diff --git a/frontend/src/features/gallery/HoverableImage.scss b/frontend/src/features/gallery/HoverableImage.scss new file mode 100644 index 0000000000..b6563f4d7b --- /dev/null +++ b/frontend/src/features/gallery/HoverableImage.scss @@ -0,0 +1,100 @@ +.hoverable-image { + display: flex; + justify-content: center; + transition: transform 0.2s ease-out; + + &:hover { + cursor: pointer; + border-radius: 0.5rem; + z-index: 2; + } + + .hoverable-image-image { + width: 100%; + height: 100%; + max-width: 100%; + max-height: 100%; + } + + .hoverable-image-delete-button { + position: absolute; + top: 0.25rem; + right: 0.25rem; + } + + .hoverable-image-content { + display: flex; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + align-items: center; + justify-content: center; + + .hoverable-image-check { + fill: var(--status-good-color); + } + } + + .hoverable-image-icons { + position: absolute; + bottom: -2rem; + display: grid; + width: min-content; + grid-template-columns: repeat(2, max-content); + border-radius: 0.4rem; + background-color: var(--background-color-secondary); + padding: 0.2rem; + gap: 0.2rem; + grid-auto-rows: max-content; + + button { + width: 12px; + height: 12px; + border-radius: 0.2rem; + padding: 10px 0; + flex-shrink: 2; + svg { + width: 12px; + height: 12px; + } + } + } +} + +.hoverable-image-context-menu { + z-index: 15; + padding: 0.4rem; + border-radius: 0.25rem; + background-color: var(--context-menu-bg-color); + box-shadow: var(--context-menu-box-shadow); + + [role='menuitem'] { + font-size: 0.8rem; + line-height: 1rem; + border-radius: 3px; + display: flex; + align-items: center; + height: 1.75rem; + padding: 0 0.5rem; + position: relative; + user-select: none; + cursor: pointer; + outline: none; + + &[data-disabled] { + color: grey; + pointer-events: none; + cursor: not-allowed; + } + + &[data-warning] { + color: var(--status-bad-color); + } + + &[data-highlighted] { + background-color: var(--context-menu-bg-color-hover); + } + } +} diff --git a/frontend/src/features/gallery/HoverableImage.tsx b/frontend/src/features/gallery/HoverableImage.tsx new file mode 100644 index 0000000000..23348a69b7 --- /dev/null +++ b/frontend/src/features/gallery/HoverableImage.tsx @@ -0,0 +1,239 @@ +import { + Box, + Icon, + IconButton, + Image, + Tooltip, + useToast, +} from '@chakra-ui/react'; +import { useAppDispatch, useAppSelector } from '../../app/store'; +import { setCurrentImage } from './gallerySlice'; +import { FaCheck, FaTrashAlt } from 'react-icons/fa'; +import DeleteImageModal from './DeleteImageModal'; +import { memo, useState } from 'react'; +import { + setActiveTab, + setAllImageToImageParameters, + setAllTextToImageParameters, + setInitialImage, + setPrompt, + setSeed, +} from '../options/optionsSlice'; +import * as InvokeAI from '../../app/invokeai'; +import * as ContextMenu from '@radix-ui/react-context-menu'; +import { setImageToInpaint } from '../tabs/Inpainting/inpaintingSlice'; +import { hoverableImageSelector } from './gallerySliceSelectors'; + +interface HoverableImageProps { + image: InvokeAI.Image; + isSelected: boolean; +} + +const memoEqualityCheck = ( + prev: HoverableImageProps, + next: HoverableImageProps +) => prev.image.uuid === next.image.uuid && prev.isSelected === next.isSelected; + +/** + * Gallery image component with delete/use all/use seed buttons on hover. + */ +const HoverableImage = memo((props: HoverableImageProps) => { + const dispatch = useAppDispatch(); + const { + activeTabName, + galleryImageObjectFit, + galleryImageMinimumWidth, + mayDeleteImage, + } = useAppSelector(hoverableImageSelector); + const { image, isSelected } = props; + const { url, uuid, metadata } = image; + + const [isHovered, setIsHovered] = useState(false); + + const toast = useToast(); + + const handleMouseOver = () => setIsHovered(true); + + const handleMouseOut = () => setIsHovered(false); + + const handleUsePrompt = () => { + image.metadata && dispatch(setPrompt(image.metadata.image.prompt)); + toast({ + title: 'Prompt Set', + status: 'success', + duration: 2500, + isClosable: true, + }); + }; + + const handleUseSeed = () => { + image.metadata && dispatch(setSeed(image.metadata.image.seed)); + toast({ + title: 'Seed Set', + status: 'success', + duration: 2500, + isClosable: true, + }); + }; + + const handleSendToImageToImage = () => { + dispatch(setInitialImage(image)); + if (activeTabName !== 'img2img') { + dispatch(setActiveTab('img2img')); + } + toast({ + title: 'Sent to Image To Image', + status: 'success', + duration: 2500, + isClosable: true, + }); + }; + + const handleSendToInpainting = () => { + dispatch(setImageToInpaint(image)); + if (activeTabName !== 'inpainting') { + dispatch(setActiveTab('inpainting')); + } + toast({ + title: 'Sent to Inpainting', + status: 'success', + duration: 2500, + isClosable: true, + }); + }; + + const handleUseAllParameters = () => { + metadata && dispatch(setAllTextToImageParameters(metadata)); + toast({ + title: 'Parameters Set', + status: 'success', + duration: 2500, + isClosable: true, + }); + }; + + const handleUseInitialImage = async () => { + // check if the image exists before setting it as initial image + if (metadata?.image?.init_image_path) { + const response = await fetch(metadata.image.init_image_path); + if (response.ok) { + dispatch(setActiveTab('img2img')); + dispatch(setAllImageToImageParameters(metadata)); + toast({ + title: 'Initial Image Set', + status: 'success', + duration: 2500, + isClosable: true, + }); + return; + } + } + toast({ + title: 'Initial Image Not Set', + description: 'Could not load initial image.', + status: 'error', + duration: 2500, + isClosable: true, + }); + }; + + const handleSelectImage = () => dispatch(setCurrentImage(image)); + + return ( + { + // dispatch(setShouldHoldGalleryOpen(open)); + // dispatch(setShouldShowGallery(true)); + // }} + > + + + +
+ {isSelected && ( + + )} +
+ {isHovered && galleryImageMinimumWidth >= 64 && ( +
+ + + } + size="xs" + variant={'imageHoverIconButton'} + fontSize={14} + isDisabled={!mayDeleteImage} + /> + + +
+ )} +
+
+ + + Use Prompt + + + + Use Seed + + + Use All Parameters + + + + Use Initial Image + + + + Send to Image To Image + + + Send to Inpainting + + + Delete Image + + +
+ ); +}, memoEqualityCheck); + +export default HoverableImage; diff --git a/frontend/src/features/gallery/ImageGallery.scss b/frontend/src/features/gallery/ImageGallery.scss new file mode 100644 index 0000000000..3b8be38cfb --- /dev/null +++ b/frontend/src/features/gallery/ImageGallery.scss @@ -0,0 +1,182 @@ +@use '../../styles/Mixins/' as *; + +.image-gallery-wrapper-enter { + transform: translateX(150%); +} + +.image-gallery-wrapper-enter-active { + transform: translateX(0); + transition: all 120ms ease-out; +} + +.image-gallery-wrapper-exit { + transform: translateX(0); +} + +.image-gallery-wrapper-exit-active { + transform: translateX(150%); + transition: all 120ms ease-out; +} + +.image-gallery-wrapper { + &[data-pinned='false'] { + position: fixed; + height: 100vh; + top: 0; + right: 0; + + .image-gallery-popup { + border-radius: 0; + box-shadow: 0 0 1rem var(--text-color-a3); + .image-gallery-container { + max-height: calc($app-height + 5rem); + } + } + } + + .image-gallery-popup { + background-color: var(--tab-color); + padding: 1rem; + display: flex; + flex-direction: column; + row-gap: 1rem; + border-radius: 0.5rem; + border-left-width: 0.3rem; + + border-color: var(--resizeable-handle-border-color); + + &[data-resize-alert='true'] { + border-color: var(--status-bad-color); + } + + .image-gallery-header { + display: flex; + align-items: center; + column-gap: 0.5rem; + justify-content: space-between; + + div { + display: flex; + column-gap: 0.5rem; + column-gap: 0.5rem; + } + + .image-gallery-icon-btn { + background-color: var(--btn-load-more) !important; + &:hover { + background-color: var(--btn-load-more-hover) !important; + } + } + + .image-gallery-settings-popover { + display: flex; + flex-direction: column; + row-gap: 0.5rem; + + div { + display: flex; + column-gap: 0.5rem; + align-items: center; + justify-content: space-between; + } + } + + h1 { + font-weight: bold; + } + } + + .image-gallery-container { + display: flex; + flex-direction: column; + max-height: $app-gallery-popover-height; + overflow-y: scroll; + @include HideScrollbar; + + .image-gallery-container-placeholder { + display: flex; + flex-direction: column; + background-color: var(--background-color-secondary); + border-radius: 0.5rem; + place-items: center; + padding: 2rem; + text-align: center; + + p { + color: var(--subtext-color-bright); + font-family: Inter; + } + + svg { + width: 5rem; + height: 5rem; + color: var(--svg-color); + } + } + + .image-gallery-load-more-btn { + background-color: var(--btn-load-more) !important; + font-size: 0.85rem !important; + padding: 0.5rem; + margin-top: 1rem; + + &:disabled { + &:hover { + background-color: var(--btn-load-more) !important; + } + } + + &:hover { + background-color: var(--btn-load-more-hover) !important; + } + } + } + } +} + +.image-gallery-category-btn-group { + width: 100% !important; + column-gap: 0 !important; + justify-content: stretch !important; + + button { + flex-grow: 1; + &[data-selected='true'] { + background-color: var(--accent-color); + &:hover { + background-color: var(--accent-color-hover); + } + } + } +} + +// from https://css-tricks.com/a-grid-of-logos-in-squares/ +.image-gallery { + display: grid; + grid-gap: 0.5rem; + .hoverable-image { + padding: 0.5rem; + position: relative; + &::before { + // for apsect ratio + content: ''; + display: block; + padding-bottom: 100%; + } + .hoverable-image-image { + position: absolute; + max-width: 100%; + + // Alternate Version + // top: 0; + // bottom: 0; + // right: 0; + // left: 0; + // margin: auto; + + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + } + } +} diff --git a/frontend/src/features/gallery/ImageGallery.tsx b/frontend/src/features/gallery/ImageGallery.tsx new file mode 100644 index 0000000000..70098588f2 --- /dev/null +++ b/frontend/src/features/gallery/ImageGallery.tsx @@ -0,0 +1,500 @@ +import { Button } from '@chakra-ui/button'; +import { NumberSize, Resizable } from 're-resizable'; + +import { ChangeEvent, useEffect, useRef, useState } from 'react'; +import { useHotkeys } from 'react-hotkeys-hook'; +import { MdPhotoLibrary } from 'react-icons/md'; +import { BsPinAngle, BsPinAngleFill } from 'react-icons/bs'; +import { requestImages } from '../../app/socketio/actions'; +import { useAppDispatch, useAppSelector } from '../../app/store'; +import IAIIconButton from '../../common/components/IAIIconButton'; +import { + selectNextImage, + selectPrevImage, + setCurrentCategory, + setGalleryImageMinimumWidth, + setGalleryImageObjectFit, + setGalleryScrollPosition, + setGalleryWidth, + setShouldAutoSwitchToNewImages, + setShouldHoldGalleryOpen, + setShouldPinGallery, +} from './gallerySlice'; +import HoverableImage from './HoverableImage'; +import { setShouldShowGallery } from '../gallery/gallerySlice'; +import { ButtonGroup, useToast } from '@chakra-ui/react'; +import { CSSTransition } from 'react-transition-group'; +import { Direction } from 're-resizable/lib/resizer'; +import { imageGallerySelector } from './gallerySliceSelectors'; +import { FaImage, FaUser, FaWrench } from 'react-icons/fa'; +import IAIPopover from '../../common/components/IAIPopover'; +import IAISlider from '../../common/components/IAISlider'; +import { BiReset } from 'react-icons/bi'; +import IAICheckbox from '../../common/components/IAICheckbox'; +import { setNeedsCache } from '../tabs/Inpainting/inpaintingSlice'; +import _ from 'lodash'; +import useClickOutsideWatcher from '../../common/hooks/useClickOutsideWatcher'; + +const GALLERY_SHOW_BUTTONS_MIN_WIDTH = 320; + +export default function ImageGallery() { + const dispatch = useAppDispatch(); + const toast = useToast(); + + const { + images, + currentCategory, + currentImageUuid, + shouldPinGallery, + shouldShowGallery, + galleryScrollPosition, + galleryImageMinimumWidth, + galleryGridTemplateColumns, + activeTabName, + galleryImageObjectFit, + shouldHoldGalleryOpen, + shouldAutoSwitchToNewImages, + areMoreImagesAvailable, + galleryWidth, + } = useAppSelector(imageGallerySelector); + + const [galleryMinWidth, setGalleryMinWidth] = useState(300); + const [galleryMaxWidth, setGalleryMaxWidth] = useState(590); + + const [shouldShowButtons, setShouldShowButtons] = useState( + galleryWidth >= GALLERY_SHOW_BUTTONS_MIN_WIDTH + ); + + useEffect(() => { + if (!shouldPinGallery) return; + + if (activeTabName === 'inpainting') { + dispatch(setGalleryWidth(190)); + setGalleryMinWidth(190); + setGalleryMaxWidth(190); + } else if (activeTabName === 'img2img') { + dispatch( + setGalleryWidth(Math.min(Math.max(Number(galleryWidth), 0), 490)) + ); + setGalleryMaxWidth(490); + } else { + dispatch( + setGalleryWidth(Math.min(Math.max(Number(galleryWidth), 0), 590)) + ); + setGalleryMaxWidth(590); + } + dispatch(setNeedsCache(true)); + }, [dispatch, activeTabName, shouldPinGallery, galleryWidth]); + + useEffect(() => { + if (!shouldPinGallery) { + setGalleryMaxWidth(window.innerWidth); + } + }, [shouldPinGallery]); + + const galleryRef = useRef(null); + const galleryContainerRef = useRef(null); + const timeoutIdRef = useRef(null); + + const handleSetShouldPinGallery = () => { + dispatch(setShouldPinGallery(!shouldPinGallery)); + dispatch(setNeedsCache(true)); + }; + + const handleToggleGallery = () => { + shouldShowGallery ? handleCloseGallery() : handleOpenGallery(); + }; + + const handleOpenGallery = () => { + dispatch(setShouldShowGallery(true)); + shouldPinGallery && dispatch(setNeedsCache(true)); + }; + + const handleCloseGallery = () => { + // if (shouldPinGallery) return; + dispatch(setShouldShowGallery(false)); + dispatch( + setGalleryScrollPosition( + galleryContainerRef.current ? galleryContainerRef.current.scrollTop : 0 + ) + ); + dispatch(setShouldHoldGalleryOpen(false)); + // dispatch(setNeedsCache(true)); + }; + + const handleClickLoadMore = () => { + dispatch(requestImages(currentCategory)); + }; + + const handleChangeGalleryImageMinimumWidth = (v: number) => { + dispatch(setGalleryImageMinimumWidth(v)); + dispatch(setNeedsCache(true)); + }; + + const setCloseGalleryTimer = () => { + timeoutIdRef.current = window.setTimeout(() => handleCloseGallery(), 500); + }; + + const cancelCloseGalleryTimer = () => { + timeoutIdRef.current && window.clearTimeout(timeoutIdRef.current); + }; + + useHotkeys( + 'g', + () => { + handleToggleGallery(); + }, + [shouldShowGallery] + ); + + useHotkeys('left', () => { + dispatch(selectPrevImage()); + }); + + useHotkeys('right', () => { + dispatch(selectNextImage()); + }); + + useHotkeys( + 'shift+g', + () => { + handleSetShouldPinGallery(); + }, + [shouldPinGallery] + ); + + useHotkeys( + 'esc', + () => { + if (shouldPinGallery) return; + dispatch(setShouldShowGallery(false)); + }, + [shouldPinGallery] + ); + + const IMAGE_SIZE_STEP = 32; + + useHotkeys( + 'shift+up', + () => { + if (galleryImageMinimumWidth >= 256) { + return; + } + if (galleryImageMinimumWidth < 256) { + const newMinWidth = galleryImageMinimumWidth + IMAGE_SIZE_STEP; + if (newMinWidth <= 256) { + dispatch(setGalleryImageMinimumWidth(newMinWidth)); + toast({ + title: `Gallery Thumbnail Size set to ${newMinWidth}`, + status: 'success', + duration: 1000, + isClosable: true, + }); + } else { + dispatch(setGalleryImageMinimumWidth(256)); + toast({ + title: `Gallery Thumbnail Size set to 256`, + status: 'success', + duration: 1000, + isClosable: true, + }); + } + } + }, + [galleryImageMinimumWidth] + ); + + useHotkeys( + 'shift+down', + () => { + if (galleryImageMinimumWidth <= 32) { + return; + } + if (galleryImageMinimumWidth > 32) { + const newMinWidth = galleryImageMinimumWidth - IMAGE_SIZE_STEP; + if (newMinWidth > 32) { + dispatch(setGalleryImageMinimumWidth(newMinWidth)); + toast({ + title: `Gallery Thumbnail Size set to ${newMinWidth}`, + status: 'success', + duration: 1000, + isClosable: true, + }); + } else { + dispatch(setGalleryImageMinimumWidth(32)); + toast({ + title: `Gallery Thumbnail Size set to 32`, + status: 'success', + duration: 1000, + isClosable: true, + }); + } + } + }, + [galleryImageMinimumWidth] + ); + + useHotkeys( + 'shift+r', + () => { + dispatch(setGalleryImageMinimumWidth(64)); + toast({ + title: `Reset Gallery Image Size`, + status: 'success', + duration: 2500, + isClosable: true, + }); + }, + [galleryImageMinimumWidth] + ); + + // set gallery scroll position + useEffect(() => { + if (!galleryContainerRef.current) return; + galleryContainerRef.current.scrollTop = galleryScrollPosition; + }, [galleryScrollPosition, shouldShowGallery]); + + useEffect(() => { + setShouldShowButtons(galleryWidth >= 280); + }, [galleryWidth]); + + useClickOutsideWatcher(galleryRef, handleCloseGallery, !shouldPinGallery); + + return ( + +
+ { + dispatch( + setGalleryWidth( + _.clamp( + Number(galleryWidth) + delta.width, + 0, + Number(galleryMaxWidth) + ) + ) + ); + elementRef.removeAttribute('data-resize-alert'); + }} + onResize={( + _event: MouseEvent | TouchEvent, + _direction: Direction, + elementRef: HTMLElement, + delta: NumberSize + ) => { + const newWidth = _.clamp( + Number(galleryWidth) + delta.width, + 0, + Number(galleryMaxWidth) + ); + + if (newWidth >= 280 && !shouldShowButtons) { + setShouldShowButtons(true); + } else if (newWidth < 280 && shouldShowButtons) { + setShouldShowButtons(false); + } + + if (newWidth >= galleryMaxWidth) { + elementRef.setAttribute('data-resize-alert', 'true'); + } else { + elementRef.removeAttribute('data-resize-alert'); + } + }} + > +
+
+ + {shouldShowButtons ? ( + <> + + + + ) : ( + <> + } + onClick={() => dispatch(setCurrentCategory('result'))} + /> + } + onClick={() => dispatch(setCurrentCategory('user'))} + /> + + )} + +
+
+ } + className="image-gallery-icon-btn" + cursor={'pointer'} + /> + } + > +
+
+ + dispatch(setGalleryImageMinimumWidth(64))} + icon={} + data-selected={shouldPinGallery} + styleClass="image-gallery-icon-btn" + /> +
+
+ + dispatch( + setGalleryImageObjectFit( + galleryImageObjectFit === 'contain' + ? 'cover' + : 'contain' + ) + ) + } + /> +
+
+ ) => + dispatch( + setShouldAutoSwitchToNewImages(e.target.checked) + ) + } + /> +
+
+
+ + : } + /> +
+
+
+ {images.length || areMoreImagesAvailable ? ( + <> +
+ {images.map((image) => { + const { uuid } = image; + const isSelected = currentImageUuid === uuid; + return ( + + ); + })} +
+ + + ) : ( +
+ +

No Images In Gallery

+
+ )} +
+
+
+
+ ); +} diff --git a/frontend/src/features/gallery/ImageMetaDataViewer/ImageMetadataViewer.scss b/frontend/src/features/gallery/ImageMetaDataViewer/ImageMetadataViewer.scss new file mode 100644 index 0000000000..ba5e660682 --- /dev/null +++ b/frontend/src/features/gallery/ImageMetaDataViewer/ImageMetadataViewer.scss @@ -0,0 +1,23 @@ +@use '../../../styles/Mixins/' as *; + +.image-metadata-viewer { + position: absolute; + top: 0; + width: 100%; + border-radius: 0.5rem; + padding: 1rem; + background-color: var(--metadata-bg-color); + overflow: scroll; + max-height: $app-metadata-height; + height: 100%; + z-index: 10; +} + +.image-json-viewer { + border-radius: 0.5rem; + margin: 0 0.5rem 1rem 0.5rem; + padding: 1rem; + overflow-x: scroll; + word-break: break-all; + background-color: var(--metadata-json-bg-color); +} diff --git a/frontend/src/features/gallery/ImageMetaDataViewer/ImageMetadataViewer.tsx b/frontend/src/features/gallery/ImageMetaDataViewer/ImageMetadataViewer.tsx new file mode 100644 index 0000000000..7da28671b4 --- /dev/null +++ b/frontend/src/features/gallery/ImageMetaDataViewer/ImageMetadataViewer.tsx @@ -0,0 +1,411 @@ +import { + Center, + Flex, + Heading, + IconButton, + Link, + Text, + Tooltip, +} from '@chakra-ui/react'; +import { ExternalLinkIcon } from '@chakra-ui/icons'; +import { memo } from 'react'; +import { IoArrowUndoCircleOutline } from 'react-icons/io5'; +import { useAppDispatch } from '../../../app/store'; +import * as InvokeAI from '../../../app/invokeai'; +import { + setCfgScale, + setFacetoolStrength, + setCodeformerFidelity, + setFacetoolType, + setHeight, + setHiresFix, + setImg2imgStrength, + setMaskPath, + setPrompt, + setSampler, + setSeamless, + setSeed, + setSeedWeights, + setShouldFitToWidthHeight, + setSteps, + setUpscalingLevel, + setUpscalingStrength, + setWidth, + setInitialImage, + setShouldShowImageDetails, +} from '../../options/optionsSlice'; +import promptToString from '../../../common/util/promptToString'; +import { seedWeightsToString } from '../../../common/util/seedWeightPairs'; +import { FaCopy } from 'react-icons/fa'; +import { useHotkeys } from 'react-hotkeys-hook'; + +type MetadataItemProps = { + isLink?: boolean; + label: string; + onClick?: () => void; + value: number | string | boolean; + labelPosition?: string; +}; + +/** + * Component to display an individual metadata item or parameter. + */ +const MetadataItem = ({ + label, + value, + onClick, + isLink, + labelPosition, +}: MetadataItemProps) => { + return ( + + {onClick && ( + + } + size={'xs'} + variant={'ghost'} + fontSize={20} + onClick={onClick} + /> + + )} + + + {label}: + + {isLink ? ( + + {value.toString()} + + ) : ( + + {value.toString()} + + )} + + + ); +}; + +type ImageMetadataViewerProps = { + image: InvokeAI.Image; + styleClass?: string; +}; + +// TODO: I don't know if this is needed. +const memoEqualityCheck = ( + prev: ImageMetadataViewerProps, + next: ImageMetadataViewerProps +) => prev.image.uuid === next.image.uuid; + +// TODO: Show more interesting information in this component. + +/** + * Image metadata viewer overlays currently selected image and provides + * access to any of its metadata for use in processing. + */ +const ImageMetadataViewer = memo( + ({ image, styleClass }: ImageMetadataViewerProps) => { + const dispatch = useAppDispatch(); + + useHotkeys('esc', () => { + dispatch(setShouldShowImageDetails(false)); + }); + + const metadata = image?.metadata?.image || {}; + const { + type, + postprocessing, + sampler, + prompt, + seed, + variations, + steps, + cfg_scale, + seamless, + hires_fix, + width, + height, + strength, + fit, + init_image_path, + mask_image_path, + orig_path, + scale, + } = metadata; + + const metadataJSON = JSON.stringify(metadata, null, 2); + + return ( +
+ + + File: + + {image.url} + + + + {Object.keys(metadata).length > 0 ? ( + <> + {type && } + {['esrgan', 'gfpgan'].includes(type) && ( + + )} + {type === 'gfpgan' && strength !== undefined && ( + dispatch(setFacetoolStrength(strength))} + /> + )} + {type === 'esrgan' && scale !== undefined && ( + dispatch(setUpscalingLevel(scale))} + /> + )} + {type === 'esrgan' && strength !== undefined && ( + dispatch(setUpscalingStrength(strength))} + /> + )} + {prompt && ( + dispatch(setPrompt(prompt))} + /> + )} + {seed !== undefined && ( + dispatch(setSeed(seed))} + /> + )} + {sampler && ( + dispatch(setSampler(sampler))} + /> + )} + {steps && ( + dispatch(setSteps(steps))} + /> + )} + {cfg_scale !== undefined && ( + dispatch(setCfgScale(cfg_scale))} + /> + )} + {variations && variations.length > 0 && ( + + dispatch(setSeedWeights(seedWeightsToString(variations))) + } + /> + )} + {seamless && ( + dispatch(setSeamless(seamless))} + /> + )} + {hires_fix && ( + dispatch(setHiresFix(hires_fix))} + /> + )} + {width && ( + dispatch(setWidth(width))} + /> + )} + {height && ( + dispatch(setHeight(height))} + /> + )} + {init_image_path && ( + dispatch(setInitialImage(init_image_path))} + /> + )} + {mask_image_path && ( + dispatch(setMaskPath(mask_image_path))} + /> + )} + {type === 'img2img' && strength && ( + dispatch(setImg2imgStrength(strength))} + /> + )} + {fit && ( + dispatch(setShouldFitToWidthHeight(fit))} + /> + )} + {postprocessing && postprocessing.length > 0 && ( + <> + Postprocessing + {postprocessing.map( + ( + postprocess: InvokeAI.PostProcessedImageMetadata, + i: number + ) => { + if (postprocess.type === 'esrgan') { + const { scale, strength } = postprocess; + return ( + + {`${ + i + 1 + }: Upscale (ESRGAN)`} + dispatch(setUpscalingLevel(scale))} + /> + + dispatch(setUpscalingStrength(strength)) + } + /> + + ); + } else if (postprocess.type === 'gfpgan') { + const { strength } = postprocess; + return ( + + {`${ + i + 1 + }: Face restoration (GFPGAN)`} + + { + dispatch(setFacetoolStrength(strength)); + dispatch(setFacetoolType('gfpgan')); + }} + /> + + ); + } else if (postprocess.type === 'codeformer') { + const { strength, fidelity } = postprocess; + return ( + + {`${ + i + 1 + }: Face restoration (Codeformer)`} + + { + dispatch(setFacetoolStrength(strength)); + dispatch(setFacetoolType('codeformer')); + }} + /> + {fidelity && ( + { + dispatch(setCodeformerFidelity(fidelity)); + dispatch(setFacetoolType('codeformer')); + }} + /> + )} + + ); + } + } + )} + + )} + + + + } + size={'xs'} + variant={'ghost'} + fontSize={14} + onClick={() => + navigator.clipboard.writeText(metadataJSON) + } + /> + + Metadata JSON: + +
+
{metadataJSON}
+
+
+ + ) : ( +
+ + No metadata available + +
+ )} +
+
+ ); + }, + memoEqualityCheck +); + +export default ImageMetadataViewer; diff --git a/frontend/src/features/gallery/gallerySlice.ts b/frontend/src/features/gallery/gallerySlice.ts new file mode 100644 index 0000000000..4d0663a486 --- /dev/null +++ b/frontend/src/features/gallery/gallerySlice.ts @@ -0,0 +1,279 @@ +import { createSlice } from '@reduxjs/toolkit'; +import type { PayloadAction } from '@reduxjs/toolkit'; +import _, { clamp } from 'lodash'; +import * as InvokeAI from '../../app/invokeai'; + +export type GalleryCategory = 'user' | 'result'; + +export type AddImagesPayload = { + images: Array; + areMoreImagesAvailable: boolean; + category: GalleryCategory; +}; + +type GalleryImageObjectFitType = 'contain' | 'cover'; + +export type Gallery = { + images: InvokeAI.Image[]; + latest_mtime?: number; + earliest_mtime?: number; + areMoreImagesAvailable: boolean; +}; + +export interface GalleryState { + currentImage?: InvokeAI.Image; + currentImageUuid: string; + intermediateImage?: InvokeAI.Image; + shouldPinGallery: boolean; + shouldShowGallery: boolean; + galleryScrollPosition: number; + galleryImageMinimumWidth: number; + galleryImageObjectFit: GalleryImageObjectFitType; + shouldHoldGalleryOpen: boolean; + shouldAutoSwitchToNewImages: boolean; + categories: { + user: Gallery; + result: Gallery; + }; + currentCategory: GalleryCategory; + galleryWidth: number; +} + +const initialState: GalleryState = { + currentImageUuid: '', + shouldPinGallery: true, + shouldShowGallery: true, + galleryScrollPosition: 0, + galleryImageMinimumWidth: 64, + galleryImageObjectFit: 'cover', + shouldHoldGalleryOpen: false, + shouldAutoSwitchToNewImages: true, + currentCategory: 'result', + categories: { + user: { + images: [], + latest_mtime: undefined, + earliest_mtime: undefined, + areMoreImagesAvailable: true, + }, + result: { + images: [], + latest_mtime: undefined, + earliest_mtime: undefined, + areMoreImagesAvailable: true, + }, + }, + galleryWidth: 300, +}; + +export const gallerySlice = createSlice({ + name: 'gallery', + initialState, + reducers: { + setCurrentImage: (state, action: PayloadAction) => { + state.currentImage = action.payload; + state.currentImageUuid = action.payload.uuid; + }, + removeImage: ( + state, + action: PayloadAction + ) => { + const { uuid, category } = action.payload; + + const tempImages = state.categories[category as GalleryCategory].images; + + const newImages = tempImages.filter((image) => image.uuid !== uuid); + + if (uuid === state.currentImageUuid) { + /** + * We are deleting the currently selected image. + * + * We want the new currentl selected image to be under the cursor in the + * gallery, so we need to do some fanagling. The currently selected image + * is set by its UUID, not its index in the image list. + * + * Get the currently selected image's index. + */ + const imageToDeleteIndex = tempImages.findIndex( + (image) => image.uuid === uuid + ); + + /** + * New current image needs to be in the same spot, but because the gallery + * is sorted in reverse order, the new current image's index will actuall be + * one less than the deleted image's index. + * + * Clamp the new index to ensure it is valid.. + */ + const newCurrentImageIndex = clamp( + imageToDeleteIndex, + 0, + newImages.length - 1 + ); + + state.currentImage = newImages.length + ? newImages[newCurrentImageIndex] + : undefined; + + state.currentImageUuid = newImages.length + ? newImages[newCurrentImageIndex].uuid + : ''; + } + + state.categories[category as GalleryCategory].images = newImages; + }, + addImage: ( + state, + action: PayloadAction<{ + image: InvokeAI.Image; + category: GalleryCategory; + }> + ) => { + const { image: newImage, category } = action.payload; + const { uuid, url, mtime } = newImage; + + const tempCategory = state.categories[category as GalleryCategory]; + + // Do not add duplicate images + if (tempCategory.images.find((i) => i.url === url && i.mtime === mtime)) { + return; + } + + tempCategory.images.unshift(newImage); + if (state.shouldAutoSwitchToNewImages) { + state.currentImageUuid = uuid; + state.currentImage = newImage; + state.currentCategory = category; + } + state.intermediateImage = undefined; + tempCategory.latest_mtime = mtime; + }, + setIntermediateImage: (state, action: PayloadAction) => { + state.intermediateImage = action.payload; + }, + clearIntermediateImage: (state) => { + state.intermediateImage = undefined; + }, + selectNextImage: (state) => { + const { currentImage } = state; + if (!currentImage) return; + const tempImages = + state.categories[currentImage.category as GalleryCategory].images; + + if (currentImage) { + const currentImageIndex = tempImages.findIndex( + (i) => i.uuid === currentImage.uuid + ); + if (_.inRange(currentImageIndex, 0, tempImages.length)) { + const newCurrentImage = tempImages[currentImageIndex + 1]; + state.currentImage = newCurrentImage; + state.currentImageUuid = newCurrentImage.uuid; + } + } + }, + selectPrevImage: (state) => { + const { currentImage } = state; + if (!currentImage) return; + const tempImages = + state.categories[currentImage.category as GalleryCategory].images; + + if (currentImage) { + const currentImageIndex = tempImages.findIndex( + (i) => i.uuid === currentImage.uuid + ); + if (_.inRange(currentImageIndex, 1, tempImages.length + 1)) { + const newCurrentImage = tempImages[currentImageIndex - 1]; + state.currentImage = newCurrentImage; + state.currentImageUuid = newCurrentImage.uuid; + } + } + }, + addGalleryImages: (state, action: PayloadAction) => { + const { images, areMoreImagesAvailable, category } = action.payload; + const tempImages = state.categories[category].images; + + // const prevImages = category === 'user' ? state.userImages : state.resultImages + + if (images.length > 0) { + // Filter images that already exist in the gallery + const newImages = images.filter( + (newImage) => + !tempImages.find( + (i) => i.url === newImage.url && i.mtime === newImage.mtime + ) + ); + state.categories[category].images = tempImages + .concat(newImages) + .sort((a, b) => b.mtime - a.mtime); + + if (!state.currentImage) { + const newCurrentImage = images[0]; + state.currentImage = newCurrentImage; + state.currentImageUuid = newCurrentImage.uuid; + } + + // keep track of the timestamps of latest and earliest images received + state.categories[category].latest_mtime = images[0].mtime; + state.categories[category].earliest_mtime = + images[images.length - 1].mtime; + } + + if (areMoreImagesAvailable !== undefined) { + state.categories[category].areMoreImagesAvailable = + areMoreImagesAvailable; + } + }, + setShouldPinGallery: (state, action: PayloadAction) => { + state.shouldPinGallery = action.payload; + }, + setShouldShowGallery: (state, action: PayloadAction) => { + state.shouldShowGallery = action.payload; + }, + setGalleryScrollPosition: (state, action: PayloadAction) => { + state.galleryScrollPosition = action.payload; + }, + setGalleryImageMinimumWidth: (state, action: PayloadAction) => { + state.galleryImageMinimumWidth = action.payload; + }, + setGalleryImageObjectFit: ( + state, + action: PayloadAction + ) => { + state.galleryImageObjectFit = action.payload; + }, + setShouldHoldGalleryOpen: (state, action: PayloadAction) => { + state.shouldHoldGalleryOpen = action.payload; + }, + setShouldAutoSwitchToNewImages: (state, action: PayloadAction) => { + state.shouldAutoSwitchToNewImages = action.payload; + }, + setCurrentCategory: (state, action: PayloadAction) => { + state.currentCategory = action.payload; + }, + setGalleryWidth: (state, action: PayloadAction) => { + state.galleryWidth = action.payload; + }, + }, +}); + +export const { + addImage, + clearIntermediateImage, + removeImage, + setCurrentImage, + addGalleryImages, + setIntermediateImage, + selectNextImage, + selectPrevImage, + setShouldPinGallery, + setShouldShowGallery, + setGalleryScrollPosition, + setGalleryImageMinimumWidth, + setGalleryImageObjectFit, + setShouldHoldGalleryOpen, + setShouldAutoSwitchToNewImages, + setCurrentCategory, + setGalleryWidth, +} = gallerySlice.actions; + +export default gallerySlice.reducer; diff --git a/frontend/src/features/gallery/gallerySliceSelectors.ts b/frontend/src/features/gallery/gallerySliceSelectors.ts new file mode 100644 index 0000000000..d0bbb5af40 --- /dev/null +++ b/frontend/src/features/gallery/gallerySliceSelectors.ts @@ -0,0 +1,80 @@ +import { createSelector } from '@reduxjs/toolkit'; +import { RootState } from '../../app/store'; +import { activeTabNameSelector } from '../options/optionsSelectors'; +import { OptionsState } from '../options/optionsSlice'; +import { SystemState } from '../system/systemSlice'; +import { GalleryState } from './gallerySlice'; +import _ from 'lodash'; + +export const imageGallerySelector = createSelector( + [ + (state: RootState) => state.gallery, + (state: RootState) => state.options, + activeTabNameSelector, + ], + (gallery: GalleryState, options: OptionsState, activeTabName) => { + const { + categories, + currentCategory, + currentImageUuid, + shouldPinGallery, + shouldShowGallery, + galleryScrollPosition, + galleryImageMinimumWidth, + galleryImageObjectFit, + shouldHoldGalleryOpen, + shouldAutoSwitchToNewImages, + galleryWidth, + } = gallery; + + return { + currentImageUuid, + shouldPinGallery, + shouldShowGallery, + galleryScrollPosition, + galleryImageMinimumWidth, + galleryImageObjectFit, + galleryGridTemplateColumns: `repeat(auto-fill, minmax(${galleryImageMinimumWidth}px, auto))`, + activeTabName, + shouldHoldGalleryOpen, + shouldAutoSwitchToNewImages, + images: categories[currentCategory].images, + areMoreImagesAvailable: + categories[currentCategory].areMoreImagesAvailable, + currentCategory, + galleryWidth, + }; + }, + { + memoizeOptions: { + resultEqualityCheck: _.isEqual, + }, + } +); + +export const hoverableImageSelector = createSelector( + [ + (state: RootState) => state.options, + (state: RootState) => state.gallery, + (state: RootState) => state.system, + activeTabNameSelector, + ], + ( + options: OptionsState, + gallery: GalleryState, + system: SystemState, + activeTabName + ) => { + return { + mayDeleteImage: system.isConnected && !system.isProcessing, + galleryImageObjectFit: gallery.galleryImageObjectFit, + galleryImageMinimumWidth: gallery.galleryImageMinimumWidth, + activeTabName, + }; + }, + { + memoizeOptions: { + resultEqualityCheck: _.isEqual, + }, + } +); diff --git a/frontend/src/features/options/AccordionItems/AdvancedSettings.scss b/frontend/src/features/options/AccordionItems/AdvancedSettings.scss new file mode 100644 index 0000000000..fd940e8182 --- /dev/null +++ b/frontend/src/features/options/AccordionItems/AdvancedSettings.scss @@ -0,0 +1,38 @@ +@use '../../../styles/Mixins/' as *; + +.advanced-settings { + display: grid; + row-gap: 0.5rem; +} + +.advanced-settings-item { + display: grid; + max-width: $options-bar-max-width; + border: none; + border-top: 0px; + border-radius: 0.4rem; + + &[aria-expanded='true'] { + background-color: var(--tab-hover-color); + border-radius: 0 0 0.4rem 0.4rem; + } +} + +.advanced-settings-panel { + background-color: var(--tab-panel-bg); + border-radius: 0 0 0.4rem 0.4rem; + border: 2px solid var(--tab-hover-color); +} + +.advanced-settings-header { + border-radius: 0.4rem; + + &[aria-expanded='true'] { + background-color: var(--tab-color); + border-radius: 0.4rem 0.4rem 0 0; + } + + &:hover { + background-color: var(--tab-hover-color) !important; + } +} diff --git a/frontend/src/features/options/AccordionItems/InvokeAccordionItem.tsx b/frontend/src/features/options/AccordionItems/InvokeAccordionItem.tsx new file mode 100644 index 0000000000..30d6f2a5e8 --- /dev/null +++ b/frontend/src/features/options/AccordionItems/InvokeAccordionItem.tsx @@ -0,0 +1,34 @@ +import { + AccordionButton, + AccordionIcon, + AccordionItem, + AccordionPanel, +} from '@chakra-ui/react'; +import React, { ReactElement } from 'react'; +import { Feature } from '../../../app/features'; +import GuideIcon from '../../../common/components/GuideIcon'; + +export interface InvokeAccordionItemProps { + header: ReactElement; + feature: Feature; + options: ReactElement; +} + +export default function InvokeAccordionItem(props: InvokeAccordionItemProps) { + const { header, feature, options } = props; + + return ( + +

+ + {header} + + + +

+ + {options} + +
+ ); +} diff --git a/frontend/src/features/options/AdvancedOptions/FaceRestore/FaceRestoreHeader.tsx b/frontend/src/features/options/AdvancedOptions/FaceRestore/FaceRestoreHeader.tsx new file mode 100644 index 0000000000..0efe400d22 --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/FaceRestore/FaceRestoreHeader.tsx @@ -0,0 +1,40 @@ +import { Flex } from '@chakra-ui/layout'; +import React, { ChangeEvent } from 'react'; +import { + RootState, + useAppDispatch, + useAppSelector, +} from '../../../../app/store'; +import IAISwitch from '../../../../common/components/IAISwitch'; +import { setShouldRunFacetool } from '../../optionsSlice'; + +export default function FaceRestoreHeader() { + const isGFPGANAvailable = useAppSelector( + (state: RootState) => state.system.isGFPGANAvailable + ); + + const shouldRunFacetool = useAppSelector( + (state: RootState) => state.options.shouldRunFacetool + ); + + const dispatch = useAppDispatch(); + + const handleChangeShouldRunFacetool = (e: ChangeEvent) => + dispatch(setShouldRunFacetool(e.target.checked)); + + return ( + +

Restore Face

+ +
+ ); +} diff --git a/frontend/src/features/options/AdvancedOptions/FaceRestore/FaceRestoreOptions.tsx b/frontend/src/features/options/AdvancedOptions/FaceRestore/FaceRestoreOptions.tsx new file mode 100644 index 0000000000..1f8e170a6f --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/FaceRestore/FaceRestoreOptions.tsx @@ -0,0 +1,105 @@ +import { Flex } from '@chakra-ui/react'; + +import { RootState } from '../../../../app/store'; +import { useAppDispatch, useAppSelector } from '../../../../app/store'; + +import { + FacetoolType, + OptionsState, + setCodeformerFidelity, + setFacetoolStrength, + setFacetoolType, +} from '../../optionsSlice'; + +import { createSelector } from '@reduxjs/toolkit'; +import { isEqual } from 'lodash'; +import { SystemState } from '../../../system/systemSlice'; +import IAINumberInput from '../../../../common/components/IAINumberInput'; +import IAISelect from '../../../../common/components/IAISelect'; +import { FACETOOL_TYPES } from '../../../../app/constants'; +import { ChangeEvent } from 'react'; + +const optionsSelector = createSelector( + (state: RootState) => state.options, + (options: OptionsState) => { + return { + facetoolStrength: options.facetoolStrength, + facetoolType: options.facetoolType, + codeformerFidelity: options.codeformerFidelity, + }; + }, + { + memoizeOptions: { + resultEqualityCheck: isEqual, + }, + } +); + +const systemSelector = createSelector( + (state: RootState) => state.system, + (system: SystemState) => { + return { + isGFPGANAvailable: system.isGFPGANAvailable, + }; + }, + { + memoizeOptions: { + resultEqualityCheck: isEqual, + }, + } +); + +/** + * Displays face-fixing/GFPGAN options (strength). + */ +const FaceRestoreOptions = () => { + const dispatch = useAppDispatch(); + const { facetoolStrength, facetoolType, codeformerFidelity } = + useAppSelector(optionsSelector); + const { isGFPGANAvailable } = useAppSelector(systemSelector); + + const handleChangeStrength = (v: number) => dispatch(setFacetoolStrength(v)); + + const handleChangeCodeformerFidelity = (v: number) => + dispatch(setCodeformerFidelity(v)); + + const handleChangeFacetoolType = (e: ChangeEvent) => + dispatch(setFacetoolType(e.target.value as FacetoolType)); + + return ( + + + + {facetoolType === 'codeformer' && ( + + )} + + ); +}; + +export default FaceRestoreOptions; diff --git a/frontend/src/features/options/AdvancedOptions/ImageToImage/ImageFit.tsx b/frontend/src/features/options/AdvancedOptions/ImageToImage/ImageFit.tsx new file mode 100644 index 0000000000..eaaa08dff4 --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/ImageToImage/ImageFit.tsx @@ -0,0 +1,27 @@ +import React, { ChangeEvent } from 'react'; +import { + RootState, + useAppDispatch, + useAppSelector, +} from '../../../../app/store'; +import IAISwitch from '../../../../common/components/IAISwitch'; +import { setShouldFitToWidthHeight } from '../../optionsSlice'; + +export default function ImageFit() { + const dispatch = useAppDispatch(); + + const shouldFitToWidthHeight = useAppSelector( + (state: RootState) => state.options.shouldFitToWidthHeight + ); + + const handleChangeFit = (e: ChangeEvent) => + dispatch(setShouldFitToWidthHeight(e.target.checked)); + + return ( + + ); +} diff --git a/frontend/src/features/options/AdvancedOptions/ImageToImage/ImageToImageStrength.tsx b/frontend/src/features/options/AdvancedOptions/ImageToImage/ImageToImageStrength.tsx new file mode 100644 index 0000000000..ea916c5460 --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/ImageToImage/ImageToImageStrength.tsx @@ -0,0 +1,38 @@ +import React from 'react'; +import { + RootState, + useAppDispatch, + useAppSelector, +} from '../../../../app/store'; +import IAINumberInput from '../../../../common/components/IAINumberInput'; +import { setImg2imgStrength } from '../../optionsSlice'; + +interface ImageToImageStrengthProps { + label?: string; + styleClass?: string; +} + +export default function ImageToImageStrength(props: ImageToImageStrengthProps) { + const { label = 'Strength', styleClass } = props; + const img2imgStrength = useAppSelector( + (state: RootState) => state.options.img2imgStrength + ); + + const dispatch = useAppDispatch(); + + const handleChangeStrength = (v: number) => dispatch(setImg2imgStrength(v)); + + return ( + + ); +} diff --git a/frontend/src/features/options/AdvancedOptions/Inpainting/BoundingBoxSettings/BoundingBoxDarkenOutside.tsx b/frontend/src/features/options/AdvancedOptions/Inpainting/BoundingBoxSettings/BoundingBoxDarkenOutside.tsx new file mode 100644 index 0000000000..b91f5d5736 --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/Inpainting/BoundingBoxSettings/BoundingBoxDarkenOutside.tsx @@ -0,0 +1,28 @@ +import React from 'react'; +import { + RootState, + useAppDispatch, + useAppSelector, +} from '../../../../../app/store'; +import IAICheckbox from '../../../../../common/components/IAICheckbox'; +import { setShouldShowBoundingBoxFill } from '../../../../tabs/Inpainting/inpaintingSlice'; + +export default function BoundingBoxDarkenOutside() { + const dispatch = useAppDispatch(); + const shouldShowBoundingBoxFill = useAppSelector( + (state: RootState) => state.inpainting.shouldShowBoundingBoxFill + ); + + const handleChangeShouldShowBoundingBoxFill = () => { + dispatch(setShouldShowBoundingBoxFill(!shouldShowBoundingBoxFill)); + }; + + return ( + + ); +} diff --git a/frontend/src/features/options/AdvancedOptions/Inpainting/BoundingBoxSettings/BoundingBoxDimensionSlider.tsx b/frontend/src/features/options/AdvancedOptions/Inpainting/BoundingBoxSettings/BoundingBoxDimensionSlider.tsx new file mode 100644 index 0000000000..709a86a80b --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/Inpainting/BoundingBoxSettings/BoundingBoxDimensionSlider.tsx @@ -0,0 +1,128 @@ +import React from 'react'; +import IAISlider from '../../../../../common/components/IAISlider'; +import IAINumberInput from '../../../../../common/components/IAINumberInput'; +import IAIIconButton from '../../../../../common/components/IAIIconButton'; +import { BiReset } from 'react-icons/bi'; + +import { + RootState, + useAppDispatch, + useAppSelector, +} from '../../../../../app/store'; +import { createSelector } from '@reduxjs/toolkit'; +import { + InpaintingState, + setBoundingBoxDimensions, +} from '../../../../tabs/Inpainting/inpaintingSlice'; + +import { roundDownToMultiple } from '../../../../../common/util/roundDownToMultiple'; +import _ from 'lodash'; + +const boundingBoxDimensionsSelector = createSelector( + (state: RootState) => state.inpainting, + (inpainting: InpaintingState) => { + const { canvasDimensions, boundingBoxDimensions, shouldLockBoundingBox } = + inpainting; + return { + canvasDimensions, + boundingBoxDimensions, + shouldLockBoundingBox, + }; + }, + { + memoizeOptions: { + resultEqualityCheck: _.isEqual, + }, + } +); + +type BoundingBoxDimensionSlidersType = { + dimension: 'width' | 'height'; +}; + +export default function BoundingBoxDimensionSlider( + props: BoundingBoxDimensionSlidersType +) { + const { dimension } = props; + const dispatch = useAppDispatch(); + const { shouldLockBoundingBox, canvasDimensions, boundingBoxDimensions } = + useAppSelector(boundingBoxDimensionsSelector); + + const canvasDimension = canvasDimensions[dimension]; + const boundingBoxDimension = boundingBoxDimensions[dimension]; + + const handleBoundingBoxDimension = (v: number) => { + if (dimension == 'width') { + dispatch( + setBoundingBoxDimensions({ + ...boundingBoxDimensions, + width: Math.floor(v), + }) + ); + } + + if (dimension == 'height') { + dispatch( + setBoundingBoxDimensions({ + ...boundingBoxDimensions, + height: Math.floor(v), + }) + ); + } + }; + + const handleResetDimension = () => { + if (dimension == 'width') { + dispatch( + setBoundingBoxDimensions({ + ...boundingBoxDimensions, + width: Math.floor(canvasDimension), + }) + ); + } + if (dimension == 'height') { + dispatch( + setBoundingBoxDimensions({ + ...boundingBoxDimensions, + height: Math.floor(canvasDimension), + }) + ); + } + }; + + return ( +
+ + + } + styleClass="inpainting-bounding-box-reset-icon-btn" + isDisabled={ + shouldLockBoundingBox || canvasDimension === boundingBoxDimension + } + /> +
+ ); +} diff --git a/frontend/src/features/options/AdvancedOptions/Inpainting/BoundingBoxSettings/BoundingBoxLock.tsx b/frontend/src/features/options/AdvancedOptions/Inpainting/BoundingBoxSettings/BoundingBoxLock.tsx new file mode 100644 index 0000000000..adea1f3f54 --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/Inpainting/BoundingBoxSettings/BoundingBoxLock.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import { + RootState, + useAppDispatch, + useAppSelector, +} from '../../../../../app/store'; +import IAICheckbox from '../../../../../common/components/IAICheckbox'; +import { setShouldLockBoundingBox } from '../../../../tabs/Inpainting/inpaintingSlice'; + +export default function BoundingBoxLock() { + const shouldLockBoundingBox = useAppSelector( + (state: RootState) => state.inpainting.shouldLockBoundingBox + ); + const dispatch = useAppDispatch(); + + const handleChangeShouldLockBoundingBox = () => { + dispatch(setShouldLockBoundingBox(!shouldLockBoundingBox)); + }; + return ( + + ); +} diff --git a/frontend/src/features/options/AdvancedOptions/Inpainting/BoundingBoxSettings/BoundingBoxSettings.scss b/frontend/src/features/options/AdvancedOptions/Inpainting/BoundingBoxSettings/BoundingBoxSettings.scss new file mode 100644 index 0000000000..5eef7cc47d --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/Inpainting/BoundingBoxSettings/BoundingBoxSettings.scss @@ -0,0 +1,53 @@ +.inpainting-bounding-box-settings { + display: flex; + flex-direction: column; + border-radius: 0.4rem; + border: 2px solid var(--tab-color); +} + +.inpainting-bounding-box-header { + background-color: var(--tab-color); + display: flex; + flex-direction: row; + justify-content: space-between; + padding: 0.5rem 1rem; + border-radius: 0.4rem 0.4rem 0 0; + align-items: center; + + button { + width: 0.5rem !important; + height: 1.2rem !important; + background: none !important; + &:hover { + background: none !important; + } + } + + p { + font-weight: bold; + } +} + +.inpainting-bounding-box-settings-items { + padding: 1rem; + display: flex; + flex-direction: column; + row-gap: 1rem; + + .inpainting-bounding-box-reset-icon-btn { + background-color: var(--btn-load-more) !important; + &:hover { + background-color: var(--btn-load-more-hover) !important; + } + } +} + +.inpainting-bounding-box-dimensions-slider-numberinput { + display: grid; + grid-template-columns: repeat(3, auto); + column-gap: 1rem; +} + +.inpainting-bounding-box-darken { + width: max-content; +} diff --git a/frontend/src/features/options/AdvancedOptions/Inpainting/BoundingBoxSettings/BoundingBoxSettings.tsx b/frontend/src/features/options/AdvancedOptions/Inpainting/BoundingBoxSettings/BoundingBoxSettings.tsx new file mode 100644 index 0000000000..5038823d85 --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/Inpainting/BoundingBoxSettings/BoundingBoxSettings.tsx @@ -0,0 +1,26 @@ +import { Flex } from '@chakra-ui/react'; +import BoundingBoxDarkenOutside from './BoundingBoxDarkenOutside'; +import BoundingBoxDimensionSlider from './BoundingBoxDimensionSlider'; +import BoundingBoxLock from './BoundingBoxLock'; +import BoundingBoxVisibility from './BoundingBoxVisibility'; + +const BoundingBoxSettings = () => { + return ( +
+
+

Inpaint Box

+ +
+
+ + + + + + +
+
+ ); +}; + +export default BoundingBoxSettings; diff --git a/frontend/src/features/options/AdvancedOptions/Inpainting/BoundingBoxSettings/BoundingBoxVisibility.tsx b/frontend/src/features/options/AdvancedOptions/Inpainting/BoundingBoxSettings/BoundingBoxVisibility.tsx new file mode 100644 index 0000000000..ef0a76d166 --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/Inpainting/BoundingBoxSettings/BoundingBoxVisibility.tsx @@ -0,0 +1,28 @@ +import React from 'react'; +import { BiHide, BiShow } from 'react-icons/bi'; +import { + RootState, + useAppDispatch, + useAppSelector, +} from '../../../../../app/store'; +import IAIIconButton from '../../../../../common/components/IAIIconButton'; +import { setShouldShowBoundingBox } from '../../../../tabs/Inpainting/inpaintingSlice'; + +export default function BoundingBoxVisibility() { + const shouldShowBoundingBox = useAppSelector( + (state: RootState) => state.inpainting.shouldShowBoundingBox + ); + const dispatch = useAppDispatch(); + + const handleShowBoundingBox = () => + dispatch(setShouldShowBoundingBox(!shouldShowBoundingBox)); + return ( + : } + onClick={handleShowBoundingBox} + background={'none'} + padding={0} + /> + ); +} diff --git a/frontend/src/features/options/AdvancedOptions/Inpainting/ClearBrushHistory.tsx b/frontend/src/features/options/AdvancedOptions/Inpainting/ClearBrushHistory.tsx new file mode 100644 index 0000000000..fd47f50196 --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/Inpainting/ClearBrushHistory.tsx @@ -0,0 +1,56 @@ +import { useToast } from '@chakra-ui/react'; +import { createSelector } from '@reduxjs/toolkit'; +import { + RootState, + useAppDispatch, + useAppSelector, +} from '../../../../app/store'; +import IAIButton from '../../../../common/components/IAIButton'; +import { + InpaintingState, + setClearBrushHistory, +} from '../../../tabs/Inpainting/inpaintingSlice'; +import _ from 'lodash'; + +const clearBrushHistorySelector = createSelector( + (state: RootState) => state.inpainting, + (inpainting: InpaintingState) => { + const { pastLines, futureLines } = inpainting; + return { + mayClearBrushHistory: + futureLines.length > 0 || pastLines.length > 0 ? false : true, + }; + }, + { + memoizeOptions: { + resultEqualityCheck: _.isEqual, + }, + } +); + +export default function ClearBrushHistory() { + const dispatch = useAppDispatch(); + const toast = useToast(); + + const { mayClearBrushHistory } = useAppSelector(clearBrushHistorySelector); + + const handleClearBrushHistory = () => { + dispatch(setClearBrushHistory()); + toast({ + title: 'Brush Stroke History Cleared', + status: 'success', + duration: 2500, + isClosable: true, + }); + }; + return ( + + Clear Brush History + + ); +} diff --git a/frontend/src/features/options/AdvancedOptions/Inpainting/InpaintReplace.tsx b/frontend/src/features/options/AdvancedOptions/Inpainting/InpaintReplace.tsx new file mode 100644 index 0000000000..5333f7b8ab --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/Inpainting/InpaintReplace.tsx @@ -0,0 +1,70 @@ +import React, { ChangeEvent } from 'react'; +import { + RootState, + useAppDispatch, + useAppSelector, +} from '../../../../app/store'; +import IAINumberInput from '../../../../common/components/IAINumberInput'; +import _ from 'lodash'; +import { createSelector } from '@reduxjs/toolkit'; +import { + InpaintingState, + setInpaintReplace, + setShouldUseInpaintReplace, +} from '../../../tabs/Inpainting/inpaintingSlice'; +import IAISwitch from '../../../../common/components/IAISwitch'; + +const inpaintReplaceSelector = createSelector( + (state: RootState) => state.inpainting, + (inpainting: InpaintingState) => { + const { inpaintReplace, shouldUseInpaintReplace } = inpainting; + return { + inpaintReplace, + shouldUseInpaintReplace, + }; + }, + { + memoizeOptions: { + resultEqualityCheck: _.isEqual, + }, + } +); + +export default function InpaintReplace() { + const { inpaintReplace, shouldUseInpaintReplace } = useAppSelector( + inpaintReplaceSelector + ); + + const dispatch = useAppDispatch(); + + return ( +
+ { + dispatch(setInpaintReplace(v)); + }} + /> + ) => + dispatch(setShouldUseInpaintReplace(e.target.checked)) + } + /> +
+ ); +} diff --git a/frontend/src/features/options/AdvancedOptions/Inpainting/InpaintingSettings.tsx b/frontend/src/features/options/AdvancedOptions/Inpainting/InpaintingSettings.tsx new file mode 100644 index 0000000000..2c9181dfa1 --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/Inpainting/InpaintingSettings.tsx @@ -0,0 +1,13 @@ +import BoundingBoxSettings from './BoundingBoxSettings/BoundingBoxSettings'; +import InpaintReplace from './InpaintReplace'; +import ClearBrushHistory from './ClearBrushHistory'; + +export default function InpaintingSettings() { + return ( + <> + + + + + ); +} diff --git a/frontend/src/features/options/AdvancedOptions/Output/HiresOptions.tsx b/frontend/src/features/options/AdvancedOptions/Output/HiresOptions.tsx new file mode 100644 index 0000000000..fc5606d027 --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/Output/HiresOptions.tsx @@ -0,0 +1,34 @@ +import { Flex } from '@chakra-ui/react'; +import { ChangeEvent } from 'react'; +import { + RootState, + useAppDispatch, + useAppSelector, +} from '../../../../app/store'; +import IAISwitch from '../../../../common/components/IAISwitch'; +import { setHiresFix } from '../../optionsSlice'; + +/** + * Hires Fix Toggle + */ +const HiresOptions = () => { + const dispatch = useAppDispatch(); + + const hiresFix = useAppSelector((state: RootState) => state.options.hiresFix); + + const handleChangeHiresFix = (e: ChangeEvent) => + dispatch(setHiresFix(e.target.checked)); + + return ( + + + + ); +}; + +export default HiresOptions; diff --git a/frontend/src/features/options/AdvancedOptions/Output/OutputHeader.tsx b/frontend/src/features/options/AdvancedOptions/Output/OutputHeader.tsx new file mode 100644 index 0000000000..6c8603d9f8 --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/Output/OutputHeader.tsx @@ -0,0 +1,11 @@ +import { Box } from '@chakra-ui/react'; + +const OutputHeader = () => { + return ( + + Other Options + + ); +}; + +export default OutputHeader; diff --git a/frontend/src/features/options/AdvancedOptions/Output/OutputOptions.tsx b/frontend/src/features/options/AdvancedOptions/Output/OutputOptions.tsx new file mode 100644 index 0000000000..7a8af1db00 --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/Output/OutputOptions.tsx @@ -0,0 +1,14 @@ +import { Flex } from '@chakra-ui/react'; +import HiresOptions from './HiresOptions'; +import SeamlessOptions from './SeamlessOptions'; + +const OutputOptions = () => { + return ( + + + + + ); +}; + +export default OutputOptions; diff --git a/frontend/src/features/options/AdvancedOptions/Output/SeamlessOptions.tsx b/frontend/src/features/options/AdvancedOptions/Output/SeamlessOptions.tsx new file mode 100644 index 0000000000..df15292870 --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/Output/SeamlessOptions.tsx @@ -0,0 +1,34 @@ +import { Flex } from '@chakra-ui/react'; +import { ChangeEvent } from 'react'; +import { + RootState, + useAppDispatch, + useAppSelector, +} from '../../../../app/store'; +import IAISwitch from '../../../../common/components/IAISwitch'; +import { setSeamless } from '../../optionsSlice'; + +/** + * Seamless tiling toggle + */ +const SeamlessOptions = () => { + const dispatch = useAppDispatch(); + + const seamless = useAppSelector((state: RootState) => state.options.seamless); + + const handleChangeSeamless = (e: ChangeEvent) => + dispatch(setSeamless(e.target.checked)); + + return ( + + + + ); +}; + +export default SeamlessOptions; diff --git a/frontend/src/features/options/AdvancedOptions/Seed/Perlin.tsx b/frontend/src/features/options/AdvancedOptions/Seed/Perlin.tsx new file mode 100644 index 0000000000..4b3df41305 --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/Seed/Perlin.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import { + RootState, + useAppDispatch, + useAppSelector, +} from '../../../../app/store'; +import IAINumberInput from '../../../../common/components/IAINumberInput'; +import { setPerlin } from '../../optionsSlice'; + +export default function Perlin() { + const dispatch = useAppDispatch(); + const perlin = useAppSelector((state: RootState) => state.options.perlin); + + const handleChangePerlin = (v: number) => dispatch(setPerlin(v)); + + return ( + + ); +} diff --git a/frontend/src/features/options/AdvancedOptions/Seed/RandomizeSeed.tsx b/frontend/src/features/options/AdvancedOptions/Seed/RandomizeSeed.tsx new file mode 100644 index 0000000000..904d82dcc2 --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/Seed/RandomizeSeed.tsx @@ -0,0 +1,28 @@ +import React, { ChangeEvent } from 'react'; + +import { + RootState, + useAppDispatch, + useAppSelector, +} from '../../../../app/store'; +import IAISwitch from '../../../../common/components/IAISwitch'; +import { setShouldRandomizeSeed } from '../../optionsSlice'; + +export default function RandomizeSeed() { + const dispatch = useAppDispatch(); + + const shouldRandomizeSeed = useAppSelector( + (state: RootState) => state.options.shouldRandomizeSeed + ); + + const handleChangeShouldRandomizeSeed = (e: ChangeEvent) => + dispatch(setShouldRandomizeSeed(e.target.checked)); + + return ( + + ); +} diff --git a/frontend/src/features/options/AdvancedOptions/Seed/Seed.tsx b/frontend/src/features/options/AdvancedOptions/Seed/Seed.tsx new file mode 100644 index 0000000000..3fc33012cc --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/Seed/Seed.tsx @@ -0,0 +1,39 @@ +import React from 'react'; +import { NUMPY_RAND_MAX, NUMPY_RAND_MIN } from '../../../../app/constants'; +import { + RootState, + useAppDispatch, + useAppSelector, +} from '../../../../app/store'; +import IAINumberInput from '../../../../common/components/IAINumberInput'; +import { setSeed } from '../../optionsSlice'; + +export default function Seed() { + const seed = useAppSelector((state: RootState) => state.options.seed); + const shouldRandomizeSeed = useAppSelector( + (state: RootState) => state.options.shouldRandomizeSeed + ); + const shouldGenerateVariations = useAppSelector( + (state: RootState) => state.options.shouldGenerateVariations + ); + + const dispatch = useAppDispatch(); + + const handleChangeSeed = (v: number) => dispatch(setSeed(v)); + + return ( + + ); +} diff --git a/frontend/src/features/options/AdvancedOptions/Seed/SeedHeader.tsx b/frontend/src/features/options/AdvancedOptions/Seed/SeedHeader.tsx new file mode 100644 index 0000000000..9c05b96d68 --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/Seed/SeedHeader.tsx @@ -0,0 +1,11 @@ +import { Box } from '@chakra-ui/react'; + +const SeedHeader = () => { + return ( + + Seed + + ); +}; + +export default SeedHeader; diff --git a/frontend/src/features/options/AdvancedOptions/Seed/SeedOptions.tsx b/frontend/src/features/options/AdvancedOptions/Seed/SeedOptions.tsx new file mode 100644 index 0000000000..9352466752 --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/Seed/SeedOptions.tsx @@ -0,0 +1,29 @@ +import { Flex } from '@chakra-ui/react'; +import RandomizeSeed from './RandomizeSeed'; +import Seed from './Seed'; +import ShuffleSeed from './ShuffleSeed'; +import Threshold from './Threshold'; +import Perlin from './Perlin'; + +/** + * Seed & variation options. Includes iteration, seed, seed randomization, variation options. + */ +const SeedOptions = () => { + return ( + + + + + + + + + + + + + + ); +}; + +export default SeedOptions; diff --git a/frontend/src/features/options/AdvancedOptions/Seed/ShuffleSeed.tsx b/frontend/src/features/options/AdvancedOptions/Seed/ShuffleSeed.tsx new file mode 100644 index 0000000000..d2b235ddd0 --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/Seed/ShuffleSeed.tsx @@ -0,0 +1,30 @@ +import { Button } from '@chakra-ui/react'; +import React from 'react'; +import { NUMPY_RAND_MAX, NUMPY_RAND_MIN } from '../../../../app/constants'; +import { + RootState, + useAppDispatch, + useAppSelector, +} from '../../../../app/store'; +import randomInt from '../../../../common/util/randomInt'; +import { setSeed } from '../../optionsSlice'; + +export default function ShuffleSeed() { + const dispatch = useAppDispatch(); + const shouldRandomizeSeed = useAppSelector( + (state: RootState) => state.options.shouldRandomizeSeed + ); + + const handleClickRandomizeSeed = () => + dispatch(setSeed(randomInt(NUMPY_RAND_MIN, NUMPY_RAND_MAX))); + + return ( + + ); +} diff --git a/frontend/src/features/options/AdvancedOptions/Seed/Threshold.tsx b/frontend/src/features/options/AdvancedOptions/Seed/Threshold.tsx new file mode 100644 index 0000000000..1b0f0e106e --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/Seed/Threshold.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import { + RootState, + useAppDispatch, + useAppSelector, +} from '../../../../app/store'; +import IAINumberInput from '../../../../common/components/IAINumberInput'; +import { setThreshold } from '../../optionsSlice'; + +export default function Threshold() { + const dispatch = useAppDispatch(); + const threshold = useAppSelector( + (state: RootState) => state.options.threshold + ); + + const handleChangeThreshold = (v: number) => dispatch(setThreshold(v)); + + return ( + + ); +} diff --git a/frontend/src/features/options/AdvancedOptions/Upscale/UpscaleHeader.tsx b/frontend/src/features/options/AdvancedOptions/Upscale/UpscaleHeader.tsx new file mode 100644 index 0000000000..4bb0347f04 --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/Upscale/UpscaleHeader.tsx @@ -0,0 +1,38 @@ +import { Flex } from '@chakra-ui/layout'; +import React, { ChangeEvent } from 'react'; +import { + RootState, + useAppDispatch, + useAppSelector, +} from '../../../../app/store'; +import IAISwitch from '../../../../common/components/IAISwitch'; +import { setShouldRunESRGAN } from '../../optionsSlice'; + +export default function UpscaleHeader() { + const isESRGANAvailable = useAppSelector( + (state: RootState) => state.system.isESRGANAvailable + ); + + const shouldRunESRGAN = useAppSelector( + (state: RootState) => state.options.shouldRunESRGAN + ); + + const dispatch = useAppDispatch(); + const handleChangeShouldRunESRGAN = (e: ChangeEvent) => + dispatch(setShouldRunESRGAN(e.target.checked)); + return ( + +

Upscale

+ +
+ ); +} diff --git a/frontend/src/features/options/AdvancedOptions/Upscale/UpscaleOptions.scss b/frontend/src/features/options/AdvancedOptions/Upscale/UpscaleOptions.scss new file mode 100644 index 0000000000..1d89c031b8 --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/Upscale/UpscaleOptions.scss @@ -0,0 +1,5 @@ +.upscale-options { + display: grid; + grid-template-columns: auto 1fr; + column-gap: 1rem; +} diff --git a/frontend/src/features/options/AdvancedOptions/Upscale/UpscaleOptions.tsx b/frontend/src/features/options/AdvancedOptions/Upscale/UpscaleOptions.tsx new file mode 100644 index 0000000000..482f773aa0 --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/Upscale/UpscaleOptions.tsx @@ -0,0 +1,85 @@ +import { RootState } from '../../../../app/store'; +import { useAppDispatch, useAppSelector } from '../../../../app/store'; + +import { + setUpscalingLevel, + setUpscalingStrength, + UpscalingLevel, + OptionsState, +} from '../../optionsSlice'; + +import { UPSCALING_LEVELS } from '../../../../app/constants'; +import { createSelector } from '@reduxjs/toolkit'; +import { isEqual } from 'lodash'; +import { SystemState } from '../../../system/systemSlice'; +import { ChangeEvent } from 'react'; +import IAINumberInput from '../../../../common/components/IAINumberInput'; +import IAISelect from '../../../../common/components/IAISelect'; + +const optionsSelector = createSelector( + (state: RootState) => state.options, + (options: OptionsState) => { + return { + upscalingLevel: options.upscalingLevel, + upscalingStrength: options.upscalingStrength, + }; + }, + { + memoizeOptions: { + resultEqualityCheck: isEqual, + }, + } +); + +const systemSelector = createSelector( + (state: RootState) => state.system, + (system: SystemState) => { + return { + isESRGANAvailable: system.isESRGANAvailable, + }; + }, + { + memoizeOptions: { + resultEqualityCheck: isEqual, + }, + } +); + +/** + * Displays upscaling/ESRGAN options (level and strength). + */ +const UpscaleOptions = () => { + const dispatch = useAppDispatch(); + const { upscalingLevel, upscalingStrength } = useAppSelector(optionsSelector); + + const { isESRGANAvailable } = useAppSelector(systemSelector); + + const handleChangeLevel = (e: ChangeEvent) => + dispatch(setUpscalingLevel(Number(e.target.value) as UpscalingLevel)); + + const handleChangeStrength = (v: number) => dispatch(setUpscalingStrength(v)); + + return ( +
+ + +
+ ); +}; + +export default UpscaleOptions; diff --git a/frontend/src/features/options/AdvancedOptions/Variations/GenerateVariations.tsx b/frontend/src/features/options/AdvancedOptions/Variations/GenerateVariations.tsx new file mode 100644 index 0000000000..f17685b0a9 --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/Variations/GenerateVariations.tsx @@ -0,0 +1,28 @@ +import React, { ChangeEvent } from 'react'; +import { + RootState, + useAppDispatch, + useAppSelector, +} from '../../../../app/store'; +import IAISwitch from '../../../../common/components/IAISwitch'; +import { setShouldGenerateVariations } from '../../optionsSlice'; + +export default function GenerateVariations() { + const shouldGenerateVariations = useAppSelector( + (state: RootState) => state.options.shouldGenerateVariations + ); + + const dispatch = useAppDispatch(); + + const handleChangeShouldGenerateVariations = ( + e: ChangeEvent + ) => dispatch(setShouldGenerateVariations(e.target.checked)); + + return ( + + ); +} diff --git a/frontend/src/features/options/AdvancedOptions/Variations/SeedWeights.tsx b/frontend/src/features/options/AdvancedOptions/Variations/SeedWeights.tsx new file mode 100644 index 0000000000..10e7d754b4 --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/Variations/SeedWeights.tsx @@ -0,0 +1,37 @@ +import React, { ChangeEvent } from 'react'; +import { + RootState, + useAppDispatch, + useAppSelector, +} from '../../../../app/store'; +import IAIInput from '../../../../common/components/IAIInput'; +import { validateSeedWeights } from '../../../../common/util/seedWeightPairs'; +import { setSeedWeights } from '../../optionsSlice'; + +export default function SeedWeights() { + const seedWeights = useAppSelector( + (state: RootState) => state.options.seedWeights + ); + + const shouldGenerateVariations = useAppSelector( + (state: RootState) => state.options.shouldGenerateVariations + ); + + const dispatch = useAppDispatch(); + + const handleChangeSeedWeights = (e: ChangeEvent) => + dispatch(setSeedWeights(e.target.value)); + + return ( + + ); +} diff --git a/frontend/src/features/options/AdvancedOptions/Variations/VariationAmount.tsx b/frontend/src/features/options/AdvancedOptions/Variations/VariationAmount.tsx new file mode 100644 index 0000000000..24fc81bb3e --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/Variations/VariationAmount.tsx @@ -0,0 +1,35 @@ +import React from 'react'; +import { + RootState, + useAppDispatch, + useAppSelector, +} from '../../../../app/store'; +import IAINumberInput from '../../../../common/components/IAINumberInput'; +import { setVariationAmount } from '../../optionsSlice'; + +export default function VariationAmount() { + const variationAmount = useAppSelector( + (state: RootState) => state.options.variationAmount + ); + + const shouldGenerateVariations = useAppSelector( + (state: RootState) => state.options.shouldGenerateVariations + ); + + const dispatch = useAppDispatch(); + const handleChangevariationAmount = (v: number) => + dispatch(setVariationAmount(v)); + + return ( + + ); +} diff --git a/frontend/src/features/options/AdvancedOptions/Variations/VariationsHeader.tsx b/frontend/src/features/options/AdvancedOptions/Variations/VariationsHeader.tsx new file mode 100644 index 0000000000..ab02fad1f6 --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/Variations/VariationsHeader.tsx @@ -0,0 +1,17 @@ +import { Flex } from '@chakra-ui/react'; +import React from 'react'; +import GenerateVariations from './GenerateVariations'; + +export default function VariationsHeader() { + return ( + +

Variations

+ +
+ ); +} diff --git a/frontend/src/features/options/AdvancedOptions/Variations/VariationsOptions.tsx b/frontend/src/features/options/AdvancedOptions/Variations/VariationsOptions.tsx new file mode 100644 index 0000000000..3062d02993 --- /dev/null +++ b/frontend/src/features/options/AdvancedOptions/Variations/VariationsOptions.tsx @@ -0,0 +1,17 @@ +import { Flex } from '@chakra-ui/react'; +import SeedWeights from './SeedWeights'; +import VariationAmount from './VariationAmount'; + +/** + * Seed & variation options. Includes iteration, seed, seed randomization, variation options. + */ +const VariationsOptions = () => { + return ( + + + + + ); +}; + +export default VariationsOptions; diff --git a/frontend/src/features/options/MainOptions/MainAdvancedOptionsCheckbox.tsx b/frontend/src/features/options/MainOptions/MainAdvancedOptionsCheckbox.tsx new file mode 100644 index 0000000000..b8b580856e --- /dev/null +++ b/frontend/src/features/options/MainOptions/MainAdvancedOptionsCheckbox.tsx @@ -0,0 +1,23 @@ +import React, { ChangeEvent } from 'react'; +import { RootState, useAppDispatch, useAppSelector } from '../../../app/store'; +import IAICheckbox from '../../../common/components/IAICheckbox'; +import { setShowAdvancedOptions } from '../optionsSlice'; + +export default function MainAdvancedOptionsCheckbox() { + const showAdvancedOptions = useAppSelector( + (state: RootState) => state.options.showAdvancedOptions + ); + const dispatch = useAppDispatch(); + + const handleShowAdvancedOptions = (e: ChangeEvent) => + dispatch(setShowAdvancedOptions(e.target.checked)); + + return ( + + ); +} diff --git a/frontend/src/features/options/MainOptions/MainCFGScale.tsx b/frontend/src/features/options/MainOptions/MainCFGScale.tsx new file mode 100644 index 0000000000..07395c9fb6 --- /dev/null +++ b/frontend/src/features/options/MainOptions/MainCFGScale.tsx @@ -0,0 +1,28 @@ +import React from 'react'; +import { RootState, useAppDispatch, useAppSelector } from '../../../app/store'; +import IAINumberInput from '../../../common/components/IAINumberInput'; +import { setCfgScale } from '../optionsSlice'; +import { fontSize, inputWidth } from './MainOptions'; + +export default function MainCFGScale() { + const dispatch = useAppDispatch(); + const cfgScale = useAppSelector((state: RootState) => state.options.cfgScale); + + const handleChangeCfgScale = (v: number) => dispatch(setCfgScale(v)); + + return ( + + ); +} diff --git a/frontend/src/features/options/MainOptions/MainHeight.tsx b/frontend/src/features/options/MainOptions/MainHeight.tsx new file mode 100644 index 0000000000..78285f7944 --- /dev/null +++ b/frontend/src/features/options/MainOptions/MainHeight.tsx @@ -0,0 +1,29 @@ +import React, { ChangeEvent } from 'react'; +import { HEIGHTS } from '../../../app/constants'; +import { RootState, useAppDispatch, useAppSelector } from '../../../app/store'; +import IAISelect from '../../../common/components/IAISelect'; +import { activeTabNameSelector } from '../optionsSelectors'; +import { setHeight } from '../optionsSlice'; +import { fontSize } from './MainOptions'; + +export default function MainHeight() { + const height = useAppSelector((state: RootState) => state.options.height); + const activeTabName = useAppSelector(activeTabNameSelector); + const dispatch = useAppDispatch(); + + const handleChangeHeight = (e: ChangeEvent) => + dispatch(setHeight(Number(e.target.value))); + + return ( + + ); +} diff --git a/frontend/src/features/options/MainOptions/MainIterations.tsx b/frontend/src/features/options/MainOptions/MainIterations.tsx new file mode 100644 index 0000000000..e244e02f05 --- /dev/null +++ b/frontend/src/features/options/MainOptions/MainIterations.tsx @@ -0,0 +1,50 @@ +import { createSelector } from '@reduxjs/toolkit'; +import _ from 'lodash'; +import React from 'react'; +import { RootState, useAppDispatch, useAppSelector } from '../../../app/store'; +import IAINumberInput from '../../../common/components/IAINumberInput'; +import { mayGenerateMultipleImagesSelector } from '../optionsSelectors'; +import { OptionsState, setIterations } from '../optionsSlice'; +import { fontSize, inputWidth } from './MainOptions'; + +const mainIterationsSelector = createSelector( + [(state: RootState) => state.options, mayGenerateMultipleImagesSelector], + (options: OptionsState, mayGenerateMultipleImages) => { + const { iterations } = options; + + return { + iterations, + mayGenerateMultipleImages, + }; + }, + { + memoizeOptions: { + resultEqualityCheck: _.isEqual, + }, + } +); + +export default function MainIterations() { + const dispatch = useAppDispatch(); + const { iterations, mayGenerateMultipleImages } = useAppSelector( + mainIterationsSelector + ); + + const handleChangeIterations = (v: number) => dispatch(setIterations(v)); + + return ( + + ); +} diff --git a/frontend/src/features/options/MainOptions/MainOptions.scss b/frontend/src/features/options/MainOptions/MainOptions.scss new file mode 100644 index 0000000000..b9854397a5 --- /dev/null +++ b/frontend/src/features/options/MainOptions/MainOptions.scss @@ -0,0 +1,47 @@ +@use '../../../styles/Mixins/' as *; + +.main-options { + display: grid; + row-gap: 1rem; +} + +.main-options-list { + display: grid; + row-gap: 1rem; +} + +.main-options-row { + display: grid; + grid-template-columns: repeat(3, auto); + column-gap: 1rem; + max-width: $options-bar-max-width; +} + +.main-option-block { + border-radius: 0.5rem; + display: grid !important; + grid-template-columns: auto !important; + row-gap: 0.4rem; + + .invokeai__number-input-form-label, + .invokeai__select-label { + width: 100%; + font-size: 0.9rem !important; + font-weight: bold; + } + + .number-input-entry { + padding: 0; + height: 2.4rem; + } + + .iai-select-picker { + height: 2.4rem; + border-radius: 0.3rem; + } +} + +.advanced-options-checkbox { + padding: 1rem; + font-weight: bold; +} diff --git a/frontend/src/features/options/MainOptions/MainOptions.tsx b/frontend/src/features/options/MainOptions/MainOptions.tsx new file mode 100644 index 0000000000..092cdea50d --- /dev/null +++ b/frontend/src/features/options/MainOptions/MainOptions.tsx @@ -0,0 +1,28 @@ +import MainCFGScale from './MainCFGScale'; +import MainHeight from './MainHeight'; +import MainIterations from './MainIterations'; +import MainSampler from './MainSampler'; +import MainSteps from './MainSteps'; +import MainWidth from './MainWidth'; + +export const fontSize = '0.9rem'; +export const inputWidth = 'auto'; + +export default function MainOptions() { + return ( +
+
+
+ + + +
+
+ + + +
+
+
+ ); +} diff --git a/frontend/src/features/options/MainOptions/MainSampler.tsx b/frontend/src/features/options/MainOptions/MainSampler.tsx new file mode 100644 index 0000000000..c6b0ae7dd3 --- /dev/null +++ b/frontend/src/features/options/MainOptions/MainSampler.tsx @@ -0,0 +1,25 @@ +import React, { ChangeEvent } from 'react'; +import { SAMPLERS } from '../../../app/constants'; +import { RootState, useAppDispatch, useAppSelector } from '../../../app/store'; +import IAISelect from '../../../common/components/IAISelect'; +import { setSampler } from '../optionsSlice'; +import { fontSize } from './MainOptions'; + +export default function MainSampler() { + const sampler = useAppSelector((state: RootState) => state.options.sampler); + const dispatch = useAppDispatch(); + + const handleChangeSampler = (e: ChangeEvent) => + dispatch(setSampler(e.target.value)); + + return ( + + ); +} diff --git a/frontend/src/features/options/MainOptions/MainSteps.tsx b/frontend/src/features/options/MainOptions/MainSteps.tsx new file mode 100644 index 0000000000..20670fc208 --- /dev/null +++ b/frontend/src/features/options/MainOptions/MainSteps.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import { RootState, useAppDispatch, useAppSelector } from '../../../app/store'; +import IAINumberInput from '../../../common/components/IAINumberInput'; +import { setSteps } from '../optionsSlice'; +import { fontSize, inputWidth } from './MainOptions'; + +export default function MainSteps() { + const dispatch = useAppDispatch(); + const steps = useAppSelector((state: RootState) => state.options.steps); + + const handleChangeSteps = (v: number) => dispatch(setSteps(v)); + + return ( + + ); +} diff --git a/frontend/src/features/options/MainOptions/MainWidth.tsx b/frontend/src/features/options/MainOptions/MainWidth.tsx new file mode 100644 index 0000000000..69841f3954 --- /dev/null +++ b/frontend/src/features/options/MainOptions/MainWidth.tsx @@ -0,0 +1,30 @@ +import React, { ChangeEvent } from 'react'; +import { WIDTHS } from '../../../app/constants'; +import { RootState, useAppDispatch, useAppSelector } from '../../../app/store'; +import IAISelect from '../../../common/components/IAISelect'; +import { activeTabNameSelector } from '../optionsSelectors'; +import { setWidth } from '../optionsSlice'; +import { fontSize } from './MainOptions'; + +export default function MainWidth() { + const width = useAppSelector((state: RootState) => state.options.width); + const activeTabName = useAppSelector(activeTabNameSelector); + + const dispatch = useAppDispatch(); + + const handleChangeWidth = (e: ChangeEvent) => + dispatch(setWidth(Number(e.target.value))); + + return ( + + ); +} diff --git a/frontend/src/features/options/OptionsAccordion.tsx b/frontend/src/features/options/OptionsAccordion.tsx new file mode 100644 index 0000000000..9971d017a0 --- /dev/null +++ b/frontend/src/features/options/OptionsAccordion.tsx @@ -0,0 +1,65 @@ +import { Accordion, ExpandedIndex } from '@chakra-ui/react'; +import { RootState, useAppDispatch, useAppSelector } from '../../app/store'; +import { setOpenAccordions } from '../system/systemSlice'; +import InvokeAccordionItem, { + InvokeAccordionItemProps, +} from './AccordionItems/InvokeAccordionItem'; +import { ReactElement } from 'react'; + +type OptionsAccordionType = { + [optionAccordionKey: string]: InvokeAccordionItemProps; +}; + +type OptionAccordionsType = { + accordionInfo: OptionsAccordionType; +}; + +/** + * Main container for generation and processing parameters. + */ +const OptionsAccordion = (props: OptionAccordionsType) => { + const { accordionInfo } = props; + + const openAccordions = useAppSelector( + (state: RootState) => state.system.openAccordions + ); + + const dispatch = useAppDispatch(); + + /** + * Stores accordion state in redux so preferred UI setup is retained. + */ + const handleChangeAccordionState = (openAccordions: ExpandedIndex) => + dispatch(setOpenAccordions(openAccordions)); + + const renderAccordions = () => { + const accordionsToRender: ReactElement[] = []; + if (accordionInfo) { + Object.keys(accordionInfo).forEach((key) => { + accordionsToRender.push( + + ); + }); + } + return accordionsToRender; + }; + + return ( + + {renderAccordions()} + + ); +}; + +export default OptionsAccordion; diff --git a/frontend/src/features/options/ProcessButtons/CancelButton.tsx b/frontend/src/features/options/ProcessButtons/CancelButton.tsx new file mode 100644 index 0000000000..7034a0338f --- /dev/null +++ b/frontend/src/features/options/ProcessButtons/CancelButton.tsx @@ -0,0 +1,58 @@ +import { MdCancel } from 'react-icons/md'; +import { cancelProcessing } from '../../../app/socketio/actions'; +import { RootState, useAppDispatch, useAppSelector } from '../../../app/store'; +import IAIIconButton, { + IAIIconButtonProps, +} from '../../../common/components/IAIIconButton'; +import { useHotkeys } from 'react-hotkeys-hook'; +import { createSelector } from '@reduxjs/toolkit'; +import { SystemState } from '../../system/systemSlice'; +import _ from 'lodash'; + +const cancelButtonSelector = createSelector( + (state: RootState) => state.system, + (system: SystemState) => { + return { + isProcessing: system.isProcessing, + isConnected: system.isConnected, + isCancelable: system.isCancelable, + }; + }, + { + memoizeOptions: { + resultEqualityCheck: _.isEqual, + }, + } +); + +export default function CancelButton( + props: Omit +) { + const { ...rest } = props; + const dispatch = useAppDispatch(); + const { isProcessing, isConnected, isCancelable } = + useAppSelector(cancelButtonSelector); + const handleClickCancel = () => dispatch(cancelProcessing()); + + useHotkeys( + 'shift+x', + () => { + if ((isConnected || isProcessing) && isCancelable) { + handleClickCancel(); + } + }, + [isConnected, isProcessing, isCancelable] + ); + + return ( + } + tooltip="Cancel" + aria-label="Cancel" + isDisabled={!isConnected || !isProcessing || !isCancelable} + onClick={handleClickCancel} + styleClass="cancel-btn" + {...rest} + /> + ); +} diff --git a/frontend/src/features/options/ProcessButtons/InvokeButton.tsx b/frontend/src/features/options/ProcessButtons/InvokeButton.tsx new file mode 100644 index 0000000000..e9a61002b4 --- /dev/null +++ b/frontend/src/features/options/ProcessButtons/InvokeButton.tsx @@ -0,0 +1,99 @@ +import { ListItem, UnorderedList } from '@chakra-ui/react'; +import { useHotkeys } from 'react-hotkeys-hook'; +import { FaPlay } from 'react-icons/fa'; +import { readinessSelector } from '../../../app/selectors/readinessSelector'; +import { generateImage } from '../../../app/socketio/actions'; +import { useAppDispatch, useAppSelector } from '../../../app/store'; +import IAIButton, { + IAIButtonProps, +} from '../../../common/components/IAIButton'; +import IAIIconButton, { + IAIIconButtonProps, +} from '../../../common/components/IAIIconButton'; +import IAIPopover from '../../../common/components/IAIPopover'; +import { activeTabNameSelector } from '../optionsSelectors'; + +interface InvokeButton + extends Omit { + iconButton?: boolean; +} + +export default function InvokeButton(props: InvokeButton) { + const { iconButton = false, ...rest } = props; + const dispatch = useAppDispatch(); + const { isReady, reasonsWhyNotReady } = useAppSelector(readinessSelector); + const activeTabName = useAppSelector(activeTabNameSelector); + + const handleClickGenerate = () => { + dispatch(generateImage(activeTabName)); + }; + + useHotkeys( + 'ctrl+enter, cmd+enter', + () => { + if (isReady) { + dispatch(generateImage(activeTabName)); + } + }, + [isReady, activeTabName] + ); + + const buttonComponent = ( +
+ {iconButton ? ( + } + isDisabled={!isReady} + onClick={handleClickGenerate} + className="invoke-btn invoke" + tooltip="Invoke" + tooltipProps={{ placement: 'bottom' }} + {...rest} + /> + ) : ( + + Invoke + + )} +
+ ); + + return isReady ? ( + buttonComponent + ) : ( + + {reasonsWhyNotReady && ( + + {reasonsWhyNotReady.map((reason, i) => ( + {reason} + ))} + + )} + + ); + + // return isReady ? ( + // buttonComponent + // ) : ( + // + // {reasonsWhyNotReady ? ( + // + // {reasonsWhyNotReady.map((reason, i) => ( + // {reason} + // ))} + // + // ) : ( + // 'test' + // )} + // + // ); +} diff --git a/frontend/src/features/options/ProcessButtons/Loopback.tsx b/frontend/src/features/options/ProcessButtons/Loopback.tsx new file mode 100644 index 0000000000..6d360f4f25 --- /dev/null +++ b/frontend/src/features/options/ProcessButtons/Loopback.tsx @@ -0,0 +1,31 @@ +import { createSelector } from '@reduxjs/toolkit'; +import { FaRecycle } from 'react-icons/fa'; +import { RootState, useAppDispatch, useAppSelector } from '../../../app/store'; +import IAIIconButton from '../../../common/components/IAIIconButton'; +import { OptionsState, setShouldLoopback } from '../optionsSlice'; + +const loopbackSelector = createSelector( + (state: RootState) => state.options, + (options: OptionsState) => options.shouldLoopback +); + +const LoopbackButton = () => { + const dispatch = useAppDispatch(); + const shouldLoopback = useAppSelector(loopbackSelector); + + return ( + } + onClick={() => { + dispatch(setShouldLoopback(!shouldLoopback)); + }} + /> + ); +}; + +export default LoopbackButton; diff --git a/frontend/src/features/options/ProcessButtons/ProcessButtons.scss b/frontend/src/features/options/ProcessButtons/ProcessButtons.scss new file mode 100644 index 0000000000..0c107e0865 --- /dev/null +++ b/frontend/src/features/options/ProcessButtons/ProcessButtons.scss @@ -0,0 +1,59 @@ +@use '../../../styles/Mixins/' as *; + +.process-buttons { + display: flex; + column-gap: 0.5rem; +} + +.invoke-btn { + flex-grow: 1; + width: 100%; + svg { + width: 18px !important; + height: 18px !important; + } + @include Button( + $btn-color: var(--accent-color), + $btn-color-hover: var(--accent-color-hover), + // $btn-width: 5rem + ); +} + +.cancel-btn { + @include Button( + $btn-color: var(--destructive-color), + $btn-color-hover: var(--destructive-color-hover), + // $btn-width: 3rem + ); +} + +.loopback-btn { + &[data-as-checkbox='true'] { + background-color: var(--btn-grey); + border: 3px solid var(--btn-grey); + svg { + fill: var(--text-color); + } + &:hover { + background-color: var(--btn-grey); + border-color: var(--btn-checkbox-border-hover); + svg { + fill: var(--text-color); + } + } + &[data-selected='true'] { + border-color: var(--accent-color); + background-color: var(--btn-grey); + svg { + fill: var(--text-color); + } + &:hover { + border-color: var(--accent-color); + background-color: var(--btn-grey); + svg { + fill: var(--text-color); + } + } + } + } +} diff --git a/frontend/src/features/options/ProcessButtons/ProcessButtons.tsx b/frontend/src/features/options/ProcessButtons/ProcessButtons.tsx new file mode 100644 index 0000000000..b27e8fe7bb --- /dev/null +++ b/frontend/src/features/options/ProcessButtons/ProcessButtons.tsx @@ -0,0 +1,18 @@ +import InvokeButton from './InvokeButton'; +import CancelButton from './CancelButton'; +import LoopbackButton from './Loopback'; + +/** + * Buttons to start and cancel image generation. + */ +const ProcessButtons = () => { + return ( +
+ + + +
+ ); +}; + +export default ProcessButtons; diff --git a/frontend/src/features/options/PromptInput/PromptInput.scss b/frontend/src/features/options/PromptInput/PromptInput.scss new file mode 100644 index 0000000000..e7baf2f5f9 --- /dev/null +++ b/frontend/src/features/options/PromptInput/PromptInput.scss @@ -0,0 +1,34 @@ +.prompt-bar { + display: grid; + row-gap: 1rem; + + input, + textarea { + background-color: var(--prompt-bg-color); + font-size: 1rem; + border: 2px solid var(--border-color); + + &:hover { + border: 2px solid var(--border-color-light); + } + + &:focus-visible { + border: 2px solid var(--input-border-color); + box-shadow: 0 0 10px 0 var(--input-box-shadow-color); + } + + &[aria-invalid='true'] { + border: 2px solid var(--border-color-invalid); + box-shadow: 0 0 10px 0 var(--box-shadow-color-invalid); + } + + &:disabled { + border: 2px solid var(--border-color); + box-shadow: none; + } + } + + textarea { + min-height: 10rem; + } +} diff --git a/frontend/src/features/options/PromptInput/PromptInput.tsx b/frontend/src/features/options/PromptInput/PromptInput.tsx new file mode 100644 index 0000000000..035d085013 --- /dev/null +++ b/frontend/src/features/options/PromptInput/PromptInput.tsx @@ -0,0 +1,79 @@ +import { FormControl, Textarea } from '@chakra-ui/react'; +import { ChangeEvent, KeyboardEvent, useRef } from 'react'; +import { RootState, useAppDispatch, useAppSelector } from '../../../app/store'; +import { generateImage } from '../../../app/socketio/actions'; + +import { OptionsState, setPrompt } from '../optionsSlice'; +import { createSelector } from '@reduxjs/toolkit'; +import _ from 'lodash'; +import { useHotkeys } from 'react-hotkeys-hook'; +import { activeTabNameSelector } from '../optionsSelectors'; +import { readinessSelector } from '../../../app/selectors/readinessSelector'; + +const promptInputSelector = createSelector( + [(state: RootState) => state.options, activeTabNameSelector], + (options: OptionsState, activeTabName) => { + return { + prompt: options.prompt, + activeTabName, + }; + }, + { + memoizeOptions: { + resultEqualityCheck: _.isEqual, + }, + } +); + +/** + * Prompt input text area. + */ +const PromptInput = () => { + const dispatch = useAppDispatch(); + const { prompt, activeTabName } = useAppSelector(promptInputSelector); + const { isReady } = useAppSelector(readinessSelector); + + const promptRef = useRef(null); + + const handleChangePrompt = (e: ChangeEvent) => { + dispatch(setPrompt(e.target.value)); + }; + + useHotkeys( + 'alt+a', + () => { + promptRef.current?.focus(); + }, + [] + ); + + const handleKeyDown = (e: KeyboardEvent) => { + if (e.key === 'Enter' && e.shiftKey === false && isReady) { + e.preventDefault(); + dispatch(generateImage(activeTabName)); + } + }; + + return ( +
+ + - -
+ + Stable Diffusion Dream Server + + + + + + + + + + + +
+

Stable Diffusion Dream Server

+
+ For news and support for this web service, visit our GitHub + site +
+
+ +
+ +
+
+ + + + + + + + + + + + + + + +
+ + + + + + + + + +
+ + + + + +
+
+ + + + +
+
+
+ + + + +
+ + + +
+
+ + + + + + + +
-
- - - - - - - - - - -
- - - - - - - - - - -
- - - - -
-
- - - -
- - - - -
-
+
+
- - - + + + + + + +
+
+ + + + +
- -
-
-
- - -
- -
- Postprocessing...1/3 -
-
-
- -
-
-

No results...

+
+ + +
+
+
+ + +
+ +
+ Postprocessing...1/3
-
- + + +
+
+ + + diff --git a/static/dream_web/index.js b/static/dream_web/index.js index ac68034920..5de690297d 100644 --- a/static/dream_web/index.js +++ b/static/dream_web/index.js @@ -1,3 +1,109 @@ +const socket = io(); + +var priorResultsLoadState = { + page: 0, + pages: 1, + per_page: 10, + total: 20, + offset: 0, // number of items generated since last load + loading: false, + initialized: false +}; + +function loadPriorResults() { + // Fix next page by offset + let offsetPages = priorResultsLoadState.offset / priorResultsLoadState.per_page; + priorResultsLoadState.page += offsetPages; + priorResultsLoadState.pages += offsetPages; + priorResultsLoadState.total += priorResultsLoadState.offset; + priorResultsLoadState.offset = 0; + + if (priorResultsLoadState.loading) { + return; + } + + if (priorResultsLoadState.page >= priorResultsLoadState.pages) { + return; // Nothing more to load + } + + // Load + priorResultsLoadState.loading = true + let url = new URL('/api/images', document.baseURI); + url.searchParams.append('page', priorResultsLoadState.initialized ? priorResultsLoadState.page + 1 : priorResultsLoadState.page); + url.searchParams.append('per_page', priorResultsLoadState.per_page); + fetch(url.href, { + method: 'GET', + headers: new Headers({'content-type': 'application/json'}) + }) + .then(response => response.json()) + .then(data => { + priorResultsLoadState.page = data.page; + priorResultsLoadState.pages = data.pages; + priorResultsLoadState.per_page = data.per_page; + priorResultsLoadState.total = data.total; + + data.items.forEach(function(dreamId, index) { + let src = 'api/images/' + dreamId; + fetch('/api/images/' + dreamId + '/metadata', { + method: 'GET', + headers: new Headers({'content-type': 'application/json'}) + }) + .then(response => response.json()) + .then(metadata => { + let seed = metadata.seed || 0; // TODO: Parse old metadata + appendOutput(src, seed, metadata, true); + }); + }); + + // Load until page is full + if (!priorResultsLoadState.initialized) { + if (document.body.scrollHeight <= window.innerHeight) { + loadPriorResults(); + } + } + }) + .finally(() => { + priorResultsLoadState.loading = false; + priorResultsLoadState.initialized = true; + }); +} + +function resetForm() { + var form = document.getElementById('generate-form'); + form.querySelector('fieldset').removeAttribute('disabled'); +} + +function initProgress(totalSteps, showProgressImages) { + // TODO: Progress could theoretically come from multiple jobs at the same time (in the future) + let progressSectionEle = document.querySelector('#progress-section'); + progressSectionEle.style.display = 'initial'; + let progressEle = document.querySelector('#progress-bar'); + progressEle.setAttribute('max', totalSteps); + + let progressImageEle = document.querySelector('#progress-image'); + progressImageEle.src = BLANK_IMAGE_URL; + progressImageEle.style.display = showProgressImages ? 'initial': 'none'; +} + +function setProgress(step, totalSteps, src) { + let progressEle = document.querySelector('#progress-bar'); + progressEle.setAttribute('value', step); + + if (src) { + let progressImageEle = document.querySelector('#progress-image'); + progressImageEle.src = src; + } +} + +function resetProgress(hide = true) { + if (hide) { + let progressSectionEle = document.querySelector('#progress-section'); + progressSectionEle.style.display = 'none'; + } + let progressEle = document.querySelector('#progress-bar'); + progressEle.setAttribute('value', 0); +} + function toBase64(file) { return new Promise((resolve, reject) => { const r = new FileReader(); @@ -7,17 +113,41 @@ function toBase64(file) { }); } -function appendOutput(src, seed, config) { - let outputNode = document.createElement("figure"); - - let variations = config.with_variations; - if (config.variation_amount > 0) { - variations = (variations ? variations + ',' : '') + seed + ':' + config.variation_amount; +function ondragdream(event) { + let dream = event.target.dataset.dream; + event.dataTransfer.setData("dream", dream); +} + +function seedClick(event) { + // Get element + var image = event.target.closest('figure').querySelector('img'); + var dream = JSON.parse(decodeURIComponent(image.dataset.dream)); + + let form = document.querySelector("#generate-form"); + for (const [k, v] of new FormData(form)) { + if (k == 'initimg') { continue; } + let formElem = form.querySelector(`*[name=${k}]`); + formElem.value = dream[k] !== undefined ? dream[k] : formElem.defaultValue; } - let baseseed = (config.with_variations || config.variation_amount > 0) ? config.seed : seed; - let altText = baseseed + ' | ' + (variations ? variations + ' | ' : '') + config.prompt; + + document.querySelector("#seed").value = dream.seed; + document.querySelector('#iterations').value = 1; // Reset to 1 iteration since we clicked a single image (not a full job) + + // NOTE: leaving this manual for the user for now - it was very confusing with this behavior + // document.querySelector("#with_variations").value = variations || ''; + // if (document.querySelector("#variation_amount").value <= 0) { + // document.querySelector("#variation_amount").value = 0.2; + // } + + saveFields(document.querySelector("#generate-form")); +} + +function appendOutput(src, seed, config, toEnd=false) { + let outputNode = document.createElement("figure"); + let altText = seed.toString() + " | " + config.prompt; // img needs width and height for lazy loading to work + // TODO: store the full config in a data attribute on the image? const figureContents = ` + height="256" + draggable="true" + ondragstart="ondragdream(event, this)" + data-dream="${encodeURIComponent(JSON.stringify(config))}" + data-dreamId="${encodeURIComponent(config.dreamId)}"> -
${seed}
+
${seed}
`; outputNode.innerHTML = figureContents; - let figcaption = outputNode.querySelector('figcaption'); - // Reload image config - figcaption.addEventListener('click', () => { - let form = document.querySelector("#generate-form"); - for (const [k, v] of new FormData(form)) { - if (k == 'initimg') { continue; } - form.querySelector(`*[name=${k}]`).value = config[k]; - } - - document.querySelector("#seed").value = baseseed; - document.querySelector("#with_variations").value = variations || ''; - if (document.querySelector("#variation_amount").value <= 0) { - document.querySelector("#variation_amount").value = 0.2; - } - - saveFields(document.querySelector("#generate-form")); - }); - - document.querySelector("#results").prepend(outputNode); + if (toEnd) { + document.querySelector("#results").append(outputNode); + } else { + document.querySelector("#results").prepend(outputNode); + } + document.querySelector("#no-results-message")?.remove(); } function saveFields(form) { @@ -79,93 +200,109 @@ function clearFields(form) { const BLANK_IMAGE_URL = 'data:image/svg+xml,'; async function generateSubmit(form) { - const prompt = document.querySelector("#prompt").value; - // Convert file data to base64 + // TODO: Should probably uplaod files with formdata or something, and store them in the backend? let formData = Object.fromEntries(new FormData(form)); + if (!formData.enable_generate && !formData.enable_init_image) { + gen_label = document.querySelector("label[for=enable_generate]").innerHTML; + initimg_label = document.querySelector("label[for=enable_init_image]").innerHTML; + alert(`Error: one of "${gen_label}" or "${initimg_label}" must be set`); + } + + formData.initimg_name = formData.initimg.name formData.initimg = formData.initimg.name !== '' ? await toBase64(formData.initimg) : null; - let strength = formData.strength; - let totalSteps = formData.initimg ? Math.floor(strength * formData.steps) : formData.steps; - - let progressSectionEle = document.querySelector('#progress-section'); - progressSectionEle.style.display = 'initial'; - let progressEle = document.querySelector('#progress-bar'); - progressEle.setAttribute('max', totalSteps); - let progressImageEle = document.querySelector('#progress-image'); - progressImageEle.src = BLANK_IMAGE_URL; - - progressImageEle.style.display = {}.hasOwnProperty.call(formData, 'progress_images') ? 'initial': 'none'; - - // Post as JSON, using Fetch streaming to get results - fetch(form.action, { - method: form.method, - body: JSON.stringify(formData), - }).then(async (response) => { - const reader = response.body.getReader(); - - let noOutputs = true; - while (true) { - let {value, done} = await reader.read(); - value = new TextDecoder().decode(value); - if (done) { - progressSectionEle.style.display = 'none'; - break; - } - - for (let event of value.split('\n').filter(e => e !== '')) { - const data = JSON.parse(event); - - if (data.event === 'result') { - noOutputs = false; - appendOutput(data.url, data.seed, data.config); - progressEle.setAttribute('value', 0); - progressEle.setAttribute('max', totalSteps); - } else if (data.event === 'upscaling-started') { - document.getElementById("processing_cnt").textContent=data.processed_file_cnt; - document.getElementById("scaling-inprocess-message").style.display = "block"; - } else if (data.event === 'upscaling-done') { - document.getElementById("scaling-inprocess-message").style.display = "none"; - } else if (data.event === 'step') { - progressEle.setAttribute('value', data.step); - if (data.url) { - progressImageEle.src = data.url; - } - } else if (data.event === 'canceled') { - // avoid alerting as if this were an error case - noOutputs = false; - } - } - } - - // Re-enable form, remove no-results-message - form.querySelector('fieldset').removeAttribute('disabled'); - document.querySelector("#prompt").value = prompt; - document.querySelector('progress').setAttribute('value', '0'); - - if (noOutputs) { - alert("Error occurred while generating."); - } + // Evaluate all checkboxes + let checkboxes = form.querySelectorAll('input[type=checkbox]'); + checkboxes.forEach(function (checkbox) { + if (checkbox.checked) { + formData[checkbox.name] = 'true'; + } + }); + + let strength = formData.strength; + let totalSteps = formData.initimg ? Math.floor(strength * formData.steps) : formData.steps; + let showProgressImages = formData.progress_images; + + // Set enabling flags + + + // Initialize the progress bar + initProgress(totalSteps, showProgressImages); + + // POST, use response to listen for events + fetch(form.action, { + method: form.method, + headers: new Headers({'content-type': 'application/json'}), + body: JSON.stringify(formData), + }) + .then(response => response.json()) + .then(data => { + var jobId = data.jobId; + socket.emit('join_room', { 'room': jobId }); }); - // Disable form while generating form.querySelector('fieldset').setAttribute('disabled',''); - document.querySelector("#prompt").value = `Generating: "${prompt}"`; } -async function fetchRunLog() { - try { - let response = await fetch('/run_log.json') - const data = await response.json(); - for(let item of data.run_log) { - appendOutput(item.url, item.seed, item); - } - } catch (e) { - console.error(e); - } +function fieldSetEnableChecked(event) { + cb = event.target; + fields = cb.closest('fieldset'); + fields.disabled = !cb.checked; } +// Socket listeners +socket.on('job_started', (data) => {}) + +socket.on('dream_result', (data) => { + var jobId = data.jobId; + var dreamId = data.dreamId; + var dreamRequest = data.dreamRequest; + var src = 'api/images/' + dreamId; + + priorResultsLoadState.offset += 1; + appendOutput(src, dreamRequest.seed, dreamRequest); + + resetProgress(false); +}) + +socket.on('dream_progress', (data) => { + // TODO: it'd be nice if we could get a seed reported here, but the generator would need to be updated + var step = data.step; + var totalSteps = data.totalSteps; + var jobId = data.jobId; + var dreamId = data.dreamId; + + var progressType = data.progressType + if (progressType === 'GENERATION') { + var src = data.hasProgressImage ? + 'api/intermediates/' + dreamId + '/' + step + : null; + setProgress(step, totalSteps, src); + } else if (progressType === 'UPSCALING_STARTED') { + // step and totalSteps are used for upscale count on this message + document.getElementById("processing_cnt").textContent = step; + document.getElementById("processing_total").textContent = totalSteps; + document.getElementById("scaling-inprocess-message").style.display = "block"; + } else if (progressType == 'UPSCALING_DONE') { + document.getElementById("scaling-inprocess-message").style.display = "none"; + } +}) + +socket.on('job_canceled', (data) => { + resetForm(); + resetProgress(); +}) + +socket.on('job_done', (data) => { + jobId = data.jobId + socket.emit('leave_room', { 'room': jobId }); + + resetForm(); + resetProgress(); +}) + window.onload = async () => { document.querySelector("#prompt").addEventListener("keydown", (e) => { if (e.key === "Enter" && !e.shiftKey) { @@ -183,7 +320,7 @@ window.onload = async () => { saveFields(e.target.form); }); document.querySelector("#reset-seed").addEventListener('click', (e) => { - document.querySelector("#seed").value = -1; + document.querySelector("#seed").value = 0; saveFields(e.target.form); }); document.querySelector("#reset-all").addEventListener('click', (e) => { @@ -195,13 +332,13 @@ window.onload = async () => { loadFields(document.querySelector("#generate-form")); document.querySelector('#cancel-button').addEventListener('click', () => { - fetch('/cancel').catch(e => { + fetch('/api/cancel').catch(e => { console.error(e); }); }); document.documentElement.addEventListener('keydown', (e) => { if (e.key === "Escape") - fetch('/cancel').catch(err => { + fetch('/api/cancel').catch(err => { console.error(err); }); }); @@ -209,5 +346,51 @@ window.onload = async () => { if (!config.gfpgan_model_exists) { document.querySelector("#gfpgan").style.display = 'none'; } - await fetchRunLog() + + window.addEventListener("scroll", () => { + if ((window.innerHeight + window.pageYOffset) >= document.body.offsetHeight) { + loadPriorResults(); + } + }); + + + + // Enable/disable forms by checkboxes + document.querySelectorAll("legend > input[type=checkbox]").forEach(function(cb) { + cb.addEventListener('change', fieldSetEnableChecked); + fieldSetEnableChecked({ target: cb}) + }); + + + // Load some of the previous results + loadPriorResults(); + + // Image drop/upload WIP + /* + let drop = document.getElementById('dropper'); + function ondrop(event) { + let dreamData = event.dataTransfer.getData('dream'); + if (dreamData) { + var dream = JSON.parse(decodeURIComponent(dreamData)); + alert(dream.dreamId); + } + }; + + function ondragenter(event) { + event.preventDefault(); + }; + + function ondragover(event) { + event.preventDefault(); + }; + + function ondragleave(event) { + + } + + drop.addEventListener('drop', ondrop); + drop.addEventListener('dragenter', ondragenter); + drop.addEventListener('dragover', ondragover); + drop.addEventListener('dragleave', ondragleave); + */ }; diff --git a/static/legacy_web/favicon.ico b/static/legacy_web/favicon.ico new file mode 100644 index 0000000000..51eb844a6a Binary files /dev/null and b/static/legacy_web/favicon.ico differ diff --git a/static/legacy_web/index.css b/static/legacy_web/index.css new file mode 100644 index 0000000000..51f0f267c3 --- /dev/null +++ b/static/legacy_web/index.css @@ -0,0 +1,152 @@ +* { + font-family: 'Arial'; + font-size: 100%; +} +body { + font-size: 1em; +} +textarea { + font-size: 0.95em; +} +header, form, #progress-section { + margin-left: auto; + margin-right: auto; + max-width: 1024px; + text-align: center; +} +fieldset { + border: none; + line-height: 2.2em; +} +select, input { + margin-right: 10px; + padding: 2px; +} +input[type=submit] { + background-color: #666; + color: white; +} +input[type=checkbox] { + margin-right: 0px; + width: 20px; + height: 20px; + vertical-align: middle; +} +input#seed { + margin-right: 0px; +} +div { + padding: 10px 10px 10px 10px; +} +header { + margin-bottom: 16px; +} +header h1 { + margin-bottom: 0; + font-size: 2em; +} +#search-box { + display: flex; +} +#scaling-inprocess-message { + font-weight: bold; + font-style: italic; + display: none; +} +#prompt { + flex-grow: 1; + padding: 5px 10px 5px 10px; + border: 1px solid #999; + outline: none; +} +#submit { + padding: 5px 10px 5px 10px; + border: 1px solid #999; +} +#reset-all, #remove-image { + margin-top: 12px; + font-size: 0.8em; + background-color: pink; + border: 1px solid #999; + border-radius: 4px; +} +#results { + text-align: center; + margin: auto; + padding-top: 10px; +} +#results figure { + display: inline-block; + margin: 10px; +} +#results figcaption { + font-size: 0.8em; + padding: 3px; + color: #888; + cursor: pointer; +} +#results img { + border-radius: 5px; + object-fit: cover; +} +#fieldset-config { + line-height:2em; + background-color: #F0F0F0; +} +input[type="number"] { + width: 60px; +} +#seed { + width: 150px; +} +button#reset-seed { + font-size: 1.7em; + background: #efefef; + border: 1px solid #999; + border-radius: 4px; + line-height: 0.8; + margin: 0 10px 0 0; + padding: 0 5px 3px; + vertical-align: middle; +} +label { + white-space: nowrap; +} +#progress-section { + display: none; +} +#progress-image { + width: 30vh; + height: 30vh; +} +#cancel-button { + cursor: pointer; + color: red; +} +#basic-parameters { + background-color: #EEEEEE; +} +#txt2img { + background-color: #DCDCDC; +} +#variations { + background-color: #EEEEEE; +} +#img2img { + background-color: #DCDCDC; +} +#gfpgan { + background-color: #EEEEEE; +} +#progress-section { + background-color: #F5F5F5; +} +.section-header { + text-align: left; + font-weight: bold; + padding: 0 0 0 0; +} +#no-results-message:not(:only-child) { + display: none; +} + diff --git a/static/legacy_web/index.html b/static/legacy_web/index.html new file mode 100644 index 0000000000..1f5c3dc9f8 --- /dev/null +++ b/static/legacy_web/index.html @@ -0,0 +1,135 @@ + + + Stable Diffusion Dream Server + + + + + + + + +
+

Stable Diffusion Dream Server

+
+ For news and support for this web service, visit our GitHub site +
+
+ +
+
+
+ +
+
+
Basic options
+ + + + + + + + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + + + +
+
+
Image-to-image options
+ + + +
+ + + + +
+
+
Post-processing options
+ + + + + + +
+
+
+
+
+ + +
+ +
+ Postprocessing...1/3 +
+ +
+ +
+
+

No results...

+
+
+
+ + diff --git a/static/legacy_web/index.js b/static/legacy_web/index.js new file mode 100644 index 0000000000..ac68034920 --- /dev/null +++ b/static/legacy_web/index.js @@ -0,0 +1,213 @@ +function toBase64(file) { + return new Promise((resolve, reject) => { + const r = new FileReader(); + r.readAsDataURL(file); + r.onload = () => resolve(r.result); + r.onerror = (error) => reject(error); + }); +} + +function appendOutput(src, seed, config) { + let outputNode = document.createElement("figure"); + + let variations = config.with_variations; + if (config.variation_amount > 0) { + variations = (variations ? variations + ',' : '') + seed + ':' + config.variation_amount; + } + let baseseed = (config.with_variations || config.variation_amount > 0) ? config.seed : seed; + let altText = baseseed + ' | ' + (variations ? variations + ' | ' : '') + config.prompt; + + // img needs width and height for lazy loading to work + const figureContents = ` + + ${altText} + +
${seed}
+ `; + + outputNode.innerHTML = figureContents; + let figcaption = outputNode.querySelector('figcaption'); + + // Reload image config + figcaption.addEventListener('click', () => { + let form = document.querySelector("#generate-form"); + for (const [k, v] of new FormData(form)) { + if (k == 'initimg') { continue; } + form.querySelector(`*[name=${k}]`).value = config[k]; + } + + document.querySelector("#seed").value = baseseed; + document.querySelector("#with_variations").value = variations || ''; + if (document.querySelector("#variation_amount").value <= 0) { + document.querySelector("#variation_amount").value = 0.2; + } + + saveFields(document.querySelector("#generate-form")); + }); + + document.querySelector("#results").prepend(outputNode); +} + +function saveFields(form) { + for (const [k, v] of new FormData(form)) { + if (typeof v !== 'object') { // Don't save 'file' type + localStorage.setItem(k, v); + } + } +} + +function loadFields(form) { + for (const [k, v] of new FormData(form)) { + const item = localStorage.getItem(k); + if (item != null) { + form.querySelector(`*[name=${k}]`).value = item; + } + } +} + +function clearFields(form) { + localStorage.clear(); + let prompt = form.prompt.value; + form.reset(); + form.prompt.value = prompt; +} + +const BLANK_IMAGE_URL = 'data:image/svg+xml,'; +async function generateSubmit(form) { + const prompt = document.querySelector("#prompt").value; + + // Convert file data to base64 + let formData = Object.fromEntries(new FormData(form)); + formData.initimg_name = formData.initimg.name + formData.initimg = formData.initimg.name !== '' ? await toBase64(formData.initimg) : null; + + let strength = formData.strength; + let totalSteps = formData.initimg ? Math.floor(strength * formData.steps) : formData.steps; + + let progressSectionEle = document.querySelector('#progress-section'); + progressSectionEle.style.display = 'initial'; + let progressEle = document.querySelector('#progress-bar'); + progressEle.setAttribute('max', totalSteps); + let progressImageEle = document.querySelector('#progress-image'); + progressImageEle.src = BLANK_IMAGE_URL; + + progressImageEle.style.display = {}.hasOwnProperty.call(formData, 'progress_images') ? 'initial': 'none'; + + // Post as JSON, using Fetch streaming to get results + fetch(form.action, { + method: form.method, + body: JSON.stringify(formData), + }).then(async (response) => { + const reader = response.body.getReader(); + + let noOutputs = true; + while (true) { + let {value, done} = await reader.read(); + value = new TextDecoder().decode(value); + if (done) { + progressSectionEle.style.display = 'none'; + break; + } + + for (let event of value.split('\n').filter(e => e !== '')) { + const data = JSON.parse(event); + + if (data.event === 'result') { + noOutputs = false; + appendOutput(data.url, data.seed, data.config); + progressEle.setAttribute('value', 0); + progressEle.setAttribute('max', totalSteps); + } else if (data.event === 'upscaling-started') { + document.getElementById("processing_cnt").textContent=data.processed_file_cnt; + document.getElementById("scaling-inprocess-message").style.display = "block"; + } else if (data.event === 'upscaling-done') { + document.getElementById("scaling-inprocess-message").style.display = "none"; + } else if (data.event === 'step') { + progressEle.setAttribute('value', data.step); + if (data.url) { + progressImageEle.src = data.url; + } + } else if (data.event === 'canceled') { + // avoid alerting as if this were an error case + noOutputs = false; + } + } + } + + // Re-enable form, remove no-results-message + form.querySelector('fieldset').removeAttribute('disabled'); + document.querySelector("#prompt").value = prompt; + document.querySelector('progress').setAttribute('value', '0'); + + if (noOutputs) { + alert("Error occurred while generating."); + } + }); + + // Disable form while generating + form.querySelector('fieldset').setAttribute('disabled',''); + document.querySelector("#prompt").value = `Generating: "${prompt}"`; +} + +async function fetchRunLog() { + try { + let response = await fetch('/run_log.json') + const data = await response.json(); + for(let item of data.run_log) { + appendOutput(item.url, item.seed, item); + } + } catch (e) { + console.error(e); + } +} + +window.onload = async () => { + document.querySelector("#prompt").addEventListener("keydown", (e) => { + if (e.key === "Enter" && !e.shiftKey) { + const form = e.target.form; + generateSubmit(form); + } + }); + document.querySelector("#generate-form").addEventListener('submit', (e) => { + e.preventDefault(); + const form = e.target; + + generateSubmit(form); + }); + document.querySelector("#generate-form").addEventListener('change', (e) => { + saveFields(e.target.form); + }); + document.querySelector("#reset-seed").addEventListener('click', (e) => { + document.querySelector("#seed").value = -1; + saveFields(e.target.form); + }); + document.querySelector("#reset-all").addEventListener('click', (e) => { + clearFields(e.target.form); + }); + document.querySelector("#remove-image").addEventListener('click', (e) => { + initimg.value=null; + }); + loadFields(document.querySelector("#generate-form")); + + document.querySelector('#cancel-button').addEventListener('click', () => { + fetch('/cancel').catch(e => { + console.error(e); + }); + }); + document.documentElement.addEventListener('keydown', (e) => { + if (e.key === "Escape") + fetch('/cancel').catch(err => { + console.error(err); + }); + }); + + if (!config.gfpgan_model_exists) { + document.querySelector("#gfpgan").style.display = 'none'; + } + await fetchRunLog() +}; diff --git a/tests/legacy_tests.sh b/tests/legacy_tests.sh new file mode 100755 index 0000000000..a171a47c2b --- /dev/null +++ b/tests/legacy_tests.sh @@ -0,0 +1,46 @@ +#! /usr/bin/env bash + +# This file contains bunch of compatibility tests that ensures +# that the API interface of `scripts/legacy-api.py` remains stable + +set -e + +OUTDIR=$(mktemp -d) + +echo "Using directory $OUTDIR" + +# Start API +python -u scripts/legacy_api.py --web --host=localhost --port=3333 --outdir=$OUTDIR &> $OUTDIR/sd.log & +APP_PID=$! + +echo "Wait for server to startup" + +tail -f -n0 $OUTDIR/sd.log | grep -qe "Point your browser at" + +echo "Started, continuing" + +if [ $? == 1 ]; then + echo "Search terminated without finding the pattern" +fi + +# Generate image +RESULT=$(curl -v -X POST -d '{"index":0,"variation_amount":0,"with_variations":"","steps":25,"width":512,"seed":"1337","prompt":"A cat wearing a hat","strength":0.5,"initimg":null,"cfg_scale":2,"iterations":1,"upscale_level":0,"upscale_strength":0,"sampler_name":"k_euler","height":512}' localhost:3333 | grep result) + +# Test 01 - Image contents +FILENAME=$(echo $RESULT | jq -r .url) + +ACTUAL_CHECKSUM=$(sha256sum $FILENAME) +EXPECTED_CHECKSUM="a77799226a4dfc62a1674498e575c775da042959a4b90b13e26f666c302f079f" + +if [ "$ACTUAL_CHECKSUM" != "$EXPECTED_CHECKSUM" ]; then + echo "Expected hash $EXPECTED_CHECKSUM but got hash $ACTUAL_CHECKSUM" + kill $APP_PID + # rm -r $OUTDIR + exit 33 +fi + +# Assert output + +# Cleanup +kill $APP_PID +# rm -r $OUTDIR diff --git a/tests/pr_prompt.txt b/tests/pr_prompt.txt new file mode 100644 index 0000000000..c1a8e00cbe --- /dev/null +++ b/tests/pr_prompt.txt @@ -0,0 +1 @@ +banana sushi -Ak_lms -S42 -s10 diff --git a/tests/test_prompt_parser.py b/tests/test_prompt_parser.py new file mode 100644 index 0000000000..0c9bbf91f9 --- /dev/null +++ b/tests/test_prompt_parser.py @@ -0,0 +1,499 @@ +import unittest + +import pyparsing + +from ldm.invoke.prompt_parser import PromptParser, Blend, Conjunction, FlattenedPrompt, CrossAttentionControlSubstitute, \ + Fragment + + +def parse_prompt(prompt_string): + pp = PromptParser() + #print(f"parsing '{prompt_string}'") + parse_result = pp.parse_conjunction(prompt_string) + #print(f"-> parsed '{prompt_string}' to {parse_result}") + return parse_result + +def make_basic_conjunction(strings: list[str]): + fragments = [Fragment(x) for x in strings] + return Conjunction([FlattenedPrompt(fragments)]) + +def make_weighted_conjunction(weighted_strings: list[tuple[str,float]]): + fragments = [Fragment(x, w) for x,w in weighted_strings] + return Conjunction([FlattenedPrompt(fragments)]) + + +class PromptParserTestCase(unittest.TestCase): + + def test_empty(self): + self.assertEqual(make_weighted_conjunction([('', 1)]), parse_prompt('')) + + def test_basic(self): + self.assertEqual(make_weighted_conjunction([("fire flames", 1)]), parse_prompt("fire flames")) + self.assertEqual(make_weighted_conjunction([('fire flames', 1)]), parse_prompt("fire (flames)")) + self.assertEqual(make_weighted_conjunction([("fire, flames", 1)]), parse_prompt("fire, flames")) + self.assertEqual(make_weighted_conjunction([("fire, flames , fire", 1)]), parse_prompt("fire, flames , fire")) + self.assertEqual(make_weighted_conjunction([("cat hot-dog eating", 1)]), parse_prompt("cat hot-dog eating")) + self.assertEqual(make_basic_conjunction(['Dalí']), parse_prompt("Dalí")) + + def test_attention(self): + self.assertEqual(make_weighted_conjunction([('flames', 0.5)]), parse_prompt("(flames)0.5")) + self.assertEqual(make_weighted_conjunction([('flames', 0.5)]), parse_prompt("(flames).attend(0.5)")) + self.assertEqual(make_weighted_conjunction([('flames', 0.5)]), parse_prompt("flames.attend(0.5)")) + self.assertEqual(make_weighted_conjunction([('flames', 0.5)]), parse_prompt("\"flames\".attend(0.5)")) + self.assertEqual(make_weighted_conjunction([('fire flames', 0.5)]), parse_prompt("(fire flames)0.5")) + self.assertEqual(make_weighted_conjunction([('fire flames', 0.5)]), parse_prompt("(fire flames).attend(0.5)")) + + self.assertEqual(make_weighted_conjunction([('flames', 1.1)]), parse_prompt("(flames)+")) + self.assertEqual(make_weighted_conjunction([('flames', 1.1)]), parse_prompt("flames+")) + self.assertEqual(make_weighted_conjunction([('flames', 1.1)]), parse_prompt("\"flames\"+")) + self.assertEqual(make_weighted_conjunction([('flames', 1.1)]), parse_prompt("flames.attend(+)")) + self.assertEqual(make_weighted_conjunction([('flames', 1.1)]), parse_prompt("(flames).attend(+)")) + self.assertEqual(make_weighted_conjunction([('flames', 1.1)]), parse_prompt("\"flames\".attend(+)")) + self.assertEqual(make_weighted_conjunction([('flames', 0.9)]), parse_prompt("(flames)-")) + self.assertEqual(make_weighted_conjunction([('flames', 0.9)]), parse_prompt("flames-")) + self.assertEqual(make_weighted_conjunction([('flames', 0.9)]), parse_prompt("\"flames\"-")) + self.assertEqual(make_weighted_conjunction([('fire', 1), ('flames', 0.5)]), parse_prompt("fire (flames)0.5")) + self.assertEqual(make_weighted_conjunction([('fire', 1), ('flames', 0.5)]), parse_prompt("fire flames.attend(0.5)")) + self.assertEqual(make_weighted_conjunction([('fire', 1), ('flames', 0.5)]), parse_prompt("fire (flames).attend(0.5)")) + self.assertEqual(make_weighted_conjunction([('fire', 1), ('flames', 0.5)]), parse_prompt("fire \"flames\".attend(0.5)")) + self.assertEqual(make_weighted_conjunction([('flames', pow(1.1, 2))]), parse_prompt("(flames)++")) + self.assertEqual(make_weighted_conjunction([('flames', pow(0.9, 2))]), parse_prompt("(flames)--")) + self.assertEqual(make_weighted_conjunction([('flowers', pow(0.9, 3)), ('flames', pow(1.1, 3))]), parse_prompt("(flowers)--- flames+++")) + self.assertEqual(make_weighted_conjunction([('pretty flowers', 1.1)]), + parse_prompt("(pretty flowers)+")) + self.assertEqual(make_weighted_conjunction([('pretty flowers', 1.1), (', the flames are too hot', 1)]), + parse_prompt("(pretty flowers)+, the flames are too hot")) + + def test_no_parens_attention_runon(self): + self.assertEqual(make_weighted_conjunction([('fire', 1.0), ('flames', pow(1.1, 2))]), parse_prompt("fire flames++")) + self.assertEqual(make_weighted_conjunction([('fire', 1.0), ('flames', pow(0.9, 2))]), parse_prompt("fire flames--")) + self.assertEqual(make_weighted_conjunction([('flowers', 1.0), ('fire', pow(1.1, 2)), ('flames', 1.0)]), parse_prompt("flowers fire++ flames")) + self.assertEqual(make_weighted_conjunction([('flowers', 1.0), ('fire', pow(0.9, 2)), ('flames', 1.0)]), parse_prompt("flowers fire-- flames")) + + + def test_explicit_conjunction(self): + self.assertEqual(Conjunction([FlattenedPrompt([('fire', 1.0)]), FlattenedPrompt([('flames', 1.0)])]), parse_prompt('("fire", "flames").and(1,1)')) + self.assertEqual(Conjunction([FlattenedPrompt([('fire', 1.0)]), FlattenedPrompt([('flames', 1.0)])]), parse_prompt('("fire", "flames").and()')) + self.assertEqual( + Conjunction([FlattenedPrompt([('fire flames', 1.0)]), FlattenedPrompt([('mountain man', 1.0)])]), parse_prompt('("fire flames", "mountain man").and()')) + self.assertEqual(Conjunction([FlattenedPrompt([('fire', 2.0)]), FlattenedPrompt([('flames', 0.9)])]), parse_prompt('("(fire)2.0", "flames-").and()')) + self.assertEqual(Conjunction([FlattenedPrompt([('fire', 1.0)]), FlattenedPrompt([('flames', 1.0)]), + FlattenedPrompt([('mountain man', 1.0)])]), parse_prompt('("fire", "flames", "mountain man").and()')) + + def test_conjunction_weights(self): + self.assertEqual(Conjunction([FlattenedPrompt([('fire', 1.0)]), FlattenedPrompt([('flames', 1.0)])], weights=[2.0,1.0]), parse_prompt('("fire", "flames").and(2,1)')) + self.assertEqual(Conjunction([FlattenedPrompt([('fire', 1.0)]), FlattenedPrompt([('flames', 1.0)])], weights=[1.0,2.0]), parse_prompt('("fire", "flames").and(1,2)')) + + with self.assertRaises(PromptParser.ParsingException): + parse_prompt('("fire", "flames").and(2)') + parse_prompt('("fire", "flames").and(2,1,2)') + + def test_complex_conjunction(self): + + #print(parse_prompt("a person with a hat (riding a bicycle.swap(skateboard))++")) + + self.assertEqual(Conjunction([FlattenedPrompt([("mountain man", 1.0)]), FlattenedPrompt([("a person with a hat", 1.0), ("riding a bicycle", pow(1.1,2))])], weights=[0.5, 0.5]), + parse_prompt("(\"mountain man\", \"a person with a hat (riding a bicycle)++\").and(0.5, 0.5)")) + self.assertEqual(Conjunction([FlattenedPrompt([("mountain man", 1.0)]), + FlattenedPrompt([("a person with a hat", 1.0), + ("riding a", 1.1*1.1), + CrossAttentionControlSubstitute( + [Fragment("bicycle", pow(1.1,2))], + [Fragment("skateboard", pow(1.1,2))]) + ]) + ], weights=[0.5, 0.5]), + parse_prompt("(\"mountain man\", \"a person with a hat (riding a bicycle.swap(skateboard))++\").and(0.5, 0.5)")) + + def test_badly_formed(self): + def make_untouched_prompt(prompt): + return Conjunction([FlattenedPrompt([(prompt, 1.0)])]) + + def assert_if_prompt_string_not_untouched(prompt): + self.assertEqual(make_untouched_prompt(prompt), parse_prompt(prompt)) + + assert_if_prompt_string_not_untouched('a test prompt') + assert_if_prompt_string_not_untouched('a badly formed +test prompt') + assert_if_prompt_string_not_untouched('a badly (formed test prompt') + + #with self.assertRaises(pyparsing.ParseException): + assert_if_prompt_string_not_untouched('a badly (formed +test prompt') + self.assertEqual(Conjunction([FlattenedPrompt([Fragment('a badly formed +test prompt',1)])]) , parse_prompt('a badly (formed +test )prompt')) + self.assertEqual(Conjunction([FlattenedPrompt([Fragment('(((a badly formed +test prompt',1)])]) , parse_prompt('(((a badly (formed +test )prompt')) + + self.assertEqual(Conjunction([FlattenedPrompt([Fragment('(a ba dly f ormed +test prompt',1)])]) , parse_prompt('(a (ba)dly (f)ormed +test prompt')) + self.assertEqual(Conjunction([FlattenedPrompt([Fragment('(a ba dly f ormed +test +prompt',1)])]) , parse_prompt('(a (ba)dly (f)ormed +test +prompt')) + self.assertEqual(Conjunction([Blend([FlattenedPrompt([Fragment('((a badly (formed +test', 1)])], [1.0])]), + parse_prompt('("((a badly (formed +test ").blend(1.0)')) + + self.assertEqual(Conjunction([FlattenedPrompt([Fragment('hamburger bun', 1)])]), + parse_prompt("hamburger ((bun))")) + self.assertEqual(Conjunction([FlattenedPrompt([Fragment('hamburger bun', 1)])]), + parse_prompt("hamburger (bun)")) + self.assertEqual(Conjunction([FlattenedPrompt([Fragment('hamburger kaiser roll', 1)])]), + parse_prompt("hamburger (kaiser roll)")) + self.assertEqual(Conjunction([FlattenedPrompt([Fragment('hamburger kaiser roll', 1)])]), + parse_prompt("hamburger ((kaiser roll))")) + + + def test_blend(self): + self.assertEqual(Conjunction( + [Blend([FlattenedPrompt([('mountain', 1.0)]), FlattenedPrompt([('man', 1.0)])], [1.0, 1.0])]), + parse_prompt("(\"mountain\", \"man\").blend()") + ) + self.assertEqual(Conjunction( + [Blend([FlattenedPrompt([('mountain', 1.0)]), FlattenedPrompt([('man', 1.0)])], [1.0, 1.0])]), + parse_prompt("(mountain, man).blend()") + ) + self.assertEqual(Conjunction( + [Blend([FlattenedPrompt([('mountain', 1.0)]), FlattenedPrompt([('man', 1.0)])], [1.0, 1.0])]), + parse_prompt("((mountain), (man)).blend()") + ) + self.assertEqual(Conjunction( + [Blend([FlattenedPrompt([('mountain', 1.0)]), FlattenedPrompt([('tall man', 1.0)])], [1.0, 1.0])]), + parse_prompt("((mountain), (tall man)).blend()") + ) + + with self.assertRaises(PromptParser.ParsingException): + print(parse_prompt("((mountain), \"cat.swap(dog)\").blend()")) + + self.assertEqual(Conjunction( + [Blend([FlattenedPrompt([('fire', 1.0)]), FlattenedPrompt([('fire flames', 1.0)])], [0.7, 0.3])]), + parse_prompt("(\"fire\", \"fire flames\").blend(0.7, 0.3)") + ) + self.assertEqual(Conjunction([Blend( + [FlattenedPrompt([('fire', 1.0)]), FlattenedPrompt([('fire flames', 1.0)]), FlattenedPrompt([('hi', 1.0)])], + [0.7, 0.3, 1.0])]), + parse_prompt("(\"fire\", \"fire flames\", \"hi\").blend(0.7, 0.3, 1.0)") + ) + self.assertEqual(Conjunction([Blend([FlattenedPrompt([('fire', 1.0)]), + FlattenedPrompt([('fire flames', 1.0), ('hot', pow(1.1, 2))]), + FlattenedPrompt([('hi', 1.0)])], + weights=[0.7, 0.3, 1.0])]), + parse_prompt("(\"fire\", \"fire flames (hot)++\", \"hi\").blend(0.7, 0.3, 1.0)") + ) + # blend a single entry is not a failure + self.assertEqual(Conjunction([Blend([FlattenedPrompt([('fire', 1.0)])], [0.7])]), + parse_prompt("(\"fire\").blend(0.7)") + ) + # blend with empty + self.assertEqual( + Conjunction([Blend([FlattenedPrompt([('fire', 1.0)]), FlattenedPrompt([('', 1.0)])], [0.7, 1.0])]), + parse_prompt("(\"fire\", \"\").blend(0.7, 1)") + ) + self.assertEqual( + Conjunction([Blend([FlattenedPrompt([('fire', 1.0)]), FlattenedPrompt([('', 1.0)])], [0.7, 1.0])]), + parse_prompt("(\"fire\", \" \").blend(0.7, 1)") + ) + self.assertEqual( + Conjunction([Blend([FlattenedPrompt([('fire', 1.0)]), FlattenedPrompt([('', 1.0)])], [0.7, 1.0])]), + parse_prompt("(\"fire\", \" \").blend(0.7, 1)") + ) + self.assertEqual( + Conjunction([Blend([FlattenedPrompt([('fire', 1.0)]), FlattenedPrompt([(',', 1.0)])], [0.7, 1.0])]), + parse_prompt("(\"fire\", \" , \").blend(0.7, 1)") + ) + + self.assertEqual( + Conjunction([Blend([FlattenedPrompt([('mountain , man , hairy', 1)]), + FlattenedPrompt([('face , teeth ,', 1), ('eyes', 0.9*0.9)])], weights=[1.0,-1.0], normalize_weights=True)]), + parse_prompt('("mountain, man, hairy", "face, teeth, eyes--").blend(1,-1)') + ) + self.assertEqual( + Conjunction([Blend([FlattenedPrompt([('mountain , man , hairy', 1)]), + FlattenedPrompt([('face , teeth ,', 1), ('eyes', 0.9 * 0.9)])], weights=[1.0, -1.0], normalize_weights=False)]), + parse_prompt('("mountain, man, hairy", "face, teeth, eyes--").blend(1,-1,no_normalize)') + ) + + with self.assertRaises(PromptParser.ParsingException): + parse_prompt("(\"fire\", \"fire flames\").blend(0.7, 0.3, 0.1)") + with self.assertRaises(PromptParser.ParsingException): + parse_prompt("(\"fire\", \"fire flames\").blend(0.7)") + + + def test_nested(self): + self.assertEqual(make_weighted_conjunction([('fire', 1.0), ('flames', 2.0), ('trees', 3.0)]), + parse_prompt('fire (flames (trees)1.5)2.0')) + self.assertEqual(Conjunction([Blend(prompts=[FlattenedPrompt([('fire', 1.0), ('flames', 1.2100000000000002)]), + FlattenedPrompt([('mountain', 1.0), ('man', 2.0)])], + weights=[1.0, 1.0])]), + parse_prompt('("fire (flames)++", "mountain (man)2").blend(1,1)')) + + def test_cross_attention_control(self): + + self.assertEqual(Conjunction([FlattenedPrompt([CrossAttentionControlSubstitute([Fragment('sun')], [Fragment('moon')])])]), + parse_prompt("sun.swap(moon)")) + + self.assertEqual(Conjunction([ + FlattenedPrompt([Fragment('a', 1), + CrossAttentionControlSubstitute([Fragment('cat', 1)], [Fragment('dog', 1)]), + Fragment('eating a hotdog', 1)])]), parse_prompt("a \"cat\".swap(dog) eating a hotdog")) + + self.assertEqual(Conjunction([ + FlattenedPrompt([Fragment('a', 1), + CrossAttentionControlSubstitute([Fragment('cat', 1)], [Fragment('dog', 1)]), + Fragment('eating a hotdog', 1)])]), parse_prompt("a cat.swap(dog) eating a hotdog")) + + + fire_flames_to_trees = Conjunction([FlattenedPrompt([('fire', 1.0), \ + CrossAttentionControlSubstitute([Fragment('flames', 1)], [Fragment('trees', 1)])])]) + self.assertEqual(fire_flames_to_trees, parse_prompt('fire "flames".swap(trees)')) + self.assertEqual(fire_flames_to_trees, parse_prompt('fire (flames).swap(trees)')) + self.assertEqual(fire_flames_to_trees, parse_prompt('fire ("flames").swap(trees)')) + self.assertEqual(fire_flames_to_trees, parse_prompt('fire "flames".swap("trees")')) + self.assertEqual(fire_flames_to_trees, parse_prompt('fire (flames).swap("trees")')) + self.assertEqual(fire_flames_to_trees, parse_prompt('fire ("flames").swap("trees")')) + + fire_flames_to_trees_and_houses = Conjunction([FlattenedPrompt([('fire', 1.0), \ + CrossAttentionControlSubstitute([Fragment('flames', 1)], [Fragment('trees and houses', 1)])])]) + self.assertEqual(fire_flames_to_trees_and_houses, parse_prompt('fire ("flames").swap("trees and houses")')) + self.assertEqual(fire_flames_to_trees_and_houses, parse_prompt('fire (flames).swap("trees and houses")')) + self.assertEqual(fire_flames_to_trees_and_houses, parse_prompt('fire "flames".swap("trees and houses")')) + + trees_and_houses_to_flames = Conjunction([FlattenedPrompt([('fire', 1.0), \ + CrossAttentionControlSubstitute([Fragment('trees and houses', 1)], [Fragment('flames',1)])])]) + self.assertEqual(trees_and_houses_to_flames, parse_prompt('fire ("trees and houses").swap("flames")')) + self.assertEqual(trees_and_houses_to_flames, parse_prompt('fire (trees and houses).swap("flames")')) + self.assertEqual(trees_and_houses_to_flames, parse_prompt('fire "trees and houses".swap("flames")')) + self.assertEqual(trees_and_houses_to_flames, parse_prompt('fire ("trees and houses").swap(flames)')) + self.assertEqual(trees_and_houses_to_flames, parse_prompt('fire (trees and houses).swap(flames)')) + self.assertEqual(trees_and_houses_to_flames, parse_prompt('fire "trees and houses".swap(flames)')) + + flames_to_trees_fire = Conjunction([FlattenedPrompt([ + CrossAttentionControlSubstitute([Fragment('flames',1)], [Fragment('trees',1)]), + (', fire', 1.0)])]) + self.assertEqual(flames_to_trees_fire, parse_prompt('"flames".swap("trees"), fire')) + self.assertEqual(flames_to_trees_fire, parse_prompt('(flames).swap("trees"), fire')) + self.assertEqual(flames_to_trees_fire, parse_prompt('("flames").swap("trees"), fire')) + self.assertEqual(flames_to_trees_fire, parse_prompt('"flames".swap(trees), fire')) + self.assertEqual(flames_to_trees_fire, parse_prompt('(flames).swap(trees), fire ')) + self.assertEqual(flames_to_trees_fire, parse_prompt('("flames").swap(trees), fire ')) + + + self.assertEqual(Conjunction([FlattenedPrompt([Fragment('a forest landscape', 1), + CrossAttentionControlSubstitute([Fragment('',1)], [Fragment('in winter',1)])])]), + parse_prompt('a forest landscape "".swap("in winter")')) + self.assertEqual(Conjunction([FlattenedPrompt([Fragment('a forest landscape', 1), + CrossAttentionControlSubstitute([Fragment('',1)], [Fragment('in winter',1)])])]), + parse_prompt('a forest landscape ().swap(in winter)')) + self.assertEqual(Conjunction([FlattenedPrompt([Fragment('a forest landscape', 1), + CrossAttentionControlSubstitute([Fragment('',1)], [Fragment('in winter',1)])])]), + parse_prompt('a forest landscape " ".swap("in winter")')) + + self.assertEqual(Conjunction([FlattenedPrompt([Fragment('a forest landscape', 1), + CrossAttentionControlSubstitute([Fragment('in winter',1)], [Fragment('',1)])])]), + parse_prompt('a forest landscape "in winter".swap("")')) + self.assertEqual(Conjunction([FlattenedPrompt([Fragment('a forest landscape', 1), + CrossAttentionControlSubstitute([Fragment('in winter',1)], [Fragment('',1)])])]), + parse_prompt('a forest landscape "in winter".swap()')) + self.assertEqual(Conjunction([FlattenedPrompt([Fragment('a forest landscape', 1), + CrossAttentionControlSubstitute([Fragment('in winter',1)], [Fragment('',1)])])]), + parse_prompt('a forest landscape "in winter".swap(" ")')) + + def test_cross_attention_control_with_attention(self): + flames_to_trees_fire = Conjunction([FlattenedPrompt([ + CrossAttentionControlSubstitute([Fragment('flames',0.5)], [Fragment('trees',0.7)]), + Fragment(',', 1), Fragment('fire', 2.0)])]) + self.assertEqual(flames_to_trees_fire, parse_prompt('"(flames)0.5".swap("(trees)0.7"), (fire)2.0')) + flames_to_trees_fire = Conjunction([FlattenedPrompt([ + CrossAttentionControlSubstitute([Fragment('fire',0.5), Fragment('flames',0.25)], [Fragment('trees',0.7)]), + Fragment(',', 1), Fragment('fire', 2.0)])]) + self.assertEqual(flames_to_trees_fire, parse_prompt('"(fire (flames)0.5)0.5".swap("(trees)0.7"), (fire)2.0')) + flames_to_trees_fire = Conjunction([FlattenedPrompt([ + CrossAttentionControlSubstitute([Fragment('fire',0.5), Fragment('flames',0.25)], [Fragment('trees',0.7), Fragment('houses', 1)]), + Fragment(',', 1), Fragment('fire', 2.0)])]) + self.assertEqual(flames_to_trees_fire, parse_prompt('"(fire (flames)0.5)0.5".swap("(trees)0.7 houses"), (fire)2.0')) + + self.assertEqual(Conjunction([FlattenedPrompt([Fragment('a', 1), + CrossAttentionControlSubstitute([Fragment('cat',1)], [Fragment('dog',1)]), + Fragment('eating a', 1), + CrossAttentionControlSubstitute([Fragment('hotdog',1)], [Fragment('hotdog', pow(1.1,4))]) + ])]), + parse_prompt("a cat.swap(dog) eating a hotdog.swap(hotdog++++)")) + self.assertEqual(Conjunction([FlattenedPrompt([Fragment('a', 1), + CrossAttentionControlSubstitute([Fragment('cat',1)], [Fragment('dog',1)]), + Fragment('eating a', 1), + CrossAttentionControlSubstitute([Fragment('hotdog',1)], [Fragment('hotdog', pow(1.1,4))]) + ])]), + parse_prompt("a cat.swap(dog) eating a hotdog.swap(hotdog++++, shape_freedom=0.5)")) + + self.assertEqual(Conjunction([FlattenedPrompt([Fragment('a', 1), + CrossAttentionControlSubstitute([Fragment('cat',1)], [Fragment('dog',1)]), + Fragment('eating a', 1), + CrossAttentionControlSubstitute([Fragment('hotdog',1)], [Fragment('hotdog', pow(1.1,4))]) + ])]), + parse_prompt("a cat.swap(dog) eating a hotdog.swap(\"hotdog++++\", shape_freedom=0.5)")) + + self.assertEqual(Conjunction([FlattenedPrompt([Fragment('a', 1), + CrossAttentionControlSubstitute([Fragment('cat',1)], [Fragment('dog',1)]), + Fragment('eating a', 1), + CrossAttentionControlSubstitute([Fragment('hotdog',1)], [Fragment('h(o)tdog', pow(1.1,4))]) + ])]), + parse_prompt("a cat.swap(dog) eating a hotdog.swap(h\(o\)tdog++++, shape_freedom=0.5)")) + self.assertEqual(Conjunction([FlattenedPrompt([Fragment('a', 1), + CrossAttentionControlSubstitute([Fragment('cat',1)], [Fragment('dog',1)]), + Fragment('eating a', 1), + CrossAttentionControlSubstitute([Fragment('hotdog',1)], [Fragment('h(o)tdog', pow(1.1,4))]) + ])]), + parse_prompt("a cat.swap(dog) eating a hotdog.swap(\"h\(o\)tdog++++\", shape_freedom=0.5)")) + + self.assertEqual(Conjunction([FlattenedPrompt([Fragment('a', 1), + CrossAttentionControlSubstitute([Fragment('cat',1)], [Fragment('dog',1)]), + Fragment('eating a', 1), + CrossAttentionControlSubstitute([Fragment('hotdog',1)], [Fragment('h(o)tdog', pow(0.9,1))]) + ])]), + parse_prompt("a cat.swap(dog) eating a hotdog.swap(h\(o\)tdog-, shape_freedom=0.5)")) + + + def test_cross_attention_control_options(self): + self.assertEqual(Conjunction([ + FlattenedPrompt([Fragment('a', 1), + CrossAttentionControlSubstitute([Fragment('cat', 1)], [Fragment('dog', 1)], options={'s_start':0.1}), + Fragment('eating a hotdog', 1)])]), + parse_prompt("a \"cat\".swap(dog, s_start=0.1) eating a hotdog")) + self.assertEqual(Conjunction([ + FlattenedPrompt([Fragment('a', 1), + CrossAttentionControlSubstitute([Fragment('cat', 1)], [Fragment('dog', 1)], options={'t_start':0.1}), + Fragment('eating a hotdog', 1)])]), + parse_prompt("a \"cat\".swap(dog, t_start=0.1) eating a hotdog")) + self.assertEqual(Conjunction([ + FlattenedPrompt([Fragment('a', 1), + CrossAttentionControlSubstitute([Fragment('cat', 1)], [Fragment('dog', 1)], options={'s_start': 20.0, 't_start':0.1}), + Fragment('eating a hotdog', 1)])]), + parse_prompt("a \"cat\".swap(dog, t_start=0.1, s_start=20) eating a hotdog")) + + self.assertEqual( + Conjunction([ + FlattenedPrompt([Fragment('a fantasy forest landscape', 1), + CrossAttentionControlSubstitute([Fragment('', 1)], [Fragment('with a river', 1)], + options={'s_start': 0.8, 't_start': 0.8})])]), + parse_prompt("a fantasy forest landscape \"\".swap(with a river, s_start=0.8, t_start=0.8)")) + + + def test_escaping(self): + + # make sure ", ( and ) can be escaped + + self.assertEqual(make_basic_conjunction(['mountain (man)']),parse_prompt('mountain \(man\)')) + self.assertEqual(make_basic_conjunction(['mountain (man )']),parse_prompt('mountain (\(man)\)')) + self.assertEqual(make_basic_conjunction(['mountain (man)']),parse_prompt('mountain (\(man\))')) + self.assertEqual(make_weighted_conjunction([('mountain', 1), ('(man)', 1.1)]), parse_prompt('mountain (\(man\))+')) + self.assertEqual(make_weighted_conjunction([('mountain', 1), ('(man)', 1.1)]), parse_prompt('"mountain" (\(man\))+')) + self.assertEqual(make_weighted_conjunction([('"mountain"', 1), ('(man)', 1.1)]), parse_prompt('\\"mountain\\" (\(man\))+')) + # same weights for each are combined into one + self.assertEqual(make_weighted_conjunction([('"mountain" (man)', 1.1)]), parse_prompt('(\\"mountain\\")+ (\(man\))+')) + self.assertEqual(make_weighted_conjunction([('"mountain"', 1.1), ('(man)', 0.9)]), parse_prompt('(\\"mountain\\")+ (\(man\))-')) + + self.assertEqual(make_weighted_conjunction([('mountain', 1), ('\(man\)', 1.1)]),parse_prompt('mountain (\(man\))1.1')) + self.assertEqual(make_weighted_conjunction([('mountain', 1), ('\(man\)', 1.1)]),parse_prompt('"mountain" (\(man\))1.1')) + self.assertEqual(make_weighted_conjunction([('"mountain"', 1), ('\(man\)', 1.1)]),parse_prompt('\\"mountain\\" (\(man\))1.1')) + # same weights for each are combined into one + self.assertEqual(make_weighted_conjunction([('\\"mountain\\" \(man\)', 1.1)]),parse_prompt('(\\"mountain\\")+ (\(man\))1.1')) + self.assertEqual(make_weighted_conjunction([('\\"mountain\\"', 1.1), ('\(man\)', 0.9)]),parse_prompt('(\\"mountain\\")1.1 (\(man\))0.9')) + + self.assertEqual(make_weighted_conjunction([('hairy', 1), ('mountain', 1.1), ('\(man\)', 1.1*1.1)]),parse_prompt('hairy (mountain (\(man\))+)+')) + self.assertEqual(make_weighted_conjunction([('hairy', 1), ('\(man\)', 1.1*1.1), ('mountain', 1.1)]),parse_prompt('hairy ((\(man\))1.1 "mountain")+')) + self.assertEqual(make_weighted_conjunction([('hairy', 1), ('mountain', 1.1), ('\(man\)', 1.1*1.1)]),parse_prompt('hairy ("mountain" (\(man\))1.1 )+')) + self.assertEqual(make_weighted_conjunction([('hairy', 1), ('mountain , man', 1.1)]),parse_prompt('hairy ("mountain, man")+')) + self.assertEqual(make_weighted_conjunction([('hairy', 1), ('mountain , man with a', 1.1), ('beard', 1.1*1.1)]), parse_prompt('hairy ("mountain, man" with a beard+)+')) + self.assertEqual(make_weighted_conjunction([('hairy', 1), ('mountain , man with a', 1.1), ('beard', 1.1*2.0)]), parse_prompt('hairy ("mountain, man" with a (beard)2.0)+')) + self.assertEqual(make_weighted_conjunction([('hairy', 1), ('mountain , \"man\" with a', 1.1), ('beard', 1.1*2.0)]), parse_prompt('hairy ("mountain, \\"man\\"" with a (beard)2.0)+')) + self.assertEqual(make_weighted_conjunction([('hairy', 1), ('mountain , m\"an\" with a', 1.1), ('beard', 1.1*2.0)]), parse_prompt('hairy ("mountain, m\\"an\\"" with a (beard)2.0)+')) + + self.assertEqual(make_weighted_conjunction([('hairy', 1), ('mountain , \"man (with a', 1.1), ('beard', 1.1*2.0)]), parse_prompt('hairy ("mountain, \\\"man\" \(with a (beard)2.0)+')) + self.assertEqual(make_weighted_conjunction([('hairy', 1), ('mountain , \"man w(ith a', 1.1), ('beard', 1.1*2.0)]), parse_prompt('hairy ("mountain, \\\"man\" w\(ith a (beard)2.0)+')) + self.assertEqual(make_weighted_conjunction([('hairy', 1), ('mountain , \"man with( a', 1.1), ('beard', 1.1*2.0)]), parse_prompt('hairy ("mountain, \\\"man\" with\( a (beard)2.0)+')) + self.assertEqual(make_weighted_conjunction([('hairy', 1), ('mountain , \"man )with a', 1.1), ('beard', 1.1*2.0)]), parse_prompt('hairy ("mountain, \\\"man\" \)with a (beard)2.0)+')) + self.assertEqual(make_weighted_conjunction([('hairy', 1), ('mountain , \"man w)ith a', 1.1), ('beard', 1.1*2.0)]), parse_prompt('hairy ("mountain, \\\"man\" w\)ith a (beard)2.0)+')) + self.assertEqual(make_weighted_conjunction([('hairy', 1), ('mountain , \"man with) a', 1.1), ('beard', 1.1*2.0)]), parse_prompt('hairy ("mountain, \\\"man\" with\) a (beard)2.0)+')) + self.assertEqual(make_weighted_conjunction([('hairy', 1), ('mou)ntain , \"man (wit(h a', 1.1), ('beard', 1.1*2.0)]), parse_prompt('hairy ("mou\)ntain, \\\"man\" \(wit\(h a (beard)2.0)+')) + self.assertEqual(make_weighted_conjunction([('hai(ry', 1), ('mountain , \"man w)ith a', 1.1), ('beard', 1.1*2.0)]), parse_prompt('hai\(ry ("mountain, \\\"man\" w\)ith a (beard)2.0)+')) + self.assertEqual(make_weighted_conjunction([('hairy((', 1), ('mountain , \"man with a', 1.1), ('beard', 1.1*2.0)]), parse_prompt('hairy\(\( ("mountain, \\\"man\" with a (beard)2.0)+')) + + self.assertEqual(make_weighted_conjunction([('mountain , \"man (with a', 1.1), ('beard', 1.1*2.0), ('hairy', 1)]), parse_prompt('("mountain, \\\"man\" \(with a (beard)2.0)+ hairy')) + self.assertEqual(make_weighted_conjunction([('mountain , \"man w(ith a', 1.1), ('beard', 1.1*2.0), ('hairy', 1)]), parse_prompt('("mountain, \\\"man\" w\(ith a (beard)2.0)+hairy')) + self.assertEqual(make_weighted_conjunction([('mountain , \"man with( a', 1.1), ('beard', 1.1*2.0), ('hairy', 1)]), parse_prompt('("mountain, \\\"man\" with\( a (beard)2.0)+ hairy')) + self.assertEqual(make_weighted_conjunction([('mountain , \"man )with a', 1.1), ('beard', 1.1*2.0), ('hairy', 1)]), parse_prompt('("mountain, \\\"man\" \)with a (beard)2.0)+ hairy')) + self.assertEqual(make_weighted_conjunction([('mountain , \"man w)ith a', 1.1), ('beard', 1.1*2.0), ('hairy', 1)]), parse_prompt('("mountain, \\\"man\" w\)ith a (beard)2.0)+ hairy')) + self.assertEqual(make_weighted_conjunction([('mountain , \"man with) a', 1.1), ('beard', 1.1*2.0), ('hairy', 1)]), parse_prompt(' ("mountain, \\\"man\" with\) a (beard)2.0)+ hairy')) + self.assertEqual(make_weighted_conjunction([('mou)ntain , \"man (wit(h a', 1.1), ('beard', 1.1*2.0), ('hairy', 1)]), parse_prompt('("mou\)ntain, \\\"man\" \(wit\(h a (beard)2.0)+ hairy')) + self.assertEqual(make_weighted_conjunction([('mountain , \"man w)ith a', 1.1), ('beard', 1.1*2.0), ('hai(ry', 1)]), parse_prompt('("mountain, \\\"man\" w\)ith a (beard)2.0)+ hai\(ry ')) + self.assertEqual(make_weighted_conjunction([('mountain , \"man with a', 1.1), ('beard', 1.1*2.0), ('hairy((', 1)]), parse_prompt('("mountain, \\\"man\" with a (beard)2.0)+ hairy\(\( ')) + + def test_cross_attention_escaping(self): + + self.assertEqual(Conjunction([FlattenedPrompt([('mountain', 1), CrossAttentionControlSubstitute([Fragment('man', 1)], [Fragment('monkey', 1)])])]), + parse_prompt('mountain (man).swap(monkey)')) + self.assertEqual(Conjunction([FlattenedPrompt([('mountain', 1), CrossAttentionControlSubstitute([Fragment('man', 1)], [Fragment('m(onkey', 1)])])]), + parse_prompt('mountain (man).swap(m\(onkey)')) + self.assertEqual(Conjunction([FlattenedPrompt([('mountain', 1), CrossAttentionControlSubstitute([Fragment('m(an', 1)], [Fragment('m(onkey', 1)])])]), + parse_prompt('mountain (m\(an).swap(m\(onkey)')) + self.assertEqual(Conjunction([FlattenedPrompt([('mountain', 1), CrossAttentionControlSubstitute([Fragment('(((', 1)], [Fragment('m(on))key', 1)])])]), + parse_prompt('mountain (\(\(\().swap(m\(on\)\)key)')) + + self.assertEqual(Conjunction([FlattenedPrompt([('mountain', 1), CrossAttentionControlSubstitute([Fragment('man', 1)], [Fragment('monkey', 1)])])]), + parse_prompt('mountain ("man").swap(monkey)')) + self.assertEqual(Conjunction([FlattenedPrompt([('mountain', 1), CrossAttentionControlSubstitute([Fragment('man', 1)], [Fragment('monkey', 1)])])]), + parse_prompt('mountain ("man").swap("monkey")')) + self.assertEqual(Conjunction([FlattenedPrompt([('mountain', 1), CrossAttentionControlSubstitute([Fragment('"man', 1)], [Fragment('monkey', 1)])])]), + parse_prompt('mountain (\\"man).swap("monkey")')) + self.assertEqual(Conjunction([FlattenedPrompt([('mountain', 1), CrossAttentionControlSubstitute([Fragment('man', 1)], [Fragment('m(onkey', 1)])])]), + parse_prompt('mountain (man).swap(m\(onkey)')) + self.assertEqual(Conjunction([FlattenedPrompt([('mountain', 1), CrossAttentionControlSubstitute([Fragment('m(an', 1)], [Fragment('m(onkey', 1)])])]), + parse_prompt('mountain (m\(an).swap(m\(onkey)')) + self.assertEqual(Conjunction([FlattenedPrompt([('mountain', 1), CrossAttentionControlSubstitute([Fragment('(((', 1)], [Fragment('m(on))key', 1)])])]), + parse_prompt('mountain (\(\(\().swap(m\(on\)\)key)')) + + def test_legacy_blend(self): + pp = PromptParser() + + self.assertEqual(Blend([FlattenedPrompt([('mountain man', 1)]), + FlattenedPrompt([('man mountain', 1)])], + weights=[0.5,0.5]), + pp.parse_legacy_blend('mountain man:1 man mountain:1')) + + self.assertEqual(Blend([FlattenedPrompt([('mountain', 1.1), ('man', 1)]), + FlattenedPrompt([('man', 1), ('mountain', 0.9)])], + weights=[0.5,0.5]), + pp.parse_legacy_blend('mountain+ man:1 man mountain-:1')) + + self.assertEqual(Blend([FlattenedPrompt([('mountain', 1.1), ('man', 1)]), + FlattenedPrompt([('man', 1), ('mountain', 0.9)])], + weights=[0.5,0.5]), + pp.parse_legacy_blend('mountain+ man:1 man mountain-')) + + self.assertEqual(Blend([FlattenedPrompt([('mountain', 1.1), ('man', 1)]), + FlattenedPrompt([('man', 1), ('mountain', 0.9)])], + weights=[0.5,0.5]), + pp.parse_legacy_blend('mountain+ man: man mountain-:')) + + self.assertEqual(Blend([FlattenedPrompt([('mountain man', 1)]), + FlattenedPrompt([('man mountain', 1)])], + weights=[0.75,0.25]), + pp.parse_legacy_blend('mountain man:3 man mountain:1')) + + self.assertEqual(Blend([FlattenedPrompt([('mountain man', 1)]), + FlattenedPrompt([('man mountain', 1)])], + weights=[1.0,0.0]), + pp.parse_legacy_blend('mountain man:3 man mountain:0')) + + self.assertEqual(Blend([FlattenedPrompt([('mountain man', 1)]), + FlattenedPrompt([('man mountain', 1)])], + weights=[0.8,0.2]), + pp.parse_legacy_blend('"mountain man":4 man mountain')) + + + def test_single(self): + self.assertEqual(Conjunction([FlattenedPrompt([("mountain man", 1.0)]), + FlattenedPrompt([("a person with a hat", 1.0), + ("riding a", 1.1*1.1), + CrossAttentionControlSubstitute( + [Fragment("bicycle", pow(1.1,2))], + [Fragment("skateboard", pow(1.1,2))]) + ]) + ], weights=[0.5, 0.5]), + parse_prompt("(\"mountain man\", \"a person with a hat (riding a bicycle.swap(skateboard))++\").and(0.5, 0.5)")) + pass + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/validate_pr_prompt.txt b/tests/validate_pr_prompt.txt new file mode 100644 index 0000000000..c1a8e00cbe --- /dev/null +++ b/tests/validate_pr_prompt.txt @@ -0,0 +1 @@ +banana sushi -Ak_lms -S42 -s10 diff --git a/update.bat b/update.bat new file mode 100644 index 0000000000..5b01a4e85f --- /dev/null +++ b/update.bat @@ -0,0 +1,19 @@ +@echo off + +set INSTALL_ENV_DIR=%cd%\installer_files\env +set PATH=%INSTALL_ENV_DIR%;%INSTALL_ENV_DIR%\Library\bin;%INSTALL_ENV_DIR%\Scripts;%INSTALL_ENV_DIR%\Library\usr\bin;%PATH% + +@rem update the repo +if exist ".git" ( + call git pull +) + + +conda env update +conda activate invokeai +python scripts/preload_models.py + +echo "Press any key to continue" +pause +exit 0 + diff --git a/update.sh b/update.sh new file mode 100755 index 0000000000..e969826359 --- /dev/null +++ b/update.sh @@ -0,0 +1,24 @@ +#!/bin/bash + + +INSTALL_ENV_DIR="$(pwd)/installer_files/env" +if [ -e "$INSTALL_ENV_DIR" ]; then export PATH="$INSTALL_ENV_DIR/bin:$PATH"; fi + +# update the repo +if [ -e ".git" ]; then + git pull +fi + +CONDA_BASEPATH=$(conda info --base) +source "$CONDA_BASEPATH/etc/profile.d/conda.sh" # otherwise conda complains about 'shell not initialized' (needed when running in a script) + +conda activate invokeai + +OS_NAME=$(uname -s) +case "${OS_NAME}" in + Linux*) conda env update;; + Darwin*) conda env update -f environment-mac.yml;; + *) echo "Unknown OS: $OS_NAME! This script runs only on Linux or Mac" && exit +esac + +python scripts/preload_models.py